使用FREERTOS软件定时器组

    刚刚学会用FREERTOS,刚好称公司项目需要,就学习着用,有几个定时需求,本来想使用硬件中断定时器,再用软件做个分组定时,刚好看到FREERTOS有软件定时器组,就想用用试试看效果;

    使用的是FREERTOSV10.0.1,MCU用的是STM32F205RET6,定时需要都是10S,2S,3S,最小单位为ms级;

FREERTOS默认定时为1MS,即#define configTICK_RATE_HZ ( ( TickType_t ) 1000 )

减小此值,定时精度更准,但开销更大,增大此值,精度变低;

1、移植好FREERTOS并编译好后,需要在freertosconfig.h增加软件定时器宏定义,如下

/* set soft timers para. */
#define configUSE_TIMERS 1
#define configTIMER_TASK_PRIORITY  2
#define configTIMER_QUEUE_LENGTH   3
#define configTIMER_TASK_STACK_DEPTH    512

/*end of set soft timer para */

configUSE_TIMERS  即使能,软件定时器实际上也是一种queue形式任务,故需要设置优先级,长度与深度;

2、创建任务

void UserTimerCreate (void)
{
uint8_t i;
for(i = 0;i< TIMER_MAX; i++)
{
xTimersName[i] = xTimerCreate("Timer",  
timer_len[i],  
pdTRUE,
(void *) timer_id[i],   
  vTimerCallback);
if(xTimersName[i] == NULL)
{
printf("timer cread is error, timer id is:%d",timer_id[i]); 
}
else
{
  printf("timer cread is ok, timer id is:%d\n\r",timer_id[i]); 
  if(xTimerStart(xTimersName[i], 100) != pdPASS)
  {
  printf("timer is start timer id is:%d\n\r",timer_id[i]); 
  }
}
}
}

其中

timer_len[i],即每个定时成员定时长度,值=1即为1ms,

timer_id[i]即返回的句柄,用于判别是哪个定时到达;

xTimerStart()用于启动定时器任务;

vTimerCallback(),回调函数,用于处理定时到达任务,一个回调函数可以多个定时任务,通过句柄判别定时ID;

2、处理定时

void vTimerCallback(TimerHandle_t xTimer)
{
uint8_t i;
float temp;
User_Timers_Id ulTimerID;
ulTimerID = (User_Timers_Id)pvTimerGetTimerID(xTimer);
if(ulTimerID == timer_id[TIMER_BUTTON_CHECK])
{
Button_check();
if(xTimerStart(xTimersName[TIMER_BUTTON_CHECK], 10) != pdPASS)
{
printf("restart timer id:%d\n\r",timer_id[TIMER_BUTTON_CHECK]); 
}

}

}

其中

(1)、pvTimerGetTimerID即获取定时ID,定时到达即可作相应定时处理;

(2)、定时处理完毕后,重新启动;

3、变更定时时长

void xTimerChPeriod( TimerHandle_t xTimer ,const BaseType_t new_Period)
{
BaseType_t wait_time;
wait_time = 300;
     // 修改定时器周期
     if(pre_Period == new_Period)
  {
  }
else
{
if(xTimerStopFromISR(xTimersName,&wait_time) == pdPASS)
{
    if( xTimerChangePeriodFromISR( xTimer, 
           /*修改定时周期*/
           new_Period, 
       /*允许阻塞最大时间 1s*/
       &wait_time ) != pdPASS )
    {
        // update fail
        // 阻塞 100 tick 仍然无法发送命令
        // 删除定时器 释放对应内存!
        //xTimerDelete( xTimer );
         //PRINTF("change timer period is error ,stop timer\r\n");
    }
    else 
    {
//PRINTF("change timer period is succes ,then start ,new period is:%d s\r\n",new_Period);
if(xTimerStartFromISR(xTimersName, &wait_time) != pdPASS)
{
//PRINTF("timer is restart\r\n"); 
}
    }
}
}

}

其中:

1、xTimerStopFromISR,停止定时器,用于中断函数中,非中断函数用xTimerStop;

2、xTimerChangePeriodFromISR,也是用于中断,非中断用xTimerChangePeriod;

你可能感兴趣的:(FREERTOS)