10.软件定时器//依据RT-Thread内核编程的学习记录(非内核实现)

定时器,由RT_Thread虚拟出来得定时器,输入的参数有五个;相对于硬件的定时器,虚拟出来的定时器的定时时间的时间精度为滴答时钟起振的倍数,所以精度会有所损失;不过有利就有弊,软件定时器可以虚拟很多啊,也很好用。

1.定时器的创建

/* 静态创建 */
/* 定时器的控制块 */
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 
*/

2.定时器的启动和停止

和硬件定时器一样,我们也可以操控定时器的启动和暂停。

/*定时器的启动*/

rt_timer_start(&static_timer);

rt_timer_start(dynamic_timer);

/*定时器的停止*/

rt_timer_stop(&static_timer);

rt_timer_stop(dynamic_timer);

3.定时器的修改

/*定时器的修改*/
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;
}

4.响应函数的编写

/* 定时器响应函数 */
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,则定时器的响应函数,是在系统滴答内执行的,这段时间不允许线程的挂起
*/

5.定时器的删除

/*定时器的删除*/

rt_timer_delete(dynamic_timer);

rt_timer_detach(&static_timer);

6.例程

/*
* 程序清单:定时器例程
*
* 这个例程会创建两个动态定时器,一个是单次定时,一个是周期性定时
* 并让周期定时器运行一段时间后停止运行
*/
#include <rtthread.h>

/* 定时器的控制块 */
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! 


*/

猜你喜欢

转载自blog.csdn.net/xiangxistu/article/details/82829669
今日推荐