定时器,由RT_Thread虚拟出来得定时器,输入的参数有五个;相对于硬件的定时器,虚拟出来的定时器的定时时间的时间精度为滴答时钟起振的倍数,所以精度会有所损失;不过有利就有弊,软件定时器可以虚拟很多啊,也很好用。
/* 静态创建 */
/* 定时器的控制块 */
static struct rt_timer static_timer;
rt_timer_init(&static_timer,
"timer1",
function,
RT_NULL,
10,
RT_TIMER_FLAG_PERIODIC);
/* 动态创建 */
/* 定时器的控制块 */
static rt_timer_t dynamic_timer;
dynamic_tinmer = rt_timer_create("timer1",
function, //响应函数
RT_NULL, //传入响应函数的参数
10,
RT_TIMER_FLAG_PERIODIC); //定时器的定时类型
/*
#define RT_TIMER_FLAG_ONE_SHOT 0x0 //< one shot timer
#define RT_TIMER_FLAG_PERIODIC 0x2 //< periodic timer
*/
和硬件定时器一样,我们也可以操控定时器的启动和暂停。
/*定时器的启动*/
rt_timer_start(&static_timer);
rt_timer_start(dynamic_timer);
/*定时器的停止*/
rt_timer_stop(&static_timer);
rt_timer_stop(dynamic_timer);
/*定时器的修改*/
rt_tick_t value = 60;
rt_timer_control(timer1,type,(void *)&value);
//control函数,有四类输入类型,类型不同,value也不同
/**
* This function will get or set some options of the timer
*
* @param timer the timer to be get or set
* @param cmd the control command
* @param arg the argument
*
* @return RT_EOK
*/
rt_err_t rt_timer_control(rt_timer_t timer, int cmd, void *arg)
{
/* timer check */
RT_ASSERT(timer != RT_NULL);
RT_ASSERT(rt_object_get_type(&timer->parent) == RT_Object_Class_Timer);
switch (cmd)
{
case RT_TIMER_CTRL_GET_TIME:
*(rt_tick_t *)arg = timer->init_tick;
break;
case RT_TIMER_CTRL_SET_TIME:
timer->init_tick = *(rt_tick_t *)arg;
break;
case RT_TIMER_CTRL_SET_ONESHOT:
timer->parent.flag &= ~RT_TIMER_FLAG_PERIODIC;
break;
case RT_TIMER_CTRL_SET_PERIODIC:
timer->parent.flag |= RT_TIMER_FLAG_PERIODIC;
break;
}
return RT_EOK;
}
/* 定时器响应函数 */
static void function(void *parameter)
{
//具体内容
}
//RT_TIMER_FLAG_xxxxx
#define RT_TIMER_FLAG_DEACTIVATED 0x0 /**< timer is deactive */
#define RT_TIMER_FLAG_ACTIVATED 0x1 /**< timer is active */
#define RT_TIMER_FLAG_ONE_SHOT 0x0 /**< one shot timer */
#define RT_TIMER_FLAG_PERIODIC 0x2 /**< periodic timer */
#define RT_TIMER_FLAG_HARD_TIMER 0x0 /**< hard timer,the timer's callback function will be called in tick isr. */
#define RT_TIMER_FLAG_SOFT_TIMER 0x4 /**< soft timer,the timer's callback function will be called in timer thread. */
/*
0 0 0 0
第2位置1,在线程内执行;为0,在系统滴答中执行
第1为置1,周期型的定时器执行,置0者为单次型
第0位置1, 时钟是开启的,这部分的操作被多个函数封装,意义较多
*/
/*如果第2位置1*/
/*
在线程内执行,就不用考虑挂起会导致系统崩溃。
如果第2位为0,则定时器的响应函数,是在系统滴答内执行的,这段时间不允许线程的挂起
*/
/*定时器的删除*/
rt_timer_delete(dynamic_timer);
rt_timer_detach(&static_timer);
/*
* 程序清单:定时器例程
*
* 这个例程会创建两个动态定时器,一个是单次定时,一个是周期性定时
* 并让周期定时器运行一段时间后停止运行
*/
#include
/* 定时器的控制块 */
static rt_timer_t timer1;
static rt_timer_t timer2;
static int cnt = 0;
/* 定时器1超时函数 */
static void timeout1(void *parameter)
{
rt_tick_t timeout = 60;
rt_kprintf("periodic timer is timeout %d\n", cnt);
/* 运行第10次,停止周期定时器 */
if (cnt++ == 10)
{
rt_timer_control(timer1,RT_TIMER_CTRL_SET_TIME,(void *)&timeout);
rt_kprintf("periodic timer was changed! \n");
}
if (cnt++ >= 20)
{
rt_timer_stop(timer1);
rt_kprintf("periodic timer was stopped! \n");
}
}
/* 定时器2超时函数 */
static void timeout2(void *parameter)
{
rt_kprintf("one shot timer is timeout,parameter :%s\n",parameter);
}
int timer_sample(void)
{
/* 创建定时器1 周期定时器 */
timer1 = rt_timer_create("timer1", timeout1,
RT_NULL, 10,
RT_TIMER_FLAG_PERIODIC);
/* 启动定时器1 */
if (timer1 != RT_NULL) rt_timer_start(timer1);
/* 创建定时器2 单次定时器 */
timer2 = rt_timer_create("timer2", timeout2,
"abc", 30,
RT_TIMER_FLAG_ONE_SHOT);
/* 启动定时器2 */
if (timer2 != RT_NULL) rt_timer_start(timer2);
return 0;
}
//打印信息
/*
periodic timer is timeout 0
periodic timer is timeout 2
one shot timer is timeout,parameter :abc
periodic timer is timeout 4
periodic timer is timeout 6
periodic timer is timeout 8
periodic timer is timeout 10
periodic timer was changed!
periodic timer is timeout 12
periodic timer is timeout 14
periodic timer is timeout 16
periodic timer is timeout 18
periodic timer is timeout 20
periodic timer was stopped!
*/