00. 目录

文章目录

  • 00. 目录
  • 01. 概述
  • 02. 函数设计
  • 03. 程序设计与分析
  • 04. 中断初始化
  • 05. 程序设计
  • 06. 附录
  • 07. 参考

01. 概述

在FreeRTOS中优先级低于configMAX_SYSCALL_INTERRUPT_PRIORITY的中断会被屏蔽掉,高于的就不会。我们使用两个定时器,一个优先级为4,一个优先级为5,两个定时器每隔1秒通过串口输出一串字符串。然后在某个任务中关闭中断一段时间,查看两个定时器的输出情况。

02. 函数设计

设计两个任务start_task()和interrupt_task(),这两个任务的功能如下:

start_task():创建另外一个任务。

interrupt_task():中断测试任务,任务中会调用FreeRTOS的关中断函数将中断关闭一段时间。

03. 程序设计与分析

任务设置

//任务优先级
#define START_TASK_PRIO         1
//任务堆栈大小
#define START_STK_SIZE          256
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);//任务优先级
#define INTERRUPT_TASK_PRIO     2
//任务堆栈大小
#define INTERRUPT_STK_SIZE      256
//任务句柄
TaskHandle_t INTERRUPTTask_Handler;
//任务函数
void interrupt_task(void *p_arg);

主函数设计

int main(void)
{ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4delay_init(168);                 //初始化延时函数uart_init(115200);                     //初始化串口LED_Init();                          //初始化LED端口TIM3_Int_Init(10000-1,8400-1);        //初始化定时器3,定时器周期1STIM5_Int_Init(10000-1,8400-1);      //初始化定时器5,定时器周期1S//创建开始任务xTaskCreate((TaskFunction_t )start_task,            //任务函数(const char*    )"start_task",          //任务名称(uint16_t       )START_STK_SIZE,        //任务堆栈大小(void*          )NULL,                  //传递给任务函数的参数(UBaseType_t    )START_TASK_PRIO,       //任务优先级(TaskHandle_t*  )&StartTask_Handler);   //任务句柄              vTaskStartScheduler();          //开启任务调度
}

任务函数设计

//开始任务任务函数
void start_task(void *pvParameters)
{taskENTER_CRITICAL();           //进入临界区//创建中断测试任务xTaskCreate((TaskFunction_t )interrupt_task,              //任务函数(const char*    )"interrupt_task",          //任务名称(uint16_t       )INTERRUPT_STK_SIZE,      //任务堆栈大小(void*          )NULL,                      //传递给任务函数的参数(UBaseType_t    )INTERRUPT_TASK_PRIO,       //任务优先级(TaskHandle_t*  )&INTERRUPTTask_Handler);    //任务句柄vTaskDelete(StartTask_Handler); //删除开始任务taskEXIT_CRITICAL();            //退出临界区
}//中断测试任务函数
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:时钟预分频数
//定时器溢出时间计算方法: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; //向上计数模式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; //抢占优先级4NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00; //子优先级0NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);
}//通用定时器5中断初始化
//arr:自动重装值。
//psc:时钟预分频数
//定时器溢出时间计算方法: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; //向上计数模式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;     //抢占优先级5NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00;        //子优先级0NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);
}//定时器3中断服务函数
void TIM3_IRQHandler(void)
{if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断{printf("TIM3输出.......\r\n");}TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}//定时器5中断服务函数
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文件


//任务优先级
#define START_TASK_PRIO         1
//任务堆栈大小
#define START_STK_SIZE          256
//任务句柄
TaskHandle_t StartTask_Handler;
//任务函数
void start_task(void *pvParameters);//任务优先级
#define INTERRUPT_TASK_PRIO     2
//任务堆栈大小
#define INTERRUPT_STK_SIZE      256
//任务句柄
TaskHandle_t INTERRUPTTask_Handler;
//任务函数
void interrupt_task(void *p_arg);int main(void)
{ NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4delay_init(168);                 //初始化延时函数uart_init(115200);                     //初始化串口LED_Init();                          //初始化LED端口TIM3_Int_Init(10000-1,8400-1);        //初始化定时器3,定时器周期1STIM5_Int_Init(10000-1,8400-1);      //初始化定时器5,定时器周期1S//创建开始任务xTaskCreate((TaskFunction_t )start_task,            //任务函数(const char*    )"start_task",          //任务名称(uint16_t       )START_STK_SIZE,        //任务堆栈大小(void*          )NULL,                  //传递给任务函数的参数(UBaseType_t    )START_TASK_PRIO,       //任务优先级(TaskHandle_t*  )&StartTask_Handler);   //任务句柄              vTaskStartScheduler();          //开启任务调度
}//开始任务任务函数
void start_task(void *pvParameters)
{taskENTER_CRITICAL();           //进入临界区//创建中断测试任务xTaskCreate((TaskFunction_t )interrupt_task,              //任务函数(const char*    )"interrupt_task",          //任务名称(uint16_t       )INTERRUPT_STK_SIZE,      //任务堆栈大小(void*          )NULL,                      //传递给任务函数的参数(UBaseType_t    )INTERRUPT_TASK_PRIO,       //任务优先级(TaskHandle_t*  )&INTERRUPTTask_Handler);    //任务句柄vTaskDelete(StartTask_Handler); //删除开始任务taskEXIT_CRITICAL();            //退出临界区
}//中断测试任务函数
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:时钟预分频数
//定时器溢出时间计算方法: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; //向上计数模式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; //抢占优先级4NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00; //子优先级0NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);
}//通用定时器5中断初始化
//arr:自动重装值。
//psc:时钟预分频数
//定时器溢出时间计算方法: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; //向上计数模式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;     //抢占优先级5NVIC_InitStructure.NVIC_IRQChannelSubPriority=0x00;        //子优先级0NVIC_InitStructure.NVIC_IRQChannelCmd=ENABLE;NVIC_Init(&NVIC_InitStructure);
}//定时器3中断服务函数
void TIM3_IRQHandler(void)
{if(TIM_GetITStatus(TIM3,TIM_IT_Update)==SET) //溢出中断{printf("TIM3输出.......\r\n");}TIM_ClearITPendingBit(TIM3,TIM_IT_Update);  //清除中断标志位
}//定时器5中断服务函数
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系列教程汇总

网址:【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》

【STM32】FreeRTOS中断示例相关推荐

  1. 【STM32】FreeRTOS中断配置

    00. 目录 文章目录 00. 目录 01. 概述 02. 中断管理 03. 优先级分组 04. 优先级设置 05. 特殊寄存器 06. FreeRTOS中断配置宏 07. FreeRTOS开关中断 ...

  2. FreeRTOS中断配置与临界段

    Cortex-M中断 中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序(中断服务程序),处理完毕后又返回原被暂停的程序继续运行.Cortex- ...

  3. (二)stm32之中断配置

    一.stm32的中断和异常 Cortex拥有强大的异常响应系统,它能够打断当前代码执行流程事件分为异常和中断,它们用一个表管理起来,编号为0~15为内核异常,16以上的为外部中断,这个表就是中断向量表 ...

  4. 基于STM32+FreeRtos+ESP8266+MQTT连接阿里云

    基于STM32+FreeRtos+DHT12+ESP8266+MQTT连接阿里云 1.概述 2.实现步骤 2.1.MQTT.fx模拟器与阿里云通信 2.2.STM32与阿里云通信 3. 搭建云平台 3 ...

  5. 【基于stm32 FreeRtos的智能台灯控制】

    基于stm32 FreeRtos的智能台灯控制 之前做了一个裸机版本的智能台灯,最近刚好复习一下FreeRto的一些基础知识,朋友发给了我一个功能需求刚好用来实践一下,需要的朋友可以自行下载. 完整工 ...

  6. STM32 FreeRTOS CMSIS—OS

    STM32 FreeRTOS CMSIS-OS 前言 1.关于 osThreadNew () 1.1 FreeRTOS线程与任务的关系 1.2 osThreadNew () 1.2.1 osThrea ...

  7. 【CubeMX配置stm32定时器中断】

    CubeMX配置stm32定时器中断 一.使用CubeMX对STM32进行基础的配置 1.选择需要使用的定时器 选择TIM2和TIM3示例, 注意: TIM2和其它定时器选择时钟的方法不同,TIM3等 ...

  8. stm32之中断配置

    一.stm32的中断和异常 Cortex拥有强大的异常响应系统,它能够打断当前代码执行流程事件分为异常和中断,它们用一个表管理起来,编号为0~15为内核异常,16以上的为外部中断,这个表就是中断向量表 ...

  9. STM32外部中断与各通道对应关系

    EXTI0_IRQn的值,其实就是EXTI0中断向量在中断向量表中的位置(STM32技术参考手册中断向量表position栏中的数值) 一:外部中断使用配置过程: (1)配置时钟信号 (2)引脚属性 ...

最新文章

  1. 阻塞(block)/非阻塞(unblock) 同步(synchronization)/异步(asynchronization) 的区别
  2. 安卓惯性传感器(二)
  3. protobuf windows java_protobuf windows java 环境搭建
  4. 基于java的WebGIS服务器的设计
  5. 每天一小时python官方文档学习(二)————流程控制工具
  6. 计算机网络误区——VLAN中Access和Trunk原理详解
  7. deepin上配置eclipse的hadoop开发环境
  8. C++端部署pytorch, libtorc使用教程(精简版)
  9. Java角度制向弧度制转化
  10. 苹果通用链接跳转apple-app-site-association
  11. 在excel中如何输入身份证号码
  12. 人民币大写转换工具C++实现(支持任意位金额转换)
  13. jenkins 使用报ERROR: svn: E155010: The node ‘/aaa/bbb/ccc/ddd‘ was not found.
  14. SolidWorks Premium 白金版
  15. ISO 14229、ISO 15765、ISO 11898的区别
  16. Pandoc下载安装教程
  17. [4G5G基础学习]:流程 - 4G LTE PLMN选择、扫频、小区搜索、系统消息读取、小区选择过程
  18. ffprobe获取mp4音视频数据信息
  19. KISSY基础篇乄KISSY之DOM(1)
  20. Pathos: Nethack Codex 游戏指南

热门文章

  1. H.264 Quantization
  2. 创建可按比例调整的布局的 Windows 窗体
  3. Wintellect Collection Classes for .NET now on CodePlex
  4. python shell下载很慢_Python踩坑之旅其一杀不死的Shell子进程
  5. matlab and操作,系统建模 | Control Tutorials for Matlab and Simulink
  6. 用户dsn保存位置‘_苹果iOS 13.6终于能保存文章阅读进度了 朋友都等秃了
  7. Java黑皮书课后题第6章:**6.18(检测密码)一些网站对于密码具有一些规则。编写一个方法检测字符串是否是一个有效密码。编写一个程序,提示用户输入一个密码,如果符合规则,则显示…否则显示…
  8. (转)Linux内核参数之arp_ignore和arp_announce
  9. spring事物回滚遇到的问题
  10. A. 本地DNS服务器的位置