本文的內(nèi)容結(jié)構如下:
2、freeRTOS的定時器種類
2.1、單次定時器
2.2、周期定時器
3、freeRTOS 軟件定時器的API函數(shù)
3.1、創(chuàng)建軟件定時器
3.2、啟動軟件定時器
3.3、停止定時器
3.4、復位定時器
3.5、查詢定時器是否已經(jīng)開始運行
4、軟件定時器使用實例
freeRTOS中加入了軟件定時器這個功能組件,是一個可選的、不屬于freeRTOS內(nèi)核的功能,由定時器服務(其實就是一個定時器任務)來提供。
軟件定時器是當設定一個定時時間,當達到設定的時間之后就會執(zhí)行指定的功能函數(shù),而這個功能函數(shù)就叫做 回調(diào)函數(shù) 。
也就是說回調(diào)函數(shù)的兩次執(zhí)行間隔叫做定時器的定時周期。
回調(diào)函數(shù): 回調(diào)函數(shù)就是一個通過函數(shù)指針調(diào)用的函數(shù)。如果你把函數(shù)的指針(地址)作為參數(shù)傳遞給另一個函數(shù),當這個指針被用來調(diào)用其所指向的函數(shù)時,我們就說這是回調(diào)函數(shù)。
1、 freeRTOS中啟用定時器
在freeRTOS中要使用軟件定時器的話,需要在配置文件freeRTOSConfig.h中設置相應的宏,如下:
#define configUSE_TIMERS 1 //使能軟件定時器
#define configTIMER_TASK_PRIORITY 2 // 軟件定時器的優(yōu)先級
#define configTIMER_QUEUE_LENGTH 10 // 軟件定時器的隊列長度
#define configTIMER_TASK_STACK_DEPTH (configMINIMAL_STACK_SIZE * 2) // 軟件定時器的堆棧空間大小(單位是字)
2、freeRTOS的定時器種類
2.1、單次定時器
單次定時器定時時間到了就執(zhí)行一次回調(diào)函數(shù),之后不會再執(zhí)行,只有在再次重新啟動的時候才會再執(zhí)行一次。
2.2、周期定時器
周期定時器根據(jù)設定的時間周期地執(zhí)行的。它一旦啟動以后,每執(zhí)行一次完一次回調(diào)函數(shù)以后定時器會自動重啟,回調(diào)函數(shù)會周期性的執(zhí)行。
3、freeRTOS 軟件定時器的API函數(shù)
3.1、創(chuàng)建軟件定時器
TimerHandle_t xTimerCreate
(
const char * const pcTimerName, /* 定時器名字 */
const TickType_t xTimerPeriod, /* 定時器周期 */
const UBaseType_t uxAutoReload, /* 選擇單次模式或者周期模式 */
void * const pvTimerID, /* 定時器 ID */
TimerCallbackFunction_t pxCallbackFunction ); /* 定時器回調(diào)函數(shù) */
函數(shù)描述:
函數(shù) xTimerCreate 用于創(chuàng)建軟件定時器。
1)第 1 個參數(shù): 定時器名字,一般用于調(diào)試,方便識別不同的定時器。
2)第 2 個參數(shù): 定時器周期,單位是系統(tǒng)時鐘節(jié)拍。
3)第 3 個參數(shù): 選擇定時器是周期模式還是單次模式。若參數(shù)為 pdTRUE ,則表示選擇周期模式,若參數(shù)為 pdFALSE ,則表示選擇單次模式。
4)第 4 個參數(shù): 定時器的 ID。當創(chuàng)建多個不同的定時器,但又使用同一個回調(diào)函數(shù)時,在回調(diào)函數(shù)中就可以通過不同的 ID 號來區(qū)分不同的定時器。
5)第 5 個參數(shù): 定時器的回調(diào)函數(shù)。
返回值: 創(chuàng)建成功返回定時器的句柄,失敗會返回 NULL。
創(chuàng)建一個單次觸發(fā)的軟件定時器示例如下:
TimerHandle_t singalTIMERS; //單次定時器
void singalTimersFunc(TimerHandle_t xTimers); //單次定時器回調(diào)函數(shù)
/*創(chuàng)建單次定時器*/
singalTIMERS = xTimerCreate(
"singalTIMERS", //軟件定時器的名字
1000, //定時周期,單位是時鐘節(jié)拍數(shù)
pdFALSE, //定時器模式,pdTRUE為周期定時器,pdFALSE為單次定時器
(void*)1, //定時器的ID號
singalTimersFunc //定時器回調(diào)函數(shù)
);//
3.2、啟動軟件定時器
1)在任務中啟動
BaseType_t xTimerStart( TimerHandle_t xTimer, /* 定時器句柄 */
TickType_t xBlockTime ); /* 成功啟動定時器前的最大等待時間設置,單位系統(tǒng)時鐘節(jié)拍 */
函數(shù)描述:
函數(shù) xTimerStart 用于啟動軟件定時器。
**1> **第 1 個參數(shù)是定時器句柄。
2> 第 2 個參數(shù)是成功啟動定時器前的最大等待時間設置,單位系統(tǒng)時鐘節(jié)拍。這是定時器組的大部分 API 函數(shù)不是直接運行的,而是通過消息隊列給定時器任務發(fā)消息來實現(xiàn)的,此參 數(shù)設置的等待時間就是當消息隊列已經(jīng)滿的情況下,等待消息隊列有空間時的最大等待時間。
返回值: 返回 pdFAIL 表示此函數(shù)向消息隊列發(fā)送消息失敗,返回 pdPASS 表示此函數(shù)向消息隊列發(fā) 送消息成功。
注意:定時器任務實際執(zhí)行消息隊列發(fā)來的命令依賴于定時器任務的優(yōu)先級,如果定時器任務 是高優(yōu)先級會及時得到執(zhí)行,如果是低優(yōu)先級,就要等待其余高優(yōu)先級任務釋放 CPU 權才可以得到執(zhí)行。
使用這個函數(shù)要注意以下問題:
1> 要使用定時器啟動函數(shù)前提是已經(jīng)通過函數(shù) xTimerCreate 成功創(chuàng)建了軟件定時器。
2> 在 FreeRTOSConfig.h 文件中使能宏定義:
#define configUSE_TIMERS 1
2)在中斷中啟動
BaseType_t xTimerStartFromISR(TimerHandle_t xTimer
BaseType_t* pxHigherPriorityTaskWoken);
函數(shù)描述:
XTimer: 軟件定時器的句柄
pxHigherPriorityTaskWoken: 退出此函數(shù)時是否要進行任務切換
返回值:
pdPASS: 軟件定時器開啟成功。
pdFAIL: 軟件定時器開啟失敗。
3.3、停止定時器
1)在任務中停止軟件定時器
BaseType_t xTimerStop(TimerHandle_t xTime,
TickType_t xTicksToWait)
函數(shù)描述:
xTimer: 軟件定時器的句柄。
xTicksToWait: 阻塞時間,即停止定時器最大的等待時間。
返回值:
pdPASS: 軟件定時器停止成功
pdFAIL: 軟件定時器停止失敗
2)在中斷中停止軟件定時器
xTimerStopFormISR(TimerHandle_t xTimer,
BaseType_t pxHigherPriorityTaskWoken);
函數(shù)描述:
xTimer: 軟件定時器句柄
pxHigherPriorityTaskWoken: 退出此函數(shù)時是否要進行任務切換
返回值:
pdPASS: 軟件定時器開啟成功。
pdFAIL: 軟件定時器開啟失敗。
3.4、復位定時器
1)在任務中復位
BaseType_t xTimerReset(TimerHandle_t xTimer,
TickType_t xTicksToWait)
函數(shù)描述:
xTimer: 軟件定時器的句柄。
xTicksToWait: 阻塞時間,即停止定時器最大的等待時間。
返回值:
pdPASS: 軟件定時器復位成功
pdFAIL: 軟件定時器復位失敗
2)在中斷中復位
BaseType_t xTimerResetFromISR(TimerHandle_t xTimer,
BaseType_t *pxHigherPriorityTaskWoken);
函數(shù)描述:
xTimer: 軟件定時器句柄
pxHigherPriorityTaskWoken: 退出此函數(shù)時是否要進行任務切換
返回值:
pdPASS: 軟件定時器復位成功。
pdFAIL: 軟件定時器復位失敗。
3.5、查詢定時器是否已經(jīng)開始運行
BaseType_t xTimerIsTimerActive( TimerHandle_t xTimer )
查詢定時器以查看它是活動的還是 休眠的 。
如果出現(xiàn)以下情況,計時器將處于休眠狀態(tài):
- 已創(chuàng)建但未啟動。
- 已過期的計時器尚未重新啟動。
返回值:
pdFALSE,沒有運行。
其他值,運行。
4、軟件定時器使用實例
創(chuàng)建2個軟件定時器,ID號分別為1、2,這兩個軟件定時器使用同一個回調(diào)函數(shù),在回調(diào)函數(shù)里面讀取定時器的ID,通過ID識別定時器。
1、創(chuàng)建軟件定時器
TimerHandle_t SoftWaveTimer1; //軟件定時器1
TimerHandle_t SoftWaveTimer2; //軟件定時器2
void pxSoftWaveTimer(TimerHandle_t xTimer); //軟件定時器回調(diào)函數(shù)
SoftWaveTimer1 = xTimerCreate(
"softwaveTimer1",
1000,
pdTRUE,
(void*)1,
pxSoftWaveTimer);
SoftWaveTimer2 = xTimerCreate(
"softwaveTimer2", //定時器句柄
3000, //定時器周期
pdTRUE, //周期/單次定時器
(void*)2, //定時器ID
pxSoftWaveTimer); //回調(diào)函數(shù)指針
2、定時器回調(diào)函數(shù)
void pxSoftWaveTimer(TimerHandle_t xTimer)
{
u32 TimerID;
u8 *TimerName;
TimerID = (u32)pvTimerGetTimerID(xTimer); //獲取定時器ID
TimerName = (u8*)pcTimerGetName( xTimer ); //獲取定時名字
if(TimerID == 1)
{
printf("軟件定時器%s運行,1S周期\\r\\n",TimerName);
}
if(TimerID == 2)
{
printf("軟件定時器%s運行,2S周期\\r\\n",TimerName);
}
}
3、啟動、關閉定時器
//task1任務函數(shù)
void task1_task(void *pvParameters) //prio = 2
{
u8 keyVal = 0;
while(1)
{
keyVal = KEY_Scan(0);
if(keyVal == KEY0_PRES) //啟動定時器
{
xTimerStart(SoftWaveTimer1,0);
xTimerStart(SoftWaveTimer2,0);
}
if(keyVal == KEY1_PRES) //關閉定時器
{
xTimerStop(SoftWaveTimer1,0);
xTimerStop(SoftWaveTimer2,0);
}
LED1 ^= 1;
vTaskDelay(200); //延時n個時鐘節(jié)拍
}
}
-
內(nèi)核
+關注
關注
3文章
1372瀏覽量
40290 -
定時器
+關注
關注
23文章
3248瀏覽量
114800 -
FreeRTOS
+關注
關注
12文章
484瀏覽量
62178
發(fā)布評論請先 登錄
相關推薦
評論