【FreeRTOS】软件定时器

目录

一、软件定时器简介

二、单次定时器与周期定时器

三、定时器相关的宏设置

四、常用API函数

1、创建定时器

(1)动态方法

(1)静态方法

2、开启定时器

(1)任务级

(2)中断级

3、复位定时器

(1)任务级

(2)中断级

4、停止定时器

(1)任务级

(2)中断级

五、定时器使用案例


一、软件定时器简介

        定时器是MCU的外设,硬件定时器不仅仅能用来定时,还能用作PWM输出、输入捕获等功能,其功能强大。但是硬件定时器是有限个数的,不同型号的MCU其定时器的个数也不一样。在FreeRTOS中提供了软件定时器,其功能较为简单,仅仅是将某个任务定时一段时间再执行而已。软件定时器是依据系统节拍来计时的,对于精度要求不高的任务可以使用软件定时器。软件定时器服务函数相当于硬件定时器中断服务函数。定时器服务函数中不能使用带有阻塞的函数,例如vTaskDelay()、vTaskDelayUnti()以及带有非0阻塞的访问队列或信号量的函数。

二、单次定时器与周期定时器

       软件定时器有单次的和周期的。单次定时器即该定时器只计时一次(对应任务执行一次)就自动关闭了;周期定时器即定时器周期性计时(对应任务周期性执行),需要关闭则要手动关闭。

三、定时器相关的宏设置

       文件"FreeRTOSConfig.h"中。

#define configUSE_TIMERS                      1
// 1:使用软件定时器  0:不使用软件定时器

#define configTIMER_TASK_PRIORITY             ( 2 )
//定时器服务任务的任务优先级(范围与任务优先级一致)

#define configTIMER_QUEUE_LENGTH            10
//设置定时器命令队列的队列长度

#define configTIMER_TASK_STACK_DEPTH      ( configMINIMAL_STACK_SIZE * 2 )
//服务任务的任务堆栈大小,单位字!

四、常用API函数

        相关函数及定义在文件”timers.c”及”timers.h”中。

1、创建定时器

(1)动态方法

TimerHandle_t xTimerCreate( const char * const pcTimerName,
                            const TickType_t xTimerPeriodInTicks,
                            const UBaseType_t uxAutoReload,
                            void * const pvTimerID,
                            TimerCallbackFunction_t pxCallbackFunction )

/*参数:
pcTimerName:        定时器名字,字符串类型;
xTimerPeriodInTicks:定时周期,单位为系统时钟节拍数;
uxAutoReload:       定时器模式,pdTRUE为周期性,pdFALSE为单次定时器;
pvTimerID:          定时器ID,当多个定时器使用同一服务函数时,通过ID来处理不同的定时器;
pxCallbackFunction: 定时器服务函数;

返回值:创建成功返回定时器句柄,失败NULL;
*/

(1)静态方法

        所需要的内存需要用户自行分配。

TimerHandle_t xTimerCreateStatic( const char * const pcTimerName,
                                  const TickType_t xTimerPeriodInTicks,
                                  const UBaseType_t uxAutoReload,
                                  void * const pvTimerID,
                                  TimerCallbackFunction_t pxCallbackFunction,
                                  StaticTimer_t * pxTimerBuffer )

/*参数:
pcTimerName:        定时器名字,字符串类型;
xTimerPeriodInTicks:定时周期,单位为系统时钟节拍数;
uxAutoReload:       定时器模式,pdTRUE为周期性,pdFALSE为单次定时器;
pvTimerID:          定时器ID,当多个定时器使用同一服务函数时,通过ID来处理不同的定时器;
pxCallbackFunction: 定时器服务函数;
pxTimerBuffer:      指向StaticTimer_t类型变量,用于保存定时器结构体;

返回值:创建成功返回定时器句柄,失败NULL;
*/

2、开启定时器

        在软件定时器创建完成的时候并没有开始运行,需要调用开启函数来开启。

(1)任务级

/*函数原型*/
BaseType_t xTimerStart( TimerHandle_t xTimer, TickType_t xTicksToWait )

/*
参数:
xTimer:        定时器句柄;
xTicksToWait:  阻塞时间;

返回值:
pdPASS:开启成功
pdFAIL:开启失败,命令发送失败

*/

/*函数宏定义*/

#define xTimerStart( xTimer, xTicksToWait ) \
        xTimerGenericCommand( ( xTimer ), 
                                tmrCOMMAND_START, 
                              ( xTaskGetTickCount() ), 
                                NULL,
                              ( xTicksToWait ) )

(2)中断级

/*函数原型*/
BaseType_t xTimerStartFromISR(   TimerHandle_t xTimer,
                                 BaseType_t *pxHigherPriorityTaskWoken );
/*
参数:
xTimer:                   定时器句柄;
pxHigherPriorityTaskWoken:标记退出此函数后是否进行任务切换,只需提供变量来保存,当该值为pdTRUE
                           时需要进行任务切换;

返回值:
pdPASS:开启成功
pdFAIL:开启失败,命令发送失败
*/



/*函数宏定义*/
#define xTimerStartFromISR( xTimer, pxHigherPriorityTaskWoken ) \
        xTimerGenericCommand( ( xTimer ), 
                                tmrCOMMAND_START_FROM_ISR, 
                              ( xTaskGetTickCountFromISR() ), 
                              ( pxHigherPriorityTaskWoken ),
                                0U )

3、复位定时器

     复位定时器并不是将定时器计数值清零,而是将响应的时间在该时刻延后一个计时周期。在未开启定时器状态下使用复位函数也能开启定时器(与开启函数使用同一个函数)。

(1)任务级

/*函数原型*/
BaseType_t xTimerReset( TimerHandle_t xTimer, TickType_t xTicksToWait )

/*
参数:
xTimer:       定时器句柄;
xTicksToWait: 阻塞时间;

返回值:
pdPASS:复位成功,即命令发送成功
pdFAIL:复位失败,即命令发送失败

*/

/*函数宏定义*/
#define xTimerReset( xTimer, xTicksToWait ) \
        xTimerGenericCommand( ( xTimer ),
                                tmrCOMMAND_RESET, 
                              ( xTaskGetTickCount() ), 
                                NULL, 
                              ( xTicksToWait ) )

(2)中断级

/*函数原型*/
BaseType_t xTimerResetFromISR(   TimerHandle_t xTimer,
                                 BaseType_t *pxHigherPriorityTaskWoken );
/*
参数:
xTimer:                   定时器句柄;
pxHigherPriorityTaskWoken:标记退出此函数后是否进行任务切换,只需提供变量来保存,当该值为pdTRUE
                           时需要进行任务切换;

返回值:
pdPASS: 复位成功,即命令发送成功
pdFAIL: 复位失败,即命令发送失败
*/

/*函数宏定义*/
#define xTimerResetFromISR( xTimer, pxHigherPriorityTaskWoken ) \
        xTimerGenericCommand( ( xTimer ),
                                tmrCOMMAND_RESET_FROM_ISR, 
                              ( xTaskGetTickCountFromISR() ), 
                              ( pxHigherPriorityTaskWoken ), 
                                0U )

4、停止定时器

(1)任务级

/*函数原型*/
BaseType_t xTimerStop( TimerHandle_t xTimer, TickType_t xTicksToWait );

/*
参数:
xTimer:      定时器句柄;
xTicksToWait:阻塞时间;

返回值:
pdPASS: 停止成功,即命令发送成功
pdFAIL: 停止失败,即命令发送失败
*/



/*函数宏定义*/
#define xTimerStop( xTimer, xTicksToWait ) \
        xTimerGenericCommand( ( xTimer ),
                                tmrCOMMAND_STOP, 
                                0U, 
                                NULL, 
                              ( xTicksToWait ) )

(2)中断级

/*函数原型*/
 BaseType_t xTimerStopFromISR(    TimerHandle_t xTimer,
                                  BaseType_t *pxHigherPriorityTaskWoken );
/*
参数:
xTimer:                   定时器句柄;
pxHigherPriorityTaskWoken:标记退出此函数后是否进行任务切换,只需提供变量来保存,当该值为pdTRUE
                           时需要进行任务切换;

返回值:
pdPASS: 停止成功,即命令发送成功
pdFAIL: 停止失败,即命令发送失败
*/

/*函数宏定义*/
#define xTimerStopFromISR( xTimer, pxHigherPriorityTaskWoken ) \
        xTimerGenericCommand( ( xTimer ), 
                                tmrCOMMAND_STOP_FROM_ISR,
                                0, 
                              ( pxHigherPriorityTaskWoken ), 
                                0U )

五、定时器使用案例

       创建一个软件定时器任务控制LED灯周期性翻转,使用按键控制定时器的开启、关闭和复位。

#include "sys.h"
#include "delay.h"
#include "usart.h"
#include "led.h"
#include "key.h"
#include "FreeRTOS.h"          
#include "task.h"
#include "core_cm4.h"
#include "timers.h"

TaskHandle_t start_taskHandle;				//任务句柄
void start_task(void *pvParameters);	//函数声明

TaskHandle_t key_taskHandle;					//任务句柄
void key_task(void *pvParameters);		//函数声明

//定时器服务函数
void TimerTask_1(void *pvParameters);
TimerHandle_t TimerTask_1Handle_t;		//定时器任务句柄



int main(void)
{ 
	SysTick_Config(168000);
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_4);//设置系统中断优先级分组4
//	delay_init(168);		//初始化延时函数
	uart_init(115200);     	//初始化串口
	LED_Init();		        //初始化LED端口
	KEY_Init();
	
    

	 xTaskCreate( (TaskFunction_t			) start_task,    //任务函数
				  (const char *				) "start_task",  //函数名称
				  (configSTACK_DEPTH_TYPE	) 128,           //堆栈大小
				  (void * 			 		) NULL,          //传给任务函数的参数
				  (UBaseType_t 				)	1,           //优先级
				  (TaskHandle_t * 			) &start_taskHandle);//任务句柄
								
    vTaskStartScheduler();          //开启任务调度
								
								

}
 



//开始任务任务函数
void start_task(void *pvParameters)
{
    //taskENTER_CRITICAL();           //进入临界区
    //创建按键任务
	 xTaskCreate( (TaskFunction_t		   ) key_task,
				  (const char *			   ) "key_task", 
				  (configSTACK_DEPTH_TYPE  )  128,
				  (void * 			 	   )  NULL,
				  (UBaseType_t 			   )  3,
				  (TaskHandle_t * 		   ) &key_taskHandle); 
    	
	//创建定时器任务	
	TimerTask_1Handle_t	= xTimerCreate( ( char *     ) "TimerTask_1",    //定时器名称
										( TickType_t ) 1000,            //延迟周期
										( UBaseType_t) pdTRUE,          //周期性
										( void *     ) 1,				//ID											    
                                        (TimerCallbackFunction_t) TimerTask_1);//服务函数	 

	vTaskDelete(start_taskHandle);		//删除该任务
	
  //taskEXIT_CRITICAL();            //退出临界区
}

//定时器服务函数
void TimerTask_1(void *pvParameters)
{
	LED0=~LED0;
	LED1=~LED1;
}
  

//按键任务函数
void key_task(void *pvParameters)
{
	int key_num=0;
	while(1)
	{
		key_num = KEY_Scan(0);
		if(key_num == KEY0_PRES)
		{
			xTimerStart( TimerTask_1Handle_t, 1 );
			printf("开启定时器任务\r\n");
		}
		else if(key_num == KEY1_PRES)
		{
			xTimerStop( TimerTask_1Handle_t, 1 );
			printf("关闭定时器任务\r\n");
		}
		else if(key_num == WKUP_PRES)
		{
			xTimerReset( TimerTask_1Handle_t, 1 );
			printf("复位定时器任务\r\n");
		}
		else  
			vTaskDelay(20);
	}
}






  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值