• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 博客專欄

    EEPW首頁 > 博客 > 老宇哥帶你玩轉 ESP32:08 硬件定時器

    老宇哥帶你玩轉 ESP32:08 硬件定時器

    發布人:芯片之大家 時間:2023-07-04 來源:工程師 發布文章

    今天我們來玩兒硬件定時器

    硬件定時器概述

    ESP32內置4個64-bit的通用定時器,每個定時器包含一個 16-bit 預分頻器和一個 64-bit 可自動重新加載向上/向下計數器,定時器是分為兩組的,每組兩個。

    定時器有以下特性:

    • 16-bit 時鐘預分頻器,分頻系數為 2-65536

    • 64-bit 時基計數器

    • 可配置的向上/向下時基計數器:增加或減少

    • 暫停和恢復時基計數器

    • 報警時自動重新加載

    • 當報警值溢出/低于保護值時報警

    • 軟件控制的即時重新加載

    • 電平觸發中斷和邊沿觸發中斷

    每個定時器以APB_CLK(80MHz)作為基礎時鐘,通過預分頻器(16-bit)進行分頻后,產生最終的時鐘信號,每過一個周期,計數器會向上加一或者向下減一,計數器支持自動重新加載和軟件即時重新加載,計數器達到軟件設定值時會觸發報警事件。

    使用定時器,可以按照一定的頻率自動的重復執行我們需要的任務,本示例我們簡單演示一個LED燈在定時器的控制下閃爍的案例。

    硬件

    SDA硬件連接很簡單,這里接到IO4

    image.png


    軟件

    初始化定時器

    定時器使用前需要初始化,第一個參數為使用哪個定時器,這里有4個定時器,所以參數可為0,1,2,3;第二個參數為預分頻數,定時器時鐘為80MHz,如果我們這里設置為80,那么每個計數周期就是1us;第三個參數為是否向上計數,true為向上,反之亦然。

    hw_timer_t * timerBegin(uint8_t timer, uint16_t divider, bool countUp);

    設置定時器中斷回調函數

    第一個參數為使用哪個定時器;第二個參數為定時器超時,中斷的回調函數;第三個參數,如果為true,則報警產生邊緣類型中斷。

    void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge);

    設置定時器的定時值

    第一個參數為使用哪個定時器;第二個參數為定時器的定時值,如果為1000000,每個計數周期為1us,定時時間就是1秒;第三個參數為是否自動重載,選擇true,在定時時間到達后會重復計時。

    void timerAlarmWrite(hw_timer_t *timer, uint64_t interruptAt, bool autoreload);

    啟動定時器

    啟動定時器后,將開始計時。

    bool timerAlarmEnabled(hw_timer_t *timer);

    定時器還有其它函數,都在庫文件中,大家可以在下面兩個文件中找到相關源碼。

    esp32-hal-timer.h
    esp32-hal-timer.c

    完整程序

    這里我們用一個例子來演示一下,定時器計時周期設置為1秒,在中斷函數中控制指示燈以1秒為周期閃爍。

    #define LED_GPIO 4/* 創建硬件定時器 */hw_timer_t * timer = NULL;/* LED 狀態 */byte led_state = LOW; 
    void IRAM_ATTR Timer0_Interrupt(){
      led_state = !led_state;
      digitalWrite(LED_GPIO, led_state);
    } 
    void setup() {
      Serial.begin(115200);
      pinMode(LED_GPIO, OUTPUT); 
      /* 使用定時器0,1/(80MHZ/80) = 1us ,周期為1us */
      timer = timerBegin(0, 80, true); 
      /* 中斷回調函數為Timer0_Interrupt */
      timerAttachInterrupt(timer, &Timer0_Interrupt, true); 
      /* 計數Count為1000000,也就是1秒中斷一次,重復計數 */
      timerAlarmWrite(timer, 1000000, true); 
      /* 啟動定時器*/
      timerAlarmEnable(timer);
      Serial.println("timer0 start");
    } 
    void loop() {
     
    }

    實驗效果:


    示波器觀察:

    image.png


    定時器使用比較簡單,當然,在一些不是特別精準的場合,使用一個硬件定時器,我們也可以創建軟件定時器,這樣就可以定義很多個不同的定時任務了,這個后面遇到案例了我們再展開討論。

    感謝大家,關于ESP32的學習,希望大家Enjoy!


    *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。



    關鍵詞: 硬件

    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 康乐县| 凤翔县| 胶州市| 广昌县| 安溪县| 景谷| 威信县| 澄迈县| 公主岭市| 泾源县| 东乌珠穆沁旗| 屏山县| 江西省| 应城市| 新沂市| 武义县| 永善县| 萍乡市| 大荔县| 登封市| 鄯善县| 四平市| 永兴县| 山丹县| 白城市| 于田县| 成安县| 新建县| 汾阳市| 如皋市| 安泽县| 安龙县| 衡山县| 合水县| 寻乌县| 长汀县| 潮州市| 富民县| 射洪县| 三亚市| 永善县|