μC/OS-II软件定时器的基本使用主要分为两步:创建与启动
一、基本知识
1、创建定时器
OS_TMR *OSTmrCreate
(
INT32U dly,
INT32U period,
INT8U opt,
OS_TMR_CALLBACK callback,
void *callback_arg,
INT8U *pname,
INT8U *perr
)
入口参数解释:
(1)dly:延时时间(单位:(1/OS_TMR_CFG_TICKS_PER_SEC)秒)
如果参数opt为:OS_TMR_OPT_ONE_SHOT,则dly表示定时器超时时间
如果参数opt为:OS_TMR_OPT_PERIODIC,则dly表示定时器在开始循环模式前等待第一次启动的超时时间
(2)period:定时器重复运行的时间周期(单位:(1/OS_TMR_CFG_TICKS_PER_SEC)秒)
如果参数opt为:OS_TMR_OPT_PERIODIC,则period表示定时器自动周期重启的时间
如果参数opt为:OS_TMR_OPT_ONE_SHOT,则period无效
(3)opt:选择定时器运行模式
如果参数opt为:OS_TMR_OPT_PERIODIC,则表示定时器会自动重载超时时间,周期运行
如果参数opt为:OS_TMR_OPT_ONE_SHOT,则表示定时器只运行一次
(4)callback:超时处理回调函数(定时器中断服务程序)
必须定义成类似这种函数接口的形式:void MyCallback (OS_TMR *ptmr, void *p_arg);
当定时器时间到了,就执行这个函数
(5)callback_arg:当callback被调用时传递给callback的入口参数
(6)pname:定时器的名称(是一个字符串,如"Timer0")
(7)*perr:定时器错误码,是下面之一:
OS_ERR_NONE:没有错误
OS_ERR_TMR_INVALID_DLY:指定了一个无效的延时时间
OS_ERR_TMR_INVALID_PERIOD:指定了一个无效的周期
OS_ERR_TMR_INVALID_OPT:指定了一个无效的选项
OS_ERR_TMR_ISR :在中断服务程序里调用错误
OS_ERR_TMR_NON_AVAIL:定时器池里没有空闲的定时器
2、启动定时器
BOOLEAN OSTmrStart (OS_TMR *ptmr, INT8U *perr)
这个函数是用来被应用程序调用,来启动定时器的。
入口参数解释:
(1)ptmr:指向待启动的定时器
(2)*perr:错误码
注意:μC/OS-II定时器的创建、启动等函数不能在中断服务程序里调用
二、使用举例
void OS_Timer0(OS_TMR *ptmr, void *p_arg)
{
static INT8U led = 1;
OSIntEnter();
led = !led;
LED0 = led;
OSIntExit();
}
//LED0任务
void led0_task(void *pdata)
{
OS_TMR *pTimer0 = 0;
INT8U err = 0;
pdata = pdata;
//创建定时器
pTimer0 = OSTmrCreate(0,
OS_TMR_CFG_TICKS_PER_SEC,
OS_TMR_OPT_PERIODIC,
//OS_TMR_OPT_ONE_SHOT,
(OS_TMR_CALLBACK)OS_Timer0,
(INT8U *)0,
"OSTIMER0",
&err);
OSTmrStart(pTimer0, &err); //启动定时器
while (1)
{
delay_ms(1000);
}
}
OSTmrCreate函数参数period为OS_TMR_CFG_TICKS_PER_SEC,故超时周期为:
(OS_TMR_CFG_TICKS_PER_SEC / OS_TMR_CFG_TICKS_PER_SEC)秒,即1秒
所以,OS_Timer0会每秒钟被调用一次,LED0会亮一秒、灭一秒的循环。
三、注意:
(1)OS_TMR_CFG_TICKS_PER_SEC的值决定超时时间的分辨率,值越大,能设定的超时时间越小,
假设设定dly或者period的为值x,则实际超时时间为:(x / OS_TMR_CFG_TICKS_PER_SEC)秒
(2)OS_TICKS_PER_SEC的值决定μC/OS-II的时间片(即心跳周期),假设其值为100,则OS时间片为(1000ms / 100)= 10ms
即μC/OS-II时间片为(1000 / OS_TICKS_PER_SEC)毫秒
四、小技巧
可以利用MCU I/O口外部中断加μC/OS-II的软件定时器实现按键的消抖。具体是按按键触发I/O硬件中断,
然后在I/O中断服务程序里发送信号量给一个阻塞的任务,这个阻塞的任务获取信号量后运行定时器启动函数,
最后在定时器超时处理函数里读取按键I/O电平值来判断按键是否按下和抬起,来得到相应键值。故中断触发
方式可以配置为双边沿触发。
|