嵌入式开发交流网论坛

标题: UCOSIII软件定时器(内附API函数实验) [打印本页]

作者: 相互欣赏对方    时间: 2019-2-17 19:09
标题: UCOSIII软件定时器(内附API函数实验)
相信大家在学习单片机的时候,不管学习的是51或者stm32,肯定都用过定时器,利用定时器功能做很多定时的任务,可以利用定时任务来定时任务功能,那么本文给大家介绍UCOSIII中的软件定时器。


定时器工作模式
在UCOSIII中,定时器实质上是一个递减的计数器,当内部的计数器逐一递减到0时,系统会触发一个动作,这个动作就是通过回调函数来实现的,当定时器计数完成后,自动调用与定时器链接的回调函数,那么,我们就可以在回调函数里实现一些设计,比如,定时10s关闭某个外设,(注意:在回调函数要尽量减少使用带有阻塞或删除定时任务的函数)。
宏OS_CFG_TMR_DEL_EN为1时则开启定时器,定时器的分辨率由配置文件中系统节拍频率0S_CFG_TICK_RATE_HZ决定,比如,我们将这个参数设定为200,则系统时钟周期为1/200=5ms,即定时器的最小分辨率就为5ms。


创建一个定时器
在自己设计的项目中,要使用定时器,则必须先创建一个定时器,我们使用API函数OSTmrCreate()来创建,此函数原型为:
[attach]25965[/attach]

参数:p_tmr:指向定时器的指针。
     p_name:定时器名称。
dly:初始化定时器的延迟。
period:重复周期。
opt:定时器运行选项,有两个选择:
OS_OPT_TMR_ONE_SHOT 单次定时器
OS_OPT_TMR_PERIODIC  周期定时器
p_callback:指回调函数的名字。
     p_callback_arg:回调函数的参数。
p_err:调用此函数返回的错误码。


定时器的模式选项1:单次定时器:
在使用OSTmrCreate()函数创建定时器时把参数opt设置为OS_OPT_TMR_ONE_SHOT,就将定时器设置为了单次定时器,创建一个单次定时器以后,我们一旦调用OSTmrCreate()函数,定时器就会从创建时定义的dly开始倒计数,减到0时调用回调函数。
[attach]25966[/attach]

上图展现了单次定时器调用OSTmrStart()函数后开始倒计时,将dly参数减为0后调用回调函数的过程,定时结束时,定时器就结束运行了,之后可以调用OSTmrStop()函数来删除这个运行完成的定时器,当然了,也可以重新调用OSTmrStart()函数来重启一个已经运行完的定时器,即通过OSTmrStart多次触发。过程如下图

[attach]25967[/attach]

定时器的模式选项2:周期定时器
在使用OSTmrCreate()函数创建定时器时把参数opt设置为OS_OPT_TMR_PERIODIC,就创建了周期定时器,当定时器倒计数完成后,定时器就会调用回调函数,且重置计数器开始下一轮的定时,且一直循环下去。举个例子,如果使用OSTmrCreate函数创建定时器,参数dly为0,则定时器在每个周期开始计数器初值就为period值



[attach]25968[/attach]

在创建定时器时也可以创建带有初始延时的,即dly参数不为0,初始化延时就是OSTmrCreate函数中的参数dly,定时器第一个周期就是dly,当第一个周期完成后采用周期period,开启有初始化延迟的定时器过程如下:

[attach]25969[/attach]



下面通过一个定时器实验代码,来具体讲解定时器的使用:



本实验新建两个任务:任务 A 和任务 B,任务 A 用于创建两个定时器:定时器 1 和定 时器 2,任务 A 还创建了另外一个任务 B。其中定时器 1 为周期定时器,初始延时为 200ms, 以后的定时器周期为 1000ms,定时器 2 为单次定时器,延时为 2000ms。
任务 B 作为按键检测任务,当 KEY_UP 键按下的时候,打开定时器 1;当 KEY0 按下的时 候打开定时器 2;当 KEY1 按下的时候,同时关闭定时器 1 和 2;任务 B 还用来控制 LED0,使其闪烁,提示系统正在运行。
定时器 1 定时完成以后调用回调函数刷新其工作区域的背景,并且在 LCD 上显示定时器 1 运行的次数。定时器 2 定时完成后也调用其回调函数来刷新其工作区域的背景,并且显示运行 次数,由于定时器 2 是单次定时器,我们通过串口打印来观察单次定时器的运行情况。



首先最重要的就是定义两个定时器,OS_TMR是一个结构体。

[attach]25970[/attach]

在main函数里,我们主要完成外设的初始化,在LCD上显示一些信息,绘制了定时器1和2的工作范围

[attach]25971[/attach]

还调用了OSTaskCreate()函数创建了start_task任务

[attach]25972[/attach]

我们在start_task任务中创建两个定时器:

使用OSTmrCreate()函数创建一个软件定时器1,此为周期定时器,初始延时为200ms,周期1000ms。软件定时器2为单次定时器,初始延时为2000ms。

[attach]25973[/attach]

并且在start_task任务中创建任务1:

[attach]25974[/attach]

定时器1和2具体的实现功能,是在对应的两个回调函数中实现的:

[attach]25975[/attach]

定时器1,2开启在task1中实现

[attach]25976[/attach]

代码编译完成后,下载到开发板

初始状态定时器1,2都没打开,只有led0闪烁

[attach]25977[/attach]

定时器1,2工作区域都为白色,运行次数都为0,当按下KEY_UP时,定时器1开始工作

[attach]25978[/attach]

上图看出定时器运行了17次,而定时器为0,因为此时没有开启定时器2,注意:当我们按下key_up后,左边区域没有立即刷新为其他颜色,因为定时器1开启时存在,初始化延时,当初始化延时完成计时后,才调用定时器1回调函数。



[attach]25979[/attach]

上图表示按下key0,开启定时器2,等待2000ms后刷新颜色,因为定时器2为单次定时器,所以只调用一次回调函数,若要再打开一次定时器2,可再按key0.









欢迎光临 嵌入式开发交流网论坛 (http://www.dianzixuexi.com/bbs/) Powered by Discuz! X3.2