uCosIII之软件定时器的使用

uCosIII 软件定时器使用实例


uCosIII软件定时器简介:

uC/OS-III提供了一些函数用于管理定时器,如下表:

函数名 功能
OSTmrCreate() 创建和设置定时器
OSTmrDel() 删除一个定时器
OSTmrRemainGet() 获得定时器的剩余期限值
OSTmrStart() 开始定时器运行
OSTmrStateGet() 获得定时器当前的状态
OSTmrStop() 暂停定时









我们在使用各个API之前我们先来看看软件定时器创建的API,通过不同的参数我们可以创建几种不同的软件定时器

void OSTmrCreate (OS_TMR *p_tmr, 			/* Pointer to timer */
		  CPU_CHAR *p_name, 			/* Name of timer, ASCII */
		  OS_TICK dly, 				/* Initial delay */
		  OS_TICK period, 			/* Repeat period */
		  OS_OPT opt, 				/* Options */
		  OS_TMR_CALLBACK_PTR p_callback, 	/* Fnct to call at 0 */
		  void *p_callback_arg, 		/* Arg. to callback */
		  OS_ERR *p_err) 


定时器可以被设置为3种模式: 一次性定时模式, 无初始定时周期模式( 没有初始的定时),有初始定时周期模式(有初始的定时)、


实例一:调速设备速度平滑控制(采用无初始定时周期模式)

此实例通过无初始值的周期软件定时器来实现调速设备的一个平滑控制,通过输入的指定值和平滑控制时间,计算出控制加速度,然后作为参数创建周期定时器,创建成功后开始定时器并在回调函数中不断将当前速度值与期望速度值进行比较,最终达到期望的速度值。

static      	OS_TMR      FanSpdAdjustTmr;//平滑调节定时器
static  	uint16_t    g_u16FanExpectCtrlSpd = 0;
static  	uint16_t    g_u16FanCurrentCtrlSpd = 0;
static  	uint16_t    g_u16FanAdjAcceleratedSpdVal = 0;

/*
***************************************************************************************************
*                            SetFanExpectSpdSmoothly()
*
* Description : Control the speed of the pump smoothly.
*
* Argument(s) : i_ExpectFanSpdValue:Expect Speed.
*               i_u8SmoothlyControlTimeDly:Adjust delay Time >= 0;if i_u8AdjustTimeDly = 0,set immediately.
*
* Return(s)   : none.
*
* Caller(s)   : none.
*
* Note(s)     : the actual speed grade whole number is 2000.
***************************************************************************************************
*/
void SetFanExpectSpdSmoothly(u16 i_ExpectFanSpdValue, u8 i_u8SmoothlyControlTimeDly)
{
    OS_ERR err;
    uint16_t m_FanSpdDiffValue = 0;

    OSTmrDel(&FanSpdAdjustTmr, &err);//重置定时器状态

    if(i_u8SmoothlyControlTimeDly > 0) { //需要速度平滑处理
        if(i_ExpectFanSpdValue != g_FanExpectCtrlSpd){//产生新的期望速度
            g_FanExpectCtrlSpd = i_ExpectFanSpdValue;
        }
        
        if(g_FanCurrentCtrlSpd != g_FanExpectCtrlSpd) {
            m_FanSpdDiffValue = abs(g_FanExpectCtrlSpd - g_FanCurrentCtrlSpd);
        }
        
        /*加速度计算*/
        g_FanAdjAcceleratedSpdVal = m_FanSpdDiffValue / 2 / i_u8SmoothlyControlTimeDly;
        
        OSTmrCreate((OS_TMR *)&FanSpdAdjustTmr,
                    (CPU_CHAR *)"Fan Speed Adjust Timer",
                    (OS_TICK)0,
                    (OS_TICK) OS_CFG_TMR_TASK_RATE_HZ / 2,      /* control cycle 0.5s */
                    (OS_OPT)OS_OPT_TMR_PERIODIC,
                    (OS_TMR_CALLBACK_PTR)FanAdjustCallBack,
                    (void *)0,
                    (OS_ERR *)&err);

        if(err == OS_ERR_NONE) {
            OSTmrStart(&FanSpdAdjustTmr, &err);
        }
    } else {
        SetFanCurrentCtrlSpd(i_ExpectFanSpdValue);
    }
}
/*
***************************************************************************************************
*                            FanAdjustCallBack()
*
* Description : when FanSpdAdjustTmr time out that call back function.
*
* Argument(s) : none.
*
* Return(s)   : none.
*
* Caller(s)   : Application.
*
* Note(s)     : none.
***************************************************************************************************
*/
static void FanAdjustCallBack(OS_TMR *p_tmr, void *p_arg)
{	
      OS_ERR err;
    uint16_t FanCurrentCtlSpd = 0;
    FanCurrentCtlSpd = GetFanCurrentCtrlSpd();
    if(FanCurrentCtlSpd != GetFanExpectCtrlSpd()) {
        if(FanCurrentCtlSpd > GetFanExpectCtrlSpd()) {
            if(FanCurrentCtlSpd > g_FanAdjAcceleratedSpdVal){//防止减溢出
                FanCurrentCtlSpd -= g_FanAdjAcceleratedSpdVal;
            }else{
                FanCurrentCtlSpd = 0;
            }
        } else {
            FanCurrentCtlSpd += g_FanAdjAcceleratedSpdVal;
            if(FanCurrentCtlSpd >= g_FanExpectCtrlSpd){
                FanCurrentCtlSpd = g_FanExpectCtrlSpd;
            }
        }
        SetFanCurrentCtrlSpd(FanCurrentCtlSpd);
    } else {
        OSTmrDel(&FanSpdAdjustTmr, &err);
    }
}

实例二:调速设备速度阶梯延时控制(采用有初始定时周期模式)


此实例通过采用有初始定时周期模式的软件定时器来实现一个阶梯延时控制调速设备的功能,通过输入初始速度和终止期望速度以及第一次延迟时间和周期延时时间来创建我们的软件定时器,之后开启软件定时器并在回调函数中不断与期望速度进行比较直到达到我们的期望速度值。

static      	OS_TMR      FanSpdSteppedCycleDlyAdjustTmr;//风机阶梯延时调节定时器
static  	uint16_t    g_FanExpectCtrlSpd = 0;
static  	uint16_t    g_FanCurrentCtrlSpd = 0;

/*
***************************************************************************************************
*                                         SetFanSpdSteppedCycleDelay()
*
* Description : Delay for a period of time to set the fan speed stepped.
*
* Arguments   : i_StartSpdVal:the start fan speed.
*				i_u8StartDlyAdjTime:start adjust delay time.
*               i_u8DelayTime:Adjust the cycle time delay(s),if i_u8DelayTime =0,set immediately.
*               i_u16ExpectSpdValue:the expected hydrogen fan speed.
*
* Returns     : none.
*
* Notes       : the actual speed grade whole number is 2000.
***************************************************************************************************
*/
void SetFanSpdSteppedCycleDelay(uint16_t i_StartSpdVal, uint8_t i_FirstDlyAdjTime, uint8_t i_CycleDlyAdjTime, uint16_t i_ExpSpdVal)
{
    OS_ERR err;

    OSTmrDel(&FanSpdSteppedCycleDlyAdjustTmr, &err);//重置定时器状态
    g_FanExpectCtrlSpd = i_ExpSpdVal ;

    if((i_FirstDlyAdjTime > 0) || (i_CycleDlyAdjTime > 0)) {
        OSTmrCreate((OS_TMR *)&FanSpdSteppedCycleDlyAdjustTmr,
                    (CPU_CHAR *)"Fan Speed cycle Delay Adjust Timer",
                    (OS_TICK)i_FirstDlyAdjTime * OS_CFG_TMR_TASK_RATE_HZ,//首次延时dly(s)
                    (OS_TICK)i_CycleDlyAdjTime * OS_CFG_TMR_TASK_RATE_HZ,//周期延时cycle(s)
                    (OS_OPT)OS_OPT_TMR_PERIODIC,
                    (OS_TMR_CALLBACK_PTR)FanSpdCycleDlyAdjCallBack,
                    (void *)0,
                    (OS_ERR *)&err);
                    
         if(err == OS_ERR_NONE) {
            OSTmrStart(&FanSpdSteppedCycleDlyAdjustTmr, &err);   
        }          
    } else {
        SetFanCtrlSpd(g_FanExpectCtrlSpd);
    }  
    SetFanCtrlSpd(i_StartSpdVal);
}

/*
***************************************************************************************************
*                            FanSpdCycleDlyAdjCallBack()
*
* Description : when FanSpdSteppedCycleDlyAdjustTmr time out that call back function.
*
* Argument(s) : none.
*
* Return(s)   : none.
*
* Note(s)     : none.
***************************************************************************************************
*/
static void FanSpdCycleDlyAdjCallBack(OS_TMR *p_tmr, void *p_arg)
{
    OS_ERR err;

    if(g_FanCurrentCtrlSpd != g_FanExpectCtrlSpd) {
        if(g_FanCurrentCtrlSpd < g_FanExpectCtrlSpd) {
            FanCtrSpdInc();
        } else {
            FanCtrSpdDec();
        }
    } else {
        OSTmrDel(&FanSpdSteppedCycleDlyAdjustTmr, &err);
    }
}

总结:
uCos软件定时器用起来还是比较灵活的,主要是灵活的进行参数的设置,单次、周期、单次+周期,活学活用嘛!
参数设置的时候用这个定时器专用的宏OS_CFG_TMR_TASK_RATE_HZ会比用OS_CFG_TICK_TASK_PRIO要好,防止别人在用你的API的时候系统时钟节拍不一样而出现异常。
发布了13 篇原创文章 · 获赞 16 · 访问量 3万+

猜你喜欢

转载自blog.csdn.net/qq_32969455/article/details/78890826