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