ucosIII_软件定时器
1.定时器API。文件 OS_Tmr.c
1.1创建定时器
void OSTmrCreate (OS_TMR *p_tmr, CPU_CHAR *p_name, OS_TICK dly, OS_TICK period, OS_OPT opt, OS_TMR_CALLBACK_PTR p_callback, void *p_callback_arg, OS_ERR *p_err)
1.2.开始定时器
CPU_BOOLEAN OSTmrStart (OS_TMR *p_tmr,
OS_ERR *p_err)
1.3.停止定时器
CPU_BOOLEAN OSTmrStop (OS_TMR *p_tmr, OS_OPT opt, void *p_callback_arg, OS_ERR *p_err)
2.定时器回调函数
软件定时器的定时精度不如硬件定时器,最小定时时间取决于OS_systick的最小时间。
systick的时间由下面两个宏定义确定
文件:os_cfg_app.c
OS_RATE_HZ const OSCfg_TickRate_Hz = (OS_RATE_HZ )OS_CFG_TICK_RATE_HZ;
文件:os_cfg_app.h
#define OS_CFG_TICK_RATE_HZ 200u /* Tick rate in Hertz (10 to 1000 Hz) */
一个systick是1s/200=50ms在创建定时器的时候第3.4个参数都是传x个systick的时间。
这里注意一下dly period opt p_callback这几个参数
dly参数:第一次启动定时器的延时时间(具体图片在后面博客链接中)
period参数:这个参数是定时器的定时时间
opt参数:
OS_OPT_TMR_ONE_SHOT:定时器只触发一次
OS_OPT_TMR_PERIODIC:定时器循环触发
无论是单次触发还是循环触发,dly和period参数都有效。
p_callback参数:是我们先定义的一个函数,把函数名字传进去,当定时器定时时间到了自动执行这个函数,这个函数又用户实现。
下面做个实验:创建一个定时器每1s给串口发送一次数据
定义定时器:
OS_TMR usarttmr;
定义回调函数:
void SoftwareTimercallbackForUsrat(void *p_tmr, void *p_arg); //定时器1回调函数
创建定时器
OSTmrCreate((OS_TMR *)&usarttmr, (CPU_CHAR *)"SoftwareTimercallbackForUsrat", (OS_TICK )20, //20*5=100ms (OS_TICK )200, //200*5=1s (OS_OPT )OS_OPT_TMR_PERIODIC
, //单次定时器 (OS_TMR_CALLBACK_PTR)SoftwareTimercallbackForUsrat, //定时器回调函数 (void *)0, (OS_ERR *)&err);
开启定时器:
OSTmrStart(&usarttmr,&err);
定时器回调函数:
//定时器usart的回调函数 void SoftwareTimercallbackForUsrat(void *p_tmr,void *p_arg) { static u8 num = 0; OS_ERR err; num++; LED1 = ~LED1; printf("UCOSIII软件定时器测试1秒\r\n"); }
结果:
一开始定时器无法工作,经过调试发现是dly和period写反了。dly可以写0,period是定时器定时时间,我们要写的是这个参数。关于dly的具体介绍在下面这篇博客中。
开启定时器的OSTmrStart函数可以写在任务中,不必紧挨着创建定时器的地方。
参考资料
【UCOSIII】UCOSIII软件定时器 https://blog.csdn.net/qq_38410730/article/details/80821152