freeRTOS软件定时器的使用

本文的内容结构如下:
1、 freertos中启用定时器
2、freertos的定时器种类
2.1、单次定时器
2.2、周期定时器
3、freertos 软件定时器的api函数
3.1、创建软件定时器
3.2、启动软件定时器
3.3、停止定时器
3.4、复位定时器
3.5、查询定时器是否已经开始运行
4、软件定时器使用实例
freertos中加入了软件定时器这个功能组件,是一个可选的、不属于freertos内核的功能,由定时器服务(其实就是一个定时器任务)来提供。
软件定时器是当设定一个定时时间,当达到设定的时间之后就会执行指定的功能函数,而这个功能函数就叫做 回调函数 。
也就是说回调函数的两次执行间隔叫做定时器的定时周期。
回调函数: 回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。
1、 freertos中启用定时器
在freertos中要使用软件定时器的话,需要在配置文件freertosconfig.h中设置相应的宏,如下:
#define configuse_timers 1 //使能软件定时器#define configtimer_task_priority 2 // 软件定时器的优先级#define configtimer_queue_length 10 // 软件定时器的队列长度#define configtimer_task_stack_depth (configminimal_stack_size * 2) // 软件定时器的堆栈空间大小(单位是字)2、freertos的定时器种类
2.1、单次定时器
单次定时器定时时间到了就执行一次回调函数,之后不会再执行,只有在再次重新启动的时候才会再执行一次。
2.2、周期定时器
周期定时器根据设定的时间周期地执行的。它一旦启动以后,每执行一次完一次回调函数以后定时器会自动重启,回调函数会周期性的执行。
3、freertos 软件定时器的api函数
3.1、创建软件定时器
timerhandle_t xtimercreate( const char * const pctimername, /* 定时器名字 */ const ticktype_t xtimerperiod, /* 定时器周期 */ const ubasetype_t uxautoreload, /* 选择单次模式或者周期模式 */ void * const pvtimerid, /* 定时器 id */ timercallbackfunction_t pxcallbackfunction ); /* 定时器回调函数 */函数描述:
函数 xtimercreate 用于创建软件定时器。
1)第 1 个参数: 定时器名字,一般用于调试,方便识别不同的定时器。
2)第 2 个参数: 定时器周期,单位是系统时钟节拍。
3)第 3 个参数: 选择定时器是周期模式还是单次模式。若参数为 pdtrue ,则表示选择周期模式,若参数为 pdfalse ,则表示选择单次模式。
4)第 4 个参数: 定时器的 id。当创建多个不同的定时器,但又使用同一个回调函数时,在回调函数中就可以通过不同的 id 号来区分不同的定时器。
5)第 5 个参数: 定时器的回调函数。
返回值: 创建成功返回定时器的句柄,失败会返回 null。
创建一个单次触发的软件定时器示例如下:
timerhandle_t singaltimers; //单次定时器 void singaltimersfunc(timerhandle_t xtimers); //单次定时器回调函数 /*创建单次定时器*/ singaltimers = xtimercreate( singaltimers, //软件定时器的名字 1000, //定时周期,单位是时钟节拍数 pdfalse, //定时器模式,pdtrue为周期定时器,pdfalse为单次定时器 (void*)1, //定时器的id号 singaltimersfunc //定时器回调函数 );//3.2、启动软件定时器
1)在任务中启动
basetype_t xtimerstart( timerhandle_t xtimer, /* 定时器句柄 */ ticktype_t xblocktime ); /* 成功启动定时器前的最大等待时间设置,单位系统时钟节拍 */函数描述:
函数 xtimerstart 用于启动软件定时器。
**1> **第 1 个参数是定时器句柄。
2> 第 2 个参数是成功启动定时器前的最大等待时间设置,单位系统时钟节拍。这是定时器组的大部分 api 函数不是直接运行的,而是通过消息队列给定时器任务发消息来实现的,此参 数设置的等待时间就是当消息队列已经满的情况下,等待消息队列有空间时的最大等待时间。
返回值: 返回 pdfail 表示此函数向消息队列发送消息失败,返回 pdpass 表示此函数向消息队列发 送消息成功。
注意:定时器任务实际执行消息队列发来的命令依赖于定时器任务的优先级,如果定时器任务 是高优先级会及时得到执行,如果是低优先级,就要等待其余高优先级任务释放 cpu 权才可以得到执行。
使用这个函数要注意以下问题:
1> 要使用定时器启动函数前提是已经通过函数 xtimercreate 成功创建了软件定时器。
2> 在 freertosconfig.h 文件中使能宏定义:
#define configuse_timers 1
2)在中断中启动
basetype_t xtimerstartfromisr(timerhandle_t xtimer basetype_t* pxhigherprioritytaskwoken);函数描述:
xtimer: 软件定时器的句柄
pxhigherprioritytaskwoken: 退出此函数时是否要进行任务切换
返回值:
pdpass: 软件定时器开启成功。
pdfail: 软件定时器开启失败。
3.3、停止定时器
1)在任务中停止软件定时器
basetype_t xtimerstop(timerhandle_t xtime, ticktype_t xtickstowait)函数描述:
xtimer: 软件定时器的句柄。
xtickstowait: 阻塞时间,即停止定时器最大的等待时间。
返回值:
pdpass: 软件定时器停止成功
pdfail: 软件定时器停止失败
2)在中断中停止软件定时器
xtimerstopformisr(timerhandle_t xtimer, basetype_t pxhigherprioritytaskwoken);函数描述:
xtimer: 软件定时器句柄
pxhigherprioritytaskwoken: 退出此函数时是否要进行任务切换
返回值:
pdpass: 软件定时器开启成功。
pdfail: 软件定时器开启失败。
3.4、复位定时器
1)在任务中复位
basetype_t xtimerreset(timerhandle_t xtimer, ticktype_t xtickstowait)函数描述:
xtimer: 软件定时器的句柄。
xtickstowait: 阻塞时间,即停止定时器最大的等待时间。
返回值:
pdpass: 软件定时器复位成功
pdfail: 软件定时器复位失败
2)在中断中复位
basetype_t xtimerresetfromisr(timerhandle_t xtimer, basetype_t *pxhigherprioritytaskwoken);函数描述:
xtimer: 软件定时器句柄
pxhigherprioritytaskwoken: 退出此函数时是否要进行任务切换
返回值:
pdpass: 软件定时器复位成功。
pdfail: 软件定时器复位失败。
3.5、查询定时器是否已经开始运行
basetype_t xtimeristimeractive( timerhandle_t xtimer )查询定时器以查看它是活动的还是 休眠的 。
如果出现以下情况,计时器将处于休眠状态:
已创建但未启动。已过期的计时器尚未重新启动。返回值:
pdfalse,没有运行。
其他值,运行。
4、软件定时器使用实例
创建2个软件定时器,id号分别为1、2,这两个软件定时器使用同一个回调函数,在回调函数里面读取定时器的id,通过id识别定时器。
1、创建软件定时器timerhandle_t softwavetimer1; //软件定时器1timerhandle_t softwavetimer2; //软件定时器2void pxsoftwavetimer(timerhandle_t xtimer); //软件定时器回调函数 softwavetimer1 = xtimercreate( softwavetimer1, 1000, pdtrue, (void*)1, pxsoftwavetimer); softwavetimer2 = xtimercreate( softwavetimer2, //定时器句柄 3000, //定时器周期 pdtrue, //周期/单次定时器 (void*)2, //定时器id pxsoftwavetimer); //回调函数指针2、定时器回调函数void pxsoftwavetimer(timerhandle_t xtimer){ u32 timerid; u8 *timername; timerid = (u32)pvtimergettimerid(xtimer); //获取定时器id timername = (u8*)pctimergetname( xtimer ); //获取定时名字 if(timerid == 1) { printf(软件定时器%s运行,1s周期\\r\\n,timername); } if(timerid == 2) { printf(软件定时器%s运行,2s周期\\r\\n,timername); }}3、启动、关闭定时器//task1任务函数void task1_task(void *pvparameters) //prio = 2{ u8 keyval = 0; while(1) { keyval = key_scan(0); if(keyval == key0_pres) //启动定时器 { xtimerstart(softwavetimer1,0); xtimerstart(softwavetimer2,0); } if(keyval == key1_pres) //关闭定时器 { xtimerstop(softwavetimer1,0); xtimerstop(softwavetimer2,0); } led1 ^= 1; vtaskdelay(200); //延时n个时钟节拍 }}

中兴5G路由器MC801入网 支持100MHz超宽带宽
九号高性能版电动车E200P正式发布搭载ABS系统最高时速可达100公里
将OrCAD Schematic和PADS Allegro PCB合并到一个项目中
白宫量子计算峰会谷歌、微软、IBM等公司开展竞赛
Windows server 2019安装iis服务教程
freeRTOS软件定时器的使用
特斯拉专利crash can,发生碰撞时保护乘客安全
如何下载安装和激活松下自动追踪软件AW-SF100
荣耀蓝牙音箱怎么样 小机身超便携的户外小钢炮
关于浏览器缓存最详细解析
瑞典查尔姆斯理工大学研究人员推出了世界上检测最快的氢传感器
支持大语言模型的下一代AIoT系统该怎么做设计验证?
变频器的安装操作
智能网联汽车已成为汽车强国的战略选择
基于STB5660解决方案的交互式机顶盒设计
SK海力士利川工厂出现首个新冠肺炎确诊病例 官方表示不会影响运转和相关产能
俩月三起火!蔚来汽车召回数千量ES8
浅谈嵌入式网络视频服务器的设计
挂脖蓝牙耳机什么牌子好,性价比高的挂脖式蓝牙耳机
如何实施符合功能安全及ASPICE要求的模型动态测试——TPT Workshop邀请函