老宇哥帶你玩轉(zhuǎn) ESP32:08 硬件定時器
今天我們來玩兒硬件定時器。
硬件定時器概述ESP32內(nèi)置4個64-bit的通用定時器,每個定時器包含一個 16-bit 預(yù)分頻器和一個 64-bit 可自動重新加載向上/向下計(jì)數(shù)器,定時器是分為兩組的,每組兩個。
定時器有以下特性:
16-bit 時鐘預(yù)分頻器,分頻系數(shù)為 2-65536
64-bit 時基計(jì)數(shù)器
可配置的向上/向下時基計(jì)數(shù)器:增加或減少
暫停和恢復(fù)時基計(jì)數(shù)器
報(bào)警時自動重新加載
當(dāng)報(bào)警值溢出/低于保護(hù)值時報(bào)警
軟件控制的即時重新加載
電平觸發(fā)中斷和邊沿觸發(fā)中斷
每個定時器以APB_CLK(80MHz)作為基礎(chǔ)時鐘,通過預(yù)分頻器(16-bit)進(jìn)行分頻后,產(chǎn)生最終的時鐘信號,每過一個周期,計(jì)數(shù)器會向上加一或者向下減一,計(jì)數(shù)器支持自動重新加載和軟件即時重新加載,計(jì)數(shù)器達(dá)到軟件設(shè)定值時會觸發(fā)報(bào)警事件。
使用定時器,可以按照一定的頻率自動的重復(fù)執(zhí)行我們需要的任務(wù),本示例我們簡單演示一個LED燈在定時器的控制下閃爍的案例。
硬件SDA硬件連接很簡單,這里接到IO4
初始化定時器
定時器使用前需要初始化,第一個參數(shù)為使用哪個定時器,這里有4個定時器,所以參數(shù)可為0,1,2,3;第二個參數(shù)為預(yù)分頻數(shù),定時器時鐘為80MHz,如果我們這里設(shè)置為80,那么每個計(jì)數(shù)周期就是1us;第三個參數(shù)為是否向上計(jì)數(shù),true為向上,反之亦然。
hw_timer_t * timerBegin(uint8_t timer, uint16_t divider, bool countUp);
設(shè)置定時器中斷回調(diào)函數(shù)
第一個參數(shù)為使用哪個定時器;第二個參數(shù)為定時器超時,中斷的回調(diào)函數(shù);第三個參數(shù),如果為true,則報(bào)警產(chǎn)生邊緣類型中斷。
void timerAttachInterrupt(hw_timer_t *timer, void (*fn)(void), bool edge);
設(shè)置定時器的定時值
第一個參數(shù)為使用哪個定時器;第二個參數(shù)為定時器的定時值,如果為1000000,每個計(jì)數(shù)周期為1us,定時時間就是1秒;第三個參數(shù)為是否自動重載,選擇true,在定時時間到達(dá)后會重復(fù)計(jì)時。
void timerAlarmWrite(hw_timer_t *timer, uint64_t interruptAt, bool autoreload);
啟動定時器
啟動定時器后,將開始計(jì)時。
bool timerAlarmEnabled(hw_timer_t *timer);
定時器還有其它函數(shù),都在庫文件中,大家可以在下面兩個文件中找到相關(guān)源碼。
esp32-hal-timer.h
esp32-hal-timer.c
完整程序
這里我們用一個例子來演示一下,定時器計(jì)時周期設(shè)置為1秒,在中斷函數(shù)中控制指示燈以1秒為周期閃爍。
#define LED_GPIO 4/* 創(chuàng)建硬件定時器 */hw_timer_t * timer = NULL;/* LED 狀態(tài) */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); /* 中斷回調(diào)函數(shù)為Timer0_Interrupt */ timerAttachInterrupt(timer, &Timer0_Interrupt, true); /* 計(jì)數(shù)Count為1000000,也就是1秒中斷一次,重復(fù)計(jì)數(shù) */ timerAlarmWrite(timer, 1000000, true); /* 啟動定時器*/ timerAlarmEnable(timer); Serial.println("timer0 start"); } void loop() { }
實(shí)驗(yàn)效果:
示波器觀察:
定時器使用比較簡單,當(dāng)然,在一些不是特別精準(zhǔn)的場合,使用一個硬件定時器,我們也可以創(chuàng)建軟件定時器,這樣就可以定義很多個不同的定時任務(wù)了,這個后面遇到案例了我們再展開討論。
感謝大家,關(guān)于ESP32的學(xué)習(xí),希望大家Enjoy!
*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點(diǎn),如有侵權(quán)請聯(lián)系工作人員刪除。