你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

基于STM32的FreeRTOS学习之中断测试实验(五)

[复制链接]
STMCU小助手 发布时间:2022-11-17 16:47
1. 实验目的
FreeRTOS可以屏蔽优先级低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断,不会屏蔽高于其的中断。本次实验就是验证这个说法。本实验使用两个定时器,一个优先级为4,另一个为5,两个定时器每隔1s通过串口输出一串字符串。然后在某个任务中关闭中断一段时间,查看输出情况。

2. 实验设计

本实验设计了两个任务start_task()和interrupt_task(),这两个任务的任务功能分别为:
start_task():创建另外一个任务;
interrupt_task():中断测试任务,任务会调用FreeRTOS的中断函数portDISABLE_INTERRUPTS()来将中断关闭一段时间。

3. 硬件
3.1 正点原子战舰v3开发板(其他板子应该也可以,主要涉及USART,TIM3,TIM5,LED);
3.2 JLINK仿真器。

4. 代码解读
4.1 timer.h和timer.c
因为用到2个定时器,这里选择TIM3和TIM5,其定时器初始化和中断函数如下:

  1. #ifndef __TIMER_H
  2. #define __TIMER_H
  3. #include "stm32f10x.h"
  4. void TIM3_Int_Init(u16 arr,u16 psc);   // 优先级4,认为高优先级
  5. void TIM5_Int_Init(u16 arr,u16 psc);   // 优先级5, 认为低优先级
  6. #endif
复制代码
  1. #include "timer.h"
  2. #include "usart.h"         
  3. // 函数名称:通用定时器3中断初始化
  4. // 入口参数:arr:自动重装值;psc:时钟预分频数
  5. void TIM3_Int_Init(u16 arr,u16 psc)
  6. {
  7.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStruct;
  8.     NVIC_InitTypeDef NVIC_InitStruct;
  9.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM3, ENABLE);         
  10.         // 定时器TIM3初始化
  11.         TIM_TimeBaseStruct.TIM_Period = arr;               
  12.         TIM_TimeBaseStruct.TIM_Prescaler =psc;
  13.         TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
  14.         TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;  
  15.         TIM_TimeBaseInit(TIM3, &TIM_TimeBaseStruct);
  16.         TIM_ITConfig(TIM3,TIM_IT_Update,ENABLE );
  17.         // 中断优先级NVIC设置
  18.         NVIC_InitStruct.NVIC_IRQChannel = TIM3_IRQn;
  19.         NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 4;  
  20.         NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;  
  21.         NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;
  22.         NVIC_Init(&NVIC_InitStruct);  
  23.         TIM_Cmd(TIM3, ENABLE);                                   
  24. }
  25. // 函数名称:通用定时器5中断初始化
  26. // 入口参数:arr:自动重装值;psc:时钟预分频数
  27. void TIM5_Int_Init(u16 arr,u16 psc)
  28. {
  29.     TIM_TimeBaseInitTypeDef  TIM_TimeBaseStruct;
  30.         NVIC_InitTypeDef NVIC_InitStruct;
  31.         RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM5, ENABLE);         
  32.         // 定时器TIM5初始化
  33.         TIM_TimeBaseStruct.TIM_Period = arr;                        
  34.         TIM_TimeBaseStruct.TIM_Prescaler =psc;                                 
  35.         TIM_TimeBaseStruct.TIM_ClockDivision = TIM_CKD_DIV1;
  36.         TIM_TimeBaseStruct.TIM_CounterMode = TIM_CounterMode_Up;
  37.         TIM_TimeBaseInit(TIM5, &TIM_TimeBaseStruct);                        
  38.         TIM_ITConfig(TIM5,TIM_IT_Update,ENABLE );                                 
  39.         // 中断优先级NVIC设置
  40.         NVIC_InitStruct.NVIC_IRQChannel = TIM5_IRQn;                  
  41.         NVIC_InitStruct.NVIC_IRQChannelPreemptionPriority = 5;         
  42.         NVIC_InitStruct.NVIC_IRQChannelSubPriority = 0;         
  43.         NVIC_InitStruct.NVIC_IRQChannelCmd = ENABLE;                 
  44.         NVIC_Init(&NVIC_InitStruct);                                                  
  45.         TIM_Cmd(TIM5, ENABLE);                                                                                   
  46. }
  47. // 函数名称:定时器3中断服务函数
  48. void TIM3_IRQHandler(void)
  49. {
  50.         if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET)
  51.         {        printf("TIM3输出.......\r\n"); }
  52.         TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  
  53. }
  54. // 函数名称:定时器5中断服务函数
  55. void TIM5_IRQHandler(void)
  56. {
  57.         if(TIM_GetITStatus(TIM5,TIM_IT_Update)==SET)
  58.         {        printf("TIM5输出.......\r\n");  }
  59.         TIM_ClearITPendingBit(TIM5,TIM_IT_Update);
  60. }
复制代码

4.2 main.c文件代码

  1. #include "sys.h"
  2. #include "delay.h"
  3. #include "usart.h"
  4. #include "led.h"
  5. #include "timer.h"
  6. #include "FreeRTOS.h"
  7. #include "task.h"
  8. // 设计第一个任务start_task()
  9. #define START_TASK_PRIO                          1         // 任务优先级
  10. #define START_STK_SIZE                           256       // 任务堆栈大小        
  11. TaskHandle_t StartTask_Handler;             // 任务句柄
  12. void start_task(void *pvParameters);        // 任务函数
  13. // 设计第二个任务interrupt_task()
  14. #define INTERRUPT_TASK_PRIO                  2         // 任务优先级
  15. #define INTERRUPT_STK_SIZE                   256       // 任务堆栈大小
  16. TaskHandle_t INTERRUPTTask_Handler;         // 任务句柄
  17. void interrupt_task(void *p_arg);           // 任务函数

  18. // 主函数
  19. int main(void)
  20. {
  21.         NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);    // 设置系统中断优先级分组4         
  22.         delay_init();                                                           // 延时函数初始化         
  23.         uart_init(115200);                                                       // 初始化串口
  24.         LED_Init();                                                                         // 初始化LED
  25.         TIM3_Int_Init(10000-1,7200-1);                               // 初始化定时器3,定时器周期1S
  26.         TIM5_Int_Init(10000-1,7200-1);                               // 初始化定时器5,定时器周期1S
  27.         // 创建开始任务
  28.         xTaskCreate(        (TaskFunction_t )start_task,            // 任务函数
  29.                                         (const char*    )"start_task",          // 任务名称
  30.                                         (uint16_t       )START_STK_SIZE,        // 任务堆栈大小
  31.                                     (void*          )NULL,                  // 传递给任务函数的参数
  32.                         (UBaseType_t    )START_TASK_PRIO,       // 任务优先级
  33.                         (TaskHandle_t*  )&StartTask_Handler);   // 任务句柄              
  34.         vTaskStartScheduler();                                      // 开启任务调度
  35. }

  36. // 主函数里创建了第一个任务函数——开始任务
  37. void start_task(void *pvParameters)
  38. {
  39.         taskENTER_CRITICAL();                                       // 进入临界区
  40.         // 创建中断测试任务,用来执行开关中断操作
  41.         xTaskCreate(        (TaskFunction_t )interrupt_task,                  // 任务函数
  42.                         (const char*    )"interrupt_task",                         // 任务名称
  43.                         (uint16_t       )INTERRUPT_STK_SIZE,                // 任务堆栈大小
  44.                         (void*          )NULL,                                                // 传递给任务函数的参数
  45.                         (UBaseType_t    )INTERRUPT_TASK_PRIO,                // 任务优先级
  46.                            (TaskHandle_t*  )&INTERRUPTTask_Handler);         // 任务句柄
  47.         vTaskDelete(StartTask_Handler);                             // 删除开始任务
  48.         taskEXIT_CRITICAL();                                        // 退出临界区
  49. }

  50. // 开始任务里创建了第二个任务函数——中断测试任务
  51. void interrupt_task(void *pvParameters)
  52. {
  53.         static u32 total_num=0;
  54.         while(1)
  55.         {
  56.                 total_num+=1;
  57.                 if(total_num==5)                        
  58.                 {
  59.                         printf("关闭中断.............\r\n");
  60.                         portDISABLE_INTERRUPTS();                                      // 关闭中断
  61.                         delay_xms(5000);                                                                                        // 延时5s
  62.                         printf("打开中断.............\r\n");          // 打开中断
  63.                         portENABLE_INTERRUPTS();
  64.                 }
  65.                 LED0=~LED0;
  66.                 vTaskDelay(1000);
  67.         }
  68. }
复制代码

5. 实验结果

20210313225858796.png

运行一开始,TIM3和TIM5都有输出,当运行5次后,关闭中断,这时只有TIM3有输出(因为优先级为4,高于configMAX_SYSCALL_INTERRUPT_PRIORITY),而TIM5优先级为5,与configMAX_SYSCALL_INTERRUPT_PRIORITY相等,被关闭了。待5s之后,重新打开中断,此时TIM5恢复运行。

最后回顾下一个知识点,configMAX_SYSCALL_INTERRUPT_PRIORITY值在哪里定义的?在FreeRTOSConfig.h文件里!

2021031323043547.png

如果将configMAX_SYSCALL_INTERRUPT_PRIORITY改为4或更小,则TIM3也会被关闭。
————————————————
版权声明:天亮继续睡

收藏 评论0 发布时间:2022-11-17 16:47

举报

0个回答

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版