ESP32高分辨率計時器筆記


盡管FreeRTOS提供了軟件計時器,但這些計時器有一些限制:

  • 最大分辨率等於RTOS滴答周期

  • 計時器回調從低優先級任務分派

硬件計時器不受這兩個限制,但是通常它們使用起來不太方便。例如,應用組件可能需要定時器事件在將來的特定時間觸發,但是硬件定時器僅包含一個用於中斷產生的“比較”值。這意味着需要在硬件計時器之上構建一些功能來管理掛起事件列表,以便在發生相應的硬件中斷時可以調度這些事件的回調。

esp_timer 一組API提供了一次性的計時器和定期的計時器,微秒級的時間分辨率以及64位范圍。

 

基於ESP-IDF4.1

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <unistd.h>
 4 #include "esp_timer.h"
 5 #include "esp_log.h"
 6 #include "esp_sleep.h"
 7 #include "sdkconfig.h"
 8 
 9 static void periodic_timer_callback(void* arg);
10 static void oneshot_timer_callback(void* arg);
11 
12 static const char* TAG = "example";
13 
14 void app_main(void)
15 {
16     /* 
17      * 創建兩個計時器:
18      * 1.每0.5秒運行的一個周期性計時器,並且打印消息
19      * 2.五秒后執行的一次性計時器,並且每1秒重啟計時器
20      */
21 
22     //創建周期性計時器
23     const esp_timer_create_args_t periodic_timer_args = {
24             .callback = &periodic_timer_callback,
25             //自定義名稱
26             .name = "periodic"
27     };
28 
29     esp_timer_handle_t periodic_timer;
30     ESP_ERROR_CHECK(esp_timer_create(&periodic_timer_args, &periodic_timer));
31 
32     //創建一次性計時器
33     const esp_timer_create_args_t oneshot_timer_args = {
34             .callback = &oneshot_timer_callback,
35             //指定的參數將會傳給計時器回調函數
36             .arg = (void*) periodic_timer,
37             .name = "one-shot"
38     };
39     esp_timer_handle_t oneshot_timer;
40     ESP_ERROR_CHECK(esp_timer_create(&oneshot_timer_args, &oneshot_timer));
41 
42     //啟動計時器
43     ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer, 500000));
44     ESP_ERROR_CHECK(esp_timer_start_once(oneshot_timer, 5000000));
45     ESP_LOGI(TAG, "Started timers, time since boot: %lld us", esp_timer_get_time());
46 
47     // 每2秒打印計時器調試信息到控制台
48     for (int i = 0; i < 5; ++i) {
49         ESP_ERROR_CHECK(esp_timer_dump(stdout));
50         usleep(2000000);
51     }
52 
53 
54     //輕度睡眠中,時間繼續保持。輕度睡眠后計時器正確執行
55     ESP_LOGI(TAG, "Entering light sleep for 0.5s, time since boot: %lld us",esp_timer_get_time());
56     ESP_ERROR_CHECK(esp_sleep_enable_timer_wakeup(500000));
57     esp_light_sleep_start();
58     ESP_LOGI(TAG, "Woke up from light sleep, time since boot: %lld us", esp_timer_get_time());
59 
60     //讓計時器再運行一會
61     usleep(2000000);
62 
63     //停止和清除計時器
64     ESP_ERROR_CHECK(esp_timer_stop(periodic_timer));
65     ESP_ERROR_CHECK(esp_timer_delete(periodic_timer));
66     ESP_ERROR_CHECK(esp_timer_delete(oneshot_timer));
67     ESP_LOGI(TAG, "Stopped and deleted timers");
68 }
69 
70 //周期性計時器回調函數
71 static void periodic_timer_callback(void* arg)
72 {
73     int64_t time_since_boot = esp_timer_get_time();
74     ESP_LOGI(TAG, "Periodic timer called, time since boot: %lld us", time_since_boot);
75 }
76 
77 //一次性計時器回調函數
78 static void oneshot_timer_callback(void* arg)
79 {
80     int64_t time_since_boot = esp_timer_get_time();
81     ESP_LOGI(TAG, "One-shot timer called, time since boot: %lld us", time_since_boot);
82     esp_timer_handle_t periodic_timer_handle = (esp_timer_handle_t) arg;
83     //啟動運行的計時器,首先需要先停止它
84     ESP_ERROR_CHECK(esp_timer_stop(periodic_timer_handle));
85     ESP_ERROR_CHECK(esp_timer_start_periodic(periodic_timer_handle, 1000000));
86     time_since_boot = esp_timer_get_time();
87     ESP_LOGI(TAG, "Restarted periodic timer with 1s period, time since boot: %lld us",time_since_boot);
88 }

 

原文:https://gitee.com/EspressifSystems/esp-idf/tree/master/examples/system/esp_timer


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM