- TimerHandle_t xTimerCreate( const char * const pcTimerName,
- const TickType_t xTimerPeriodInTicks,
- const BaseType_t xAutoReload,
- void * const pvTimerID,
- TimerCallbackFunction_t pxCallbackFunction );
函数参数说明:
const char * const pcTimerName:定时器名称。
const TickType_t xTimerPeriodInTicks:定时器的周期
const BaseType_t xAutoReload:是否自动重载。
void * const pvTimerID:定时器标识ID
TimerCallbackFunction_t pxCallbackFunction:回调函数
返回值说明:
TimerHandle_t:创建的定时器句柄。创建失败为NULL。
定时器周期
直译过来,就是表示多少次Tick运行一个周期。
稍微直白点说,多少次Tick执行一次回调函数。
如果需要再直白点描述,就需要把Tick概念了解清楚。在 FreeRTOS 中,Tick(时钟节拍)是指 FreeRTOS 内核使用的基本时间单位。它代表了内核中的时间流逝。在FreeRTOSConfig.h中默认配置有这个Tick的频率,configTICK_RATE_HZ默认值为1000,表示1秒钟有1000个Tick。Tick可以理解为数数,1秒钟数1000下。
回到定时器周期描述上来说,简单来说,操作系统数多少下,执行1次回调函数。
人的认知,可能更好的理解多长时间执行一次这个函数,这里有可以将时间转换为tick计数的方法:pdMS_TO_TICKS.
毫秒转换为Tick计数
- pdMS_TO_TICKS(1000);//参数为毫秒值
自动重载
自动重载,取值有两种:pdFALSE和pdTrue
1. pdFALSE:非自动重载模式。
在非自动重载模式下,定时器只会触发一次,在到期时停止计时,不会自动重新启动。这意味着在定时器到期后,需要手动调用 xTimerStart() 函数重新启动定时器,才能触发下一次定时。
2. pdTRUE:自动重载模式。
在自动重载模式下,定时器在每次到期后会自动重新启动,以便周期性地触发任务或回调函数的执行。定时器到期后,会重新开始计时,等待下一个到期时刻。
回调函数
- // typedef void (* TimerCallbackFunction_t)( TimerHandle_t xTimer );
- void callback(TimerHandle_t xTimer);
定时器标识通常多个定时器公用一个回调时,可以通过标识来判断是哪个个timer触发的。
- // 定时器回调函数
- void timerCallback(TimerHandle_t xTimer)
- {
- // 获取定时器的标识符
- BaseType_t timerID = pvTimerGetTimerID(xTimer);
-
- // 根据标识符处理相应的逻辑
- if (timerID == 1)
- {
- // 处理定时器1的逻辑
- }
- else if (timerID == 2)
- {
- // 处理定时器2的逻辑
- }
- // ...
- }
- ......
- // 创建定时器1,并传递标识符1
- TimerHandle_t timer1 = xTimerCreate("Timer1", pdMS_TO_TICKS(1000), pdTRUE, (void *)1, timerCallback);
-
- // 创建定时器2,并传递标识符2
- TimerHandle_t timer2 = xTimerCreate("Timer2", pdMS_TO_TICKS(2000), pdTRUE, (void *)2, timerCallback);
Timer开启和停止Timer开启API
- xTimerStart(xTimer, xTicksToWait);
第一个参数为timer的句柄
第二个参数表示,多少个tick后启动timer,0表示立刻启动
Timer停止API
- xTimerStop(xTimer, xTicksToWait);
第一个参数为timer的句柄
第二个参数表示,多少个tick后停止timer,0表示立刻停止
Timer的开启和启动可以重复调用。
Timer删除Timer删除API
- xTimerDelete(xTimer, xTickToWait);
第一个参数为timer的句柄
第二个参数表示,多少个tick后删除timer,0表示立刻删除
Timer一旦删除,就不可以再通过timer的句柄进行启动和停止等操作。
三、开发案例重复Timer和单次Timertimer间隔固定时间执行逻辑
main.c
- #include "gd32f4xx.h"
- #include "systick.h"
- #include <stdio.h>
- #include "main.h"
- #include "FreeRTOS.h"
- #include "task.h"
- #include "timers.h"
- #include "usart0.h"
-
- TaskHandle_t start_handler;
- TimerHandle_t timer1;
-
- void Usart0_recv(uint8_t *data, uint32_t len) {
- printf("recv: %s\r\n", data);
- }
-
- void timerCallback(TimerHandle_t xTimer) {
- printf("timer\r\n");
- }
-
- static void GPIO_config() {
- // 时钟初始化
- rcu_periph_clock_enable(RCU_GPIOA);
- // 配置GPIO模式
- gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN_0);
- }
-
- int main(void)
- {
- NVIC_SetPriorityGrouping(NVIC_PRIGROUP_PRE4_SUB0);
- systick_config();
- GPIO_config();
- Usart0_init();
-
- timer1 = xTimerCreate("Timer1", pdMS_TO_TICKS(1000), pdTRUE, (void *)1, timerCallback);
- xTimerStart(timer1, 0);
-
- vTaskStartScheduler();
-
- while(1) {}
- }
Timer启停控制通过按键启动和停止Timer
main.c
- #include "gd32f4xx.h"
- #include "systick.h"
- #include <stdio.h>
- #include "main.h"
- #include "FreeRTOS.h"
- #include "task.h"
- #include "timers.h"
- #include "usart0.h"
-
- TaskHandle_t start_handler;
- TaskHandle_t task_key_handler;
- TimerHandle_t timer1;
-
-
- void task_key(void *pvParameters) {
- uint32_t flag = 0;
- FlagStatus pre_state = RESET;
- BaseType_t result;
- while(1) {
- FlagStatus state = gpio_input_bit_get(GPIOA, GPIO_PIN_0);
- if(SET == state && pre_state == RESET) {
- // 当前高电平, 上一次为低电平,按下
- pre_state = state;
-
- if(flag == 1) {
- printf("stop\r\n");
- xTimerStop(timer1, 0);
- } else {
- printf("start\r\n");
- xTimerStart(timer1, 0);
- }
- flag ++;
- if(flag == 2) flag = 0;
- } else if(RESET == state && pre_state == SET) {
- // 当前高电平, 上一次为低电平,抬起
- pre_state = state;
- }
- vTaskDelay(20);
- }
- }
-
- void Usart0_recv(uint8_t *data, uint32_t len) {
- printf("recv: %s\r\n", data);
- }
-
- void timerCallback(TimerHandle_t xTimer) {
- printf("timer\r\n");
- }
-
- void start_task(void *pvParameters) {
- taskENTER_CRITICAL();
-
- timer1 = xTimerCreate("Timer1", pdMS_TO_TICKS(1000), pdTRUE, (void *)1, timerCallback);
- xTaskCreate(task_key, "task_key", 64, NULL, 2, &task_key_handler);
-
- vTaskDelete(start_handler);
-
- taskEXIT_CRITICAL();
- }
-
- static void GPIO_config() {
- // 时钟初始化
- rcu_periph_clock_enable(RCU_GPIOA);
- // 配置GPIO模式
- gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN_0);
- }
-
- int main(void)
- {
- NVIC_SetPriorityGrouping(NVIC_PRIGROUP_PRE4_SUB0);
- systick_config();
- GPIO_config();
- Usart0_init();
-
- xTaskCreate(start_task, "start_task", 128, NULL, 1, &start_handler);
- vTaskStartScheduler();
-
- while(1) {}
- }
中断中启停Timer在中断中启动和停止Timer
main.c
- #include "gd32f4xx.h"
- #include "systick.h"
- #include <stdio.h>
- #include "main.h"
- #include "FreeRTOS.h"
- #include "task.h"
- #include "timers.h"
- #include "usart0.h"
-
- TaskHandle_t start_handler;
- TaskHandle_t task_key_handler;
- TimerHandle_t timer1;
-
-
- void task_key(void *pvParameters) {
- uint32_t flag = 0;
- FlagStatus pre_state = RESET;
- BaseType_t result;
- while(1) {
- FlagStatus state = gpio_input_bit_get(GPIOA, GPIO_PIN_0);
- if(SET == state && pre_state == RESET) {
- // 当前高电平, 上一次为低电平,按下
- pre_state = state;
-
- if(flag == 1) {
- printf("stop\r\n");
- xTimerStop(timer1, 0);
- } else {
- printf("start\r\n");
- xTimerStart(timer1, 0);
- }
- flag ++;
- if(flag == 2) flag = 0;
- } else if(RESET == state && pre_state == SET) {
- // 当前高电平, 上一次为低电平,抬起
- pre_state = state;
- }
- vTaskDelay(20);
- }
- }
-
- void Usart0_recv(uint8_t *data, uint32_t len) {
- printf("recv: %s\r\n", data);
- if(data[0] == 0x00) {
- printf("start \r\n");
- xTimerStartFromISR(timer1, NULL);
- } else if(data[0] == 0x01) {
- printf("stop \r\n");
- xTimerStopFromISR(timer1, NULL);
- }
- }
-
- void timerCallback(TimerHandle_t xTimer) {
- printf("timer\r\n");
- }
-
- void start_task(void *pvParameters) {
- taskENTER_CRITICAL();
-
- timer1 = xTimerCreate("Timer1", pdMS_TO_TICKS(1000), pdTRUE, (void *)1, timerCallback);
- xTaskCreate(task_key, "task_key", 64, NULL, 2, &task_key_handler);
-
- vTaskDelete(start_handler);
-
- taskEXIT_CRITICAL();
- }
-
- static void GPIO_config() {
- // 时钟初始化
- rcu_periph_clock_enable(RCU_GPIOA);
- // 配置GPIO模式
- gpio_mode_set(GPIOA, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, GPIO_PIN_0);
- }
-
- int main(void)
- {
- NVIC_SetPriorityGrouping(NVIC_PRIGROUP_PRE4_SUB0);
- systick_config();
- GPIO_config();
- Usart0_init();
-
- xTaskCreate(start_task, "start_task", 128, NULL, 1, &start_handler);
- vTaskStartScheduler();
-
- while(1) {}
- }