ESP32 學習筆記(十九)High Resolution Timer
文章目錄
高解析度定時器
概述
雖然 FreeRTOS 提供軟體定時器,但這些定時器有一些限制:
- 最大解析度等於 RTOS 滴答週期
- 低優先順序任務排程定時器回撥
硬體定時器沒有這兩個限制,但通常使用起來不方便。例如,應用程式元件可能需要在將來的某些時間觸發定時器事件,但硬體定時器僅包含一個用於中斷生成的“比較”值。這意味著需要在硬體計時器之上構建一些設施來管理待處理事件列表,可以在發生相應的硬體中斷時為這些事件排程回撥。
esp_timer
API 集提供了這樣的功能。在內部,esp_timer
使用 32 位硬體定時器(FRC1,“傳統”定時器)。esp_timer
提供單次和週期定時器,微秒時間解析度和 64 位範圍。
從高優先順序的 esp_timer
任務排程定時器回撥。由於所有回撥都是從同一任務排程的,因此建議僅從回撥本身執行儘可能少的工作,而是使用佇列將事件釋出到優先順序較低的任務。
如果優先順序高於 esp_timer
的其他任務正在執行,則回撥排程將延遲,直到 esp_timer
任務有機會執行。例如,如果正在進行 SPI
快閃記憶體操作,則會發生這種情況。
建立和啟動計時器,並排程回撥需要一些時間。因此,單觸發 esp_timer
esp_timer_start_once()
時超時值小於20us,則僅在大約 20us 後排程回撥。
週期性 esp_timer
還對最小定時器週期施加 50us 限制。週期小於 50us 的定期軟體定時器不實用,因為它們會佔用大部分 CPU 時間。如果發現需要小週期的定時器,請考慮使用專用硬體外設或 DMA 功能。
使用 esp_timer
API
單個計時器由 esp_timer_handle_t
型別表示。定時器有與之關聯的回撥函式。每次計時器過去時,都會從 esp_timer
任務呼叫此回撥函式。
- 要建立計時器,請呼叫
esp_timer_create()
- 要在不再需要時刪除計時器,請呼叫
esp_timer_delete()
。
定時器可以以單次模式或定期模式啟動。
- 要以單次模式啟動計時器,請呼叫
esp_timer_start_once()
,傳遞應該呼叫回撥的時間間隔。呼叫回撥時,會認為計時器已停止。 - 要以週期模式啟動定時器,請呼叫
esp_timer_start_periodic()
,傳遞應呼叫回撥的週期。計時器一直執行,直到呼叫esp_timer_stop()
。
請注意,呼叫 esp_timer_start_once()
或 esp_timer_start_periodic()
時,計時器不能執行。要重新啟動正在執行的計時器,請先呼叫 esp_timer_stop()
,然後呼叫其中一個啟動函式。
獲得當前時間
esp_timer
還提供了一個便捷函式來獲取自啟動以來經過的時間,精度為微秒:esp_timer_get_time()
。此函式返回自 esp_timer
初始化以來的微秒數,這通常在呼叫 app_main
函式之前不久發生。
與 gettimeofday
函式不同,esp_timer_get_time()
返回的值:
- 晶片從深度睡眠中喚醒後,從零開始
- 沒有應用時區或 DST 調整