单片机
返回首页

05_FreeRTOS中断管理

2025-09-05 来源:cnblogs

什么是中断?

image-20240320170332894

中断优先级分组设置

image-20240320170345479

不同时发生具有相同抢占优先级的两个中断时,顺序执行

image-20240320170355917

image-20240320170406132

中断相关寄存器

image-20240320170421525

每个地址存储8位

image-20240321003034191

FreeRTOS如何配置PendSV和Systick中断优先级?

image-20240320170610328

image-20240320170631489

image-20240320170639374

image-20240320170649951

image-20240320170657507

FreeRTOS中断管理实验

image-20240320170710929


代码

btim.c


/**

 ****************************************************************************************************

 * @file        btim.c

 * @author      正点原子团队(ALIENTEK)

 * @version     V1.0

 * @date        2021-10-15

 * @brief       基本定时器 驱动代码

 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司

 ****************************************************************************************************

 * @attention

 *

 * 实验平台:正点原子 探索者 F407开发板

 * 在线视频:www.yuanzige.com

 * 技术论坛:www.openedv.com

 * 公司网址:www.alientek.com

 * 购买地址:openedv.taobao.com

 *

 * 修改说明

 * V1.0 20211015

 * 第一次发布

 *

 ****************************************************************************************************

 */


#include './BSP/LED/led.h'

#include './BSP/TIMER/btim.h'

#include './SYSTEM/usart/usart.h'



TIM_HandleTypeDef g_timx_handler;         /* 定时器参数句柄 */

TIM_HandleTypeDef g_tim7_handler;         /* 定时器参数句柄 */


/**

 * @brief       基本定时器TIMX定时中断初始化函数

 * @note

 *              基本定时器的时钟来自APB1,当PPRE1 ≥ 2分频的时候

 *              基本定时器的时钟为APB1时钟的2倍, 而APB1为42M, 所以定时器时钟 = 84Mhz

 *              定时器溢出时间计算方法: Tout = ((arr + 1) * (psc + 1)) / Ft us.

 *              Ft=定时器工作频率,单位:Mhz

 *

 * @param       arr : 自动重装值。

 * @param       psc : 时钟预分频数

 * @retval      无

 */

void btim_timx_int_init(uint16_t arr, uint16_t psc)

{

    g_timx_handler.Instance = BTIM_TIMX_INT;                      /* 定时器x */

    g_timx_handler.Init.Prescaler = psc;                          /* 分频 */

    g_timx_handler.Init.CounterMode = TIM_COUNTERMODE_UP;         /* 递增计数模式 */

    g_timx_handler.Init.Period = arr;                             /* 自动装载值 */

    HAL_TIM_Base_Init(&g_timx_handler);

    

    HAL_TIM_Base_Start_IT(&g_timx_handler);                       /* 使能定时器x和定时器更新中断 */

}


/* TIM7初始化函数 */

void btim_tim7_int_init(uint16_t arr, uint16_t psc)

{

    g_tim7_handler.Instance = BTIM_TIM7_INT;                      /* 定时器x */

    g_tim7_handler.Init.Prescaler = psc;                          /* 分频 */

    g_tim7_handler.Init.CounterMode = TIM_COUNTERMODE_UP;         /* 递增计数模式 */

    g_tim7_handler.Init.Period = arr;                             /* 自动装载值 */

    HAL_TIM_Base_Init(&g_tim7_handler);

    

    HAL_TIM_Base_Start_IT(&g_tim7_handler);                       /* 使能定时器x和定时器更新中断 */

}


/**

 * @brief       定时器底层驱动,开启时钟,设置中断优先级

                此函数会被HAL_TIM_Base_Init()函数调用

 * @param       无

 * @retval      无

 */

void HAL_TIM_Base_MspInit(TIM_HandleTypeDef *htim)

{

    if (htim->Instance == BTIM_TIMX_INT)

    {

        BTIM_TIMX_INT_CLK_ENABLE();                     /* 使能TIMx时钟 */

        HAL_NVIC_SetPriority(BTIM_TIMX_INT_IRQn, 6, 0); /* 抢占6,子优先级0 */

        HAL_NVIC_EnableIRQ(BTIM_TIMX_INT_IRQn);         /* 开启ITMx中断 */

    }

if (htim->Instance == BTIM_TIM7_INT)

    {

        BTIM_TIM7_INT_CLK_ENABLE();                     /* 使能TIM7时钟 */

        HAL_NVIC_SetPriority(BTIM_TIM7_INT_IRQn, 4, 0); /* 抢占4,子优先级0 */

        HAL_NVIC_EnableIRQ(BTIM_TIM7_INT_IRQn);         /* 开启ITM7中断 */

    }

}


/**

 * @brief       基本定时器TIMX中断服务函数

 * @param       无

 * @retval      无

 */

void BTIM_TIMX_INT_IRQHandler(void)

{

    HAL_TIM_IRQHandler(&g_timx_handler);  /* 定时器回调函数 */

}


/* 基本定时器TIM7中断服务函数 */

void BTIM_TIM7_INT_IRQHandler(void)

{

    HAL_TIM_IRQHandler(&g_tim7_handler);  /* 定时器回调函数 */

}


/**

 * @brief       回调函数,定时器中断服务函数调用

 * @param       无

 * @retval      无

 */

void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)

{

    if (htim->Instance == BTIM_TIMX_INT)

    {

        printf('TIM6正在运行rn');

    }

else if (htim->Instance == BTIM_TIM7_INT)

    {

        printf('TIM7正在运行rn');

    }

}


btim.h


/**

 ****************************************************************************************************

 * @file        btim.h

 * @author      正点原子团队(ALIENTEK)

 * @version     V1.0

 * @date        2021-10-15

 * @brief       基本定时器 驱动代码

 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司

 ****************************************************************************************************

 * @attention

 *

 * 实验平台:正点原子 探索者 F407开发板

 * 在线视频:www.yuanzige.com

 * 技术论坛:www.openedv.com

 * 公司网址:www.alientek.com

 * 购买地址:openedv.taobao.com

 *

 * 修改说明

 * V1.0 20211015

 * 第一次发布

 *

 ****************************************************************************************************

 */


#ifndef __BTIM_H

#define __BTIM_H


#include './SYSTEM/sys/sys.h'



/******************************************************************************************/

/* 基本定时器 定义 */


/* TIMX 中断定义 

 * 默认是针对TIM6/TIM7

 * 注意: 通过修改这4个宏定义,可以支持TIM1~TIM8任意一个定时器.

 */

 

#define BTIM_TIMX_INT                       TIM6

#define BTIM_TIMX_INT_IRQn                  TIM6_DAC_IRQn

#define BTIM_TIMX_INT_IRQHandler            TIM6_DAC_IRQHandler

#define BTIM_TIMX_INT_CLK_ENABLE()          do{ __HAL_RCC_TIM6_CLK_ENABLE(); }while(0)  /* TIM6 时钟使能 */


#define BTIM_TIM7_INT                       TIM7

#define BTIM_TIM7_INT_IRQn                  TIM7_IRQn

#define BTIM_TIM7_INT_IRQHandler            TIM7_IRQHandler

#define BTIM_TIM7_INT_CLK_ENABLE()          do{ __HAL_RCC_TIM7_CLK_ENABLE(); }while(0)  /* TIM7 时钟使能 */


/******************************************************************************************/


void btim_timx_int_init(uint16_t arr, uint16_t psc);    /* 基本定时器 定时中断初始化函数 */

void btim_tim7_int_init(uint16_t arr, uint16_t psc);    /* 基本定时器 定时中断初始化函数 */


#endif


main.c


/**

 ****************************************************************************************************

 * @file        main.c

 * @author      正点原子团队(ALIENTEK)

 * @version     V1.0

 * @date        2021-11-04

 * @brief       任务挂起和恢复 实验

 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司

 ****************************************************************************************************

 * @attention

 *

 *

 ****************************************************************************************************

 */


#include './SYSTEM/sys/sys.h'

#include './SYSTEM/usart/usart.h'

#include './SYSTEM/delay/delay.h'

#include './BSP/LED/led.h'

#include './BSP/LCD/lcd.h'

#include './BSP/KEY/key.h'

#include './BSP/SRAM/sram.h'

#include './MALLOC/malloc.h'

#include 'freertos_demo.h'

#include './BSP/TIMER/btim.h'


int main(void)

{


    HAL_Init();                         /* 初始化HAL库 */

    sys_stm32_clock_init(336, 8, 2, 7); /* 设置时钟,168Mhz */

    delay_init(168);                    /* 延时初始化 */

    usart_init(115200);                 /* 串口初始化为115200 */

    led_init();                         /* 初始化LED */

    lcd_init();                         /* 初始化LCD */

    key_init();                         /* 初始化按键 */

    sram_init();                        /* SRAM初始化 */

btim_timx_int_init(10000-1,8400-1);

btim_tim7_int_init(10000-1,8400-1);

    my_mem_init(SRAMIN);                /* 初始化内部SRAM内存池 */

    my_mem_init(SRAMEX);                /* 初始化外部SRAM内存池 */

    my_mem_init(SRAMCCM);               /* 初始化内部CCM内存池 */

    freertos_demo();

    

}


freertos_demo.c


/**

 ****************************************************************************************************

 * @file        freertos.c

 * @author      正点原子团队(ALIENTEK)

 * @version     V1.4

 * @date        2022-01-04

 * @brief       FreeRTOS 移植实验

 * @license     Copyright (c) 2020-2032, 广州市星翼电子科技有限公司

 ****************************************************************************************************

 * @attention

 *

 * 实验平台:正点原子 探索者F407开发板

 * 在线视频:www.yuanzige.com

 * 技术论坛:www.openedv.com

 * 公司网址:www.alientek.com

 * 购买地址:openedv.taobao.com

 *

 ****************************************************************************************************

 */


#include 'freertos_demo.h'

#include './SYSTEM/usart/usart.h'

#include './BSP/LED/led.h'

#include './BSP/LCD/lcd.h'

#include './BSP/KEY/key.h'

#include './SYSTEM/delay/delay.h'

/*FreeRTOS*********************************************************************************************/

#include 'FreeRTOS.h'

#include 'task.h'


/******************************************************************************************************/

/*FreeRTOS配置*/


/* START_TASK 任务 配置

 * 包括: 任务句柄 任务优先级 堆栈大小 创建任务

 */

 #define START_TASK_STACK_SIZE 128

 #define START_TASK_PRIO 1

 TaskHandle_t start_task_handler;

 

 #define TASK1_STACK_SIZE 128

 #define TASK1_PRIO 2

 TaskHandle_t task1_handler;

 

void start_task( void * pvParameters );


void task1( void * pvParameters )

{

uint8_t task1_num = 0;

while(1)

{

if(++task1_num == 5)

{

task1_num = 0;

printf('关中断rn');

portDISABLE_INTERRUPTS();

delay_ms(5000);

printf('开中断rn');

portENABLE_INTERRUPTS();

}

vTaskDelay(1000);

}

}


/******************************************************************************************************/


/**

 * @brief       FreeRTOS例程入口函数

 * @param       无

 * @retval      无

 */

void freertos_demo(void)

{

    xTaskCreate(start_task, 'start_task', START_TASK_STACK_SIZE, NULL, START_TASK_PRIO, &start_task_handler);

    vTaskStartScheduler();

}


void start_task( void * pvParameters )

{

taskENTER_CRITICAL(); //进入临界区

xTaskCreate(task1, 'task1', TASK1_STACK_SIZE, NULL, TASK1_PRIO, &task1_handler);

    vTaskDelete(NULL);

taskEXIT_CRITICAL(); //退出临界区

}


进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 1瓦线性调频增强器

  • 1瓦四级调频发射机

  • 500W MOS场效应管电源逆变器,12V转110V/220V

  • 红外开关

  • LM317过压保护

  • 0-30V/20A 大功率稳压电源(采用LM338)

    相关电子头条文章