【STM32】FreeRTOS中断示例
00. 目錄
文章目錄
- 00. 目錄
- 01. 概述
- 02. 函數(shù)設(shè)計(jì)
- 03. 程序設(shè)計(jì)與分析
- 04. 中斷初始化
- 05. 程序設(shè)計(jì)
- 06. 附錄
- 07. 參考
01. 概述
在FreeRTOS中優(yōu)先級(jí)低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中斷會(huì)被屏蔽掉,高于的就不會(huì)。我們使用兩個(gè)定時(shí)器,一個(gè)優(yōu)先級(jí)為4,一個(gè)優(yōu)先級(jí)為5,兩個(gè)定時(shí)器每隔1秒通過(guò)串口輸出一串字符串。然后在某個(gè)任務(wù)中關(guān)閉中斷一段時(shí)間,查看兩個(gè)定時(shí)器的輸出情況。
02. 函數(shù)設(shè)計(jì)
設(shè)計(jì)兩個(gè)任務(wù)start_task()和interrupt_task(),這兩個(gè)任務(wù)的功能如下:
start_task():創(chuàng)建另外一個(gè)任務(wù)。
interrupt_task():中斷測(cè)試任務(wù),任務(wù)中會(huì)調(diào)用FreeRTOS的關(guān)中斷函數(shù)將中斷關(guān)閉一段時(shí)間。
03. 程序設(shè)計(jì)與分析
任務(wù)設(shè)置
//任務(wù)優(yōu)先級(jí) #define START_TASK_PRIO 1 //任務(wù)堆棧大小 #define START_STK_SIZE 256 //任務(wù)句柄 TaskHandle_t StartTask_Handler; //任務(wù)函數(shù) void start_task(void *pvParameters);//任務(wù)優(yōu)先級(jí) #define INTERRUPT_TASK_PRIO 2 //任務(wù)堆棧大小 #define INTERRUPT_STK_SIZE 256 //任務(wù)句柄 TaskHandle_t INTERRUPTTask_Handler; //任務(wù)函數(shù) void interrupt_task(void *p_arg);主函數(shù)設(shè)計(jì)
int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//設(shè)置系統(tǒng)中斷優(yōu)先級(jí)分組4delay_init(168); //初始化延時(shí)函數(shù)uart_init(115200); //初始化串口LED_Init(); //初始化LED端口TIM3_Int_Init(10000-1,8400-1); //初始化定時(shí)器3,定時(shí)器周期1STIM5_Int_Init(10000-1,8400-1); //初始化定時(shí)器5,定時(shí)器周期1S//創(chuàng)建開(kāi)始任務(wù)xTaskCreate((TaskFunction_t )start_task, //任務(wù)函數(shù)(const char* )"start_task", //任務(wù)名稱(chēng)(uint16_t )START_STK_SIZE, //任務(wù)堆棧大小(void* )NULL, //傳遞給任務(wù)函數(shù)的參數(shù)(UBaseType_t )START_TASK_PRIO, //任務(wù)優(yōu)先級(jí)(TaskHandle_t* )&StartTask_Handler); //任務(wù)句柄 vTaskStartScheduler(); //開(kāi)啟任務(wù)調(diào)度 }任務(wù)函數(shù)設(shè)計(jì)
//開(kāi)始任務(wù)任務(wù)函數(shù) void start_task(void *pvParameters) {taskENTER_CRITICAL(); //進(jìn)入臨界區(qū)//創(chuàng)建中斷測(cè)試任務(wù)xTaskCreate((TaskFunction_t )interrupt_task, //任務(wù)函數(shù)(const char* )"interrupt_task", //任務(wù)名稱(chēng)(uint16_t )INTERRUPT_STK_SIZE, //任務(wù)堆棧大小(void* )NULL, //傳遞給任務(wù)函數(shù)的參數(shù)(UBaseType_t )INTERRUPT_TASK_PRIO, //任務(wù)優(yōu)先級(jí)(TaskHandle_t* )&INTERRUPTTask_Handler); //任務(wù)句柄vTaskDelete(StartTask_Handler); //刪除開(kāi)始任務(wù)taskEXIT_CRITICAL(); //退出臨界區(qū) }//中斷測(cè)試任務(wù)函數(shù) void interrupt_task(void *pvParameters) {static u32 total_num=0;while(1){total_num+=1;if(total_num==5) {printf("關(guān)閉中斷.............\r\n");portDISABLE_INTERRUPTS(); //關(guān)閉中斷delay_xms(5000); //延時(shí)5sprintf("打開(kāi)中斷.............\r\n"); //打開(kāi)中斷portENABLE_INTERRUPTS();}LED0=~LED0;vTaskDelay(1000);} }04. 中斷初始化
//通用定時(shí)器3中斷初始化 //arr:自動(dòng)重裝值。 //psc:時(shí)鐘預(yù)分頻數(shù) //定時(shí)器溢出時(shí)間計(jì)算方法:Tout=((arr+1)*(psc+1))/Ft us. //Ft=定時(shí)器工作頻率,單位:Mhz //這里使用的是定時(shí)器3! void TIM3_Int_Init(u16 arr,u16 psc) {TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///使能TIM3時(shí)鐘TIM_TimeBaseInitStructure.TIM_Period = arr; //自動(dòng)重裝載值TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定時(shí)器分頻TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上計(jì)數(shù)模式TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允許定時(shí)器3更新中斷TIM_Cmd(TIM3,ENABLE); //使能定時(shí)器3NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定時(shí)器3中斷NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x04; //搶占優(yōu)先級(jí)4NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00; //子優(yōu)先級(jí)0NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure); }//通用定時(shí)器5中斷初始化 //arr:自動(dòng)重裝值。 //psc:時(shí)鐘預(yù)分頻數(shù) //定時(shí)器溢出時(shí)間計(jì)算方法:Tout=((arr+1)*(psc+1))/Ft us. //Ft=定時(shí)器工作頻率,單位:Mhz //這里使用的是定時(shí)器5! void TIM5_Int_Init(u16 arr,u16 psc) {TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE); //使能TIM5時(shí)鐘TIM_TimeBaseInitStructure.TIM_Period = arr; //自動(dòng)重裝載值TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定時(shí)器分頻TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上計(jì)數(shù)模式TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure); //初始化TIM5TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE); //允許定時(shí)器5更新中斷TIM_Cmd(TIM5,ENABLE); //使能定時(shí)器5NVIC_InitStructure.NVIC_IRQChannel=TIM5_IRQn; //定時(shí)器5中斷NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x05; //搶占優(yōu)先級(jí)5NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00; //子優(yōu)先級(jí)0NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure); }//定時(shí)器3中斷服務(wù)函數(shù) void TIM3_IRQHandler(void) {if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中斷{printf("TIM3輸出.......\r\n");}TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中斷標(biāo)志位 }//定時(shí)器5中斷服務(wù)函數(shù) void TIM5_IRQHandler(void) {if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET) //溢出中斷{printf("TIM5輸出.......\r\n");}TIM_ClearITPendingBit(TIM5,TIM_IT_Update); //清除中斷標(biāo)志位 }05. 程序設(shè)計(jì)
main.c文件
//任務(wù)優(yōu)先級(jí) #define START_TASK_PRIO 1 //任務(wù)堆棧大小 #define START_STK_SIZE 256 //任務(wù)句柄 TaskHandle_t StartTask_Handler; //任務(wù)函數(shù) void start_task(void *pvParameters);//任務(wù)優(yōu)先級(jí) #define INTERRUPT_TASK_PRIO 2 //任務(wù)堆棧大小 #define INTERRUPT_STK_SIZE 256 //任務(wù)句柄 TaskHandle_t INTERRUPTTask_Handler; //任務(wù)函數(shù) void interrupt_task(void *p_arg);int main(void) { NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//設(shè)置系統(tǒng)中斷優(yōu)先級(jí)分組4delay_init(168); //初始化延時(shí)函數(shù)uart_init(115200); //初始化串口LED_Init(); //初始化LED端口TIM3_Int_Init(10000-1,8400-1); //初始化定時(shí)器3,定時(shí)器周期1STIM5_Int_Init(10000-1,8400-1); //初始化定時(shí)器5,定時(shí)器周期1S//創(chuàng)建開(kāi)始任務(wù)xTaskCreate((TaskFunction_t )start_task, //任務(wù)函數(shù)(const char* )"start_task", //任務(wù)名稱(chēng)(uint16_t )START_STK_SIZE, //任務(wù)堆棧大小(void* )NULL, //傳遞給任務(wù)函數(shù)的參數(shù)(UBaseType_t )START_TASK_PRIO, //任務(wù)優(yōu)先級(jí)(TaskHandle_t* )&StartTask_Handler); //任務(wù)句柄 vTaskStartScheduler(); //開(kāi)啟任務(wù)調(diào)度 }//開(kāi)始任務(wù)任務(wù)函數(shù) void start_task(void *pvParameters) {taskENTER_CRITICAL(); //進(jìn)入臨界區(qū)//創(chuàng)建中斷測(cè)試任務(wù)xTaskCreate((TaskFunction_t )interrupt_task, //任務(wù)函數(shù)(const char* )"interrupt_task", //任務(wù)名稱(chēng)(uint16_t )INTERRUPT_STK_SIZE, //任務(wù)堆棧大小(void* )NULL, //傳遞給任務(wù)函數(shù)的參數(shù)(UBaseType_t )INTERRUPT_TASK_PRIO, //任務(wù)優(yōu)先級(jí)(TaskHandle_t* )&INTERRUPTTask_Handler); //任務(wù)句柄vTaskDelete(StartTask_Handler); //刪除開(kāi)始任務(wù)taskEXIT_CRITICAL(); //退出臨界區(qū) }//中斷測(cè)試任務(wù)函數(shù) void interrupt_task(void *pvParameters) {static u32 total_num=0;while(1){total_num+=1;if(total_num==5) {printf("關(guān)閉中斷.............\r\n");portDISABLE_INTERRUPTS(); //關(guān)閉中斷delay_xms(5000); //延時(shí)5sprintf("打開(kāi)中斷.............\r\n"); //打開(kāi)中斷portENABLE_INTERRUPTS();}LED0=~LED0;vTaskDelay(1000);} }timer.c文件
//通用定時(shí)器3中斷初始化 //arr:自動(dòng)重裝值。 //psc:時(shí)鐘預(yù)分頻數(shù) //定時(shí)器溢出時(shí)間計(jì)算方法:Tout=((arr+1)*(psc+1))/Ft us. //Ft=定時(shí)器工作頻率,單位:Mhz //這里使用的是定時(shí)器3! void TIM3_Int_Init(u16 arr,u16 psc) {TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3,ENABLE); ///使能TIM3時(shí)鐘TIM_TimeBaseInitStructure.TIM_Period = arr; //自動(dòng)重裝載值TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定時(shí)器分頻TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上計(jì)數(shù)模式TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM3,&TIM_TimeBaseInitStructure);//初始化TIM3TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE); //允許定時(shí)器3更新中斷TIM_Cmd(TIM3,ENABLE); //使能定時(shí)器3NVIC_InitStructure.NVIC_IRQChannel=TIM3_IRQn; //定時(shí)器3中斷NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x04; //搶占優(yōu)先級(jí)4NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00; //子優(yōu)先級(jí)0NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure); }//通用定時(shí)器5中斷初始化 //arr:自動(dòng)重裝值。 //psc:時(shí)鐘預(yù)分頻數(shù) //定時(shí)器溢出時(shí)間計(jì)算方法:Tout=((arr+1)*(psc+1))/Ft us. //Ft=定時(shí)器工作頻率,單位:Mhz //這里使用的是定時(shí)器5! void TIM5_Int_Init(u16 arr,u16 psc) {TIM_TimeBaseInitTypeDef TIM_TimeBaseInitStructure;NVIC_InitTypeDef NVIC_InitStructure;RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5,ENABLE); //使能TIM5時(shí)鐘TIM_TimeBaseInitStructure.TIM_Period = arr; //自動(dòng)重裝載值TIM_TimeBaseInitStructure.TIM_Prescaler=psc; //定時(shí)器分頻TIM_TimeBaseInitStructure.TIM_CounterMode=TIM_CounterMode_Up; //向上計(jì)數(shù)模式TIM_TimeBaseInitStructure.TIM_ClockDivision=TIM_CKD_DIV1; TIM_TimeBaseInit(TIM5,&TIM_TimeBaseInitStructure); //初始化TIM5TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE); //允許定時(shí)器5更新中斷TIM_Cmd(TIM5,ENABLE); //使能定時(shí)器5NVIC_InitStructure.NVIC_IRQChannel=TIM5_IRQn; //定時(shí)器5中斷NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=0x05; //搶占優(yōu)先級(jí)5NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00; //子優(yōu)先級(jí)0NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure); }//定時(shí)器3中斷服務(wù)函數(shù) void TIM3_IRQHandler(void) {if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中斷{printf("TIM3輸出.......\r\n");}TIM_ClearITPendingBit(TIM3,TIM_IT_Update); //清除中斷標(biāo)志位 }//定時(shí)器5中斷服務(wù)函數(shù) void TIM5_IRQHandler(void) {if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET) //溢出中斷{printf("TIM5輸出.......\r\n");}TIM_ClearITPendingBit(TIM5,TIM_IT_Update); //清除中斷標(biāo)志位 }06. 附錄
6.1 【STM32】STM32系列教程匯總
網(wǎng)址:【STM32】STM32系列教程匯總
07. 參考
《FreeRTOS Reference Manual》
《Using the FreeRTOS Real Time Kernel -A Practical Guide》
《The Definitive Guide to ARM Cortex-M3 and Cortex-M4 Processors,3rd Edition》
總結(jié)
以上是生活随笔為你收集整理的【STM32】FreeRTOS中断示例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 【STM32】FreeRTOS临界区
- 下一篇: 【STM32】FreeRTOS任务相关A