STM32MP157资源扩展板驱动移植篇10:FreeRTOS软件定时器
写在前面:
本文章为《STM32MP157资源扩展板驱动移植篇》系列中的一篇,笔者使用的开发平台为华清远见FS-MP1A开发板(STM32MP157开发板)。资源扩展板是FS-MP1A开发板的扩展模块,主要包含了10余种主流传感器、执行器件、总线控制器件,非常方便项目扩展用。可拓展开发智慧家庭、智能医疗、智能安防、工业控制、图像识别、环境检测等方向的10个左右综合项目,华清远见开发板也将配套提供所有项目的说明文档、实验源码、应用程序等资料。
针对FS-MP1A开发板,除了资源扩展板驱动移植篇外,还包括其他多系列教程,包括Cortex-A7开发篇、Cortex-M4开发篇、FreeRTOS篇、Linux应用开发篇、Linux系统移植篇、Linux驱动开发篇、硬件设计篇、人工智能机器视觉篇、Qt应用编程篇、Qt综合项目实战篇等。欢迎关注,更多stm32mp157开发教程及视频,可加技术交流Q群459754978,感谢关注。
FS-MP1A开发板详情介绍:https://item.taobao.com/item.htm?id=622457259672
1.资源扩展板介绍
1.1硬件介绍
1.2资源扩展板可开发项目
2.FreeRTOS软件定时器
2.1软件定时器简介
对于MCU而言,其自带的定时器属于硬件定时器,在FreeRTOS系统中,另外提供了软件定时器功能。软件定时器的精度比不上硬件定时器,但对于要求不高的周期性处理任务来说足够了。
软件定时器可以设置一段时间,当设置的时间到达以后就去执行回调函数,其中,回调函数的两次执行间隔就是定时器的定时周期,即每次定时周期到达以后就去执行一次回调函数。因为回调函数是在定时器服务函数中执行的,因此在回调函数中一定不能调用会阻塞任务的API函数。
软件定时器分为周期定时器和单次定时器两种。周期定时器启动以后就会在执行完回调函数后自动的重新启动,所以回调函数可以周期性执行,对于单次定时器,回调函数只执行一次,执行完以后,定时器就会停止运行,当然我们可以调用函数再次手动重新启动。
2.2软件定时器函数
2.2.1 复位定时器
在定时器正常运行时,我们有时可能需要定时器的复位操作,当复位软件定时器时,系统会重新计算定时周期到达的时间点,但此时间点是相对于复位时刻计算的,并不是第一次启动软件定时器的那个时间点。
在新版FreeRTOS中,共有两个API函数可以完成软件定时器的复位,分别应用于任务中和中断中。
任务级复位软件定时器函数xTimerReset(),此函数是一个宏,其函数原型如下
BaseType_t xTimerReset( TimerHandle_t xTimer,
TickType_t xTicksToWait)
参数:
xTimer:要复位的软件定时器的句柄。
xTickToWait:设置阻塞时间。
返回值:
pdPASS:软件定时器复位成功,即命令发送成功。
pdFAIL:软件定时器复位失败,即命令发送失败。
任务级复位软件定时器函数xTimerReset(),此函数是一个宏,其函数原型如下
BaseType_t xTimerResetFromISR( TimerHandle_t xTimer,
BaseType_t * pxHigherPriorityTaskWoken );
参数:
xTimer:要复位的软件定时器的句柄。
pxHigherPriorityTaskWoken:记退出此函数以后是否进行任务切换,用户不用进行设置。
返回值:
pdPASS:软件定时器复位成功,即命令发送成功。
pdFAIL:软件定时器复位失败,即命令发送失败。
2.2.2 创建软件定时器
创建软件定时器的函数有两个,分别如下:
xTimerCreate(),此函数用于创建软件定时器,所需要的内存通过动态内存管理方法分配,创建以后软件定时器处于休眠状态,其函数原型如下:
TimerHandle_t xTimerCreate( const char * const pcTimerName,
TickType_t xTimerPeriodInTicks,
UBaseType_t uxAutoReload,
void * pvTimerID,
TimerCallbackFunction_t pxCallbackFunction )
参数:
pcTimerName: 软件定时器名字,是一串字符串,用于调试使用。
xTimerPeriodInTicks: 定时器周期,单位是时钟节拍数。
uxAutoReload: 设置定时器模式,单次定时器还是周期定时器。
pvTimerID: 定时器ID号。
pxCallbackFunction: 定时器回调函数。
返回值:
NULL:软件定时器创建失败。
其他值:创建成功的软件定时器句柄。
xTimerCreateStatic(),此函数也用于创建软件定时器,所需要的内存通过用户自行分配,创建以后软件定时器处于休眠状态,其函数原型如下:
TimerHandle_t xTimerCreateStatic(const char * const pcTimerName,
TickType_t xTimerPeriodInTicks,
UBaseType_t uxAutoReload,
void * pvTimerID,
TimerCallbackFunction_t pxCallbackFunction,
StaticTimer_t * pxTimerBuffer )
参数:
pcTimerName: 软件定时器名字,是一串字符串,用于调试使用。
xTimerPeriodInTicks:定时器周期,单位是时钟节拍数。
uxAutoReload: 设置定时器模式,单次定时器还是周期定时器。
pvTimerID: 定时器ID号。
pxCallbackFunction: 定时器回调函数。
pxTimerBuffer: 指向一个StaticTimer_t类型的变量,用来保存定时器结构体。
返回值:
NULL:软件定时器创建失败。
其他值:创建成功的软件定时器句柄。
2.2.3 开启软件定时器
开启软件定时器的函数也有两个,分别如下:
任务级开启定时器函数xTimerStart(),此函数是个宏,如果软件定时器没有运行的话调用函数 xTimerStart()就会计算定时器到期时间,如果软件定时器正在运行的话调用函数 xTimerStart()的结果和 xTimerReset()一样,其函数原型如下:
BaseType_t xTimerStart( TimerHandle_t xTimer,
TickType_t xTicksToWait )
参数:
xTimer: 要开启的软件定时器句柄。
xTickToWait: 设置阻塞时间。
返回值:
pdPASS:软件定时器开启成功,即命令发送成功。
pdFAIL:软件定时器开启失败,即命令发送失败。
中断级开启定时器函数xTimerStartFromISR(),此函数也是个宏,为函数xTimerStart()的中断版本,只能用于中断服务函数中,其函数原型如下:
BaseType_t xTimerStartFromISR( TimerHandle_t xTimer,
BaseType_t * pxHigherPriorityTaskWoken );
参数:
xTimer: 要开启的软件定时器句柄。
pxHigherPriorityTaskWoken: 标记退出此函数以后是否进行任务切换。
返回值:
pdPASS:软件定时器开启成功,即命令发送成功。
pdFAIL:软件定时器开启失败,即命令发送失败。
2.2.4 停止软件定时器
与开启软件定时器一样,停止软件定时器的函数也有两个,分别如下:
任务级停止定时器函数xTimerStop(),此函数是个宏,其函数原型如下:
BaseType_t xTimerStop( TimerHandle_t xTimer,
TickType_t xTicksToWait )
参数:
xTimer: 要停止的软件定时器句柄。
xTickToWait: 设置阻塞时间。
返回值:
pdPASS:软件定时器停止成功,即命令发送成功。
pdFAIL:软件定时器停止失败,即命令发送失败。
中断级停止定时器函数xTimerStopFromISR(),此函数也是个宏,为函数xTimerStop()的中断版本,只能用于中断服务函数中,其函数原型如下:
BaseType_t xTimerStopFromISR( TimerHandle_t xTimer,
BaseType_t * pxHigherPriorityTaskWoken );
参数:
xTimer: 要停止的软件定时器句柄。
pxHigherPriorityTaskWoken: 标记退出此函数以后是否进行任务切换。
返回值:
pdPASS:软件定时器停止成功,即命令发送成功。
pdFAIL:软件定时器停止失败,即命令发送失败。
2.3操作实验
2.3.1实验设计
本次实验创建两个软件定时器,分别为周期定时器CycleTimer_Handle和单次定时器SingleTimer_Handle,其中,CycleTimer_Handle的定时器周期为1000个时钟节拍,SingleTimer_Handle的定时器周期为2000个时钟节拍。
可参考12.3.2章节进行导入已有工程,工程存放路径【华清远见-FS-MP1A开发资料\02-程序源码\ARM体系结构与接口技术\FreeRTOS\4_MP1A-FreeRTOS-TIMER】
通过按键中断设置不同的指令,在任务中根据接收到的指令来控制周期定时器与单次定时器的工作。
任务及其功能如下:
StartTask02(): 控制LED3闪烁,提示系统正在运行。
StartDefaultTask():进行指令处理,根据接收的指令控制定时器工作。
2.3.2实验过程与分析
首先,根据之前几章内容配置好CubeMX,按照上一节配置“FREERTOS”,完成后生成代码。 在StartDefaultTask() 与StartTask02()中添加代码如下。
当按下KEY1键时,单次定时器工作,当定时器时间到了以后就会调用OneShotCallback()函数,此时会发现LED1的电平发生翻转,然后停止运行。当按下KEY2键时,周期定时器工作,当定时器时间到了以后就会调用AutoReloadCallback()函数,因为周期定时器不会停止运行,此时会发现LED2每隔1秒电平发生翻转。当按下KEY3键时,单次定时器和周期定时器关闭,LED灯的电平不再发生变化。
硬件平台:华清远见FS-MP1A开发板(STM32MP157)
部分开发教程下载:加QQ群459754978,群文件里有。
部分视频课程收看:华清远见研发中心的个人空间_哔哩哔哩_Bilibili
淘宝购买链接:华清远见stm32mp157开发板stm32 linux开发板单片机arm嵌入式学习
手机淘宝分享码:复制本行文字打开手淘₤T4FPXn3YYJ2₤