ESP32 - Micropython ESP-IDF 雙線教程 中斷和定時器
- ESP32中斷
- ESP32定時器
- 歸納
- ESP32 - Micropython 定時器
- 示例代碼
- 代碼介紹
- ESP32 - IDF 定時器
- 示例代碼
- 代碼解釋
- ESP32-IDF定時器使用介紹
ESP32中的中斷和定時器是兩種重要的硬件特性,它們在嵌入式系統開發中扮演著關鍵角色。以下是關于ESP32中斷和定時器的詳細介紹:
本文無中斷實例代碼,中斷代碼可以在按鍵部分查找
ESP32中斷
1. 中斷概述
中斷是一種硬件機制,用于處理在程序正常執行期間不發生但在特定觸發發生時的事件。ESP32的每個內核最多提供32個中斷槽,用于響應各種外部和內部事件。
2. 中斷類型
- 硬件中斷:響應外部硬件事件,如GPIO中斷(如按鍵按下時)或觸摸中斷(檢測到觸摸時)。
- 軟件中斷:響應軟件指令,如定時器中斷(當定時器超時時)或看門狗定時器中斷。
3. ESP32 GPIO中斷
- 功能:ESP32板上的所有GPIO引腳都可以配置為充當中斷請求輸入。
- 配置:使用
attachInterrupt()
函數將中斷附加到GPIO引腳。該函數接受三個參數:GPIO引腳號、中斷服務例程(ISR)函數名和觸發模式。 - ISR(中斷服務例程):每次GPIO引腳上發生中斷時調用的函數。ISR應該盡可能簡短且快速,因為它們會阻止正常的程序執行。
ESP32定時器
1. 定時器概述
ESP32內置4個64位通用定時器,每個定時器包含一個16位預分頻器和一個64位可自動重新加載的向上/向下計數器。這些定時器可以用于各種時間相關的應用,如事件計時、周期性操作、脈沖寬度調制(PWM)等。
2. 定時器特性
- 16位預分頻器:用于對APB時鐘進行分頻,產生時基計數器時鐘(TB_clk)。
- 64位時基計數器:支持向上/向下計數,并可在報警時自動重新加載。
- 觸發中斷:支持電平觸發和邊沿觸發中斷。
3. 定時器使用
- 初始化:通過配置相關寄存器來初始化定時器,包括設置預分頻器值、計數方向、中斷使能等。
- 設置中斷時間:通過配置定時器的計數器和預分頻器來設定中斷觸發的時間間隔。
- 設置回調函數:當定時器觸發中斷時,可以調用預設的回調函數來執行特定任務。
- 使能定時器:配置完成后,使能定時器以開始計時。
歸納
- 中斷:用于處理外部和內部事件,通過中斷服務例程實現快速響應。ESP32的每個內核支持多達32個中斷,可配置GPIO引腳作為中斷源。
- 定時器:用于計時、計數和生成定時事件。ESP32內置4個64位通用定時器,支持多種觸發方式和中斷機制,適用于各種實時應用。
在ESP32的MicroPython環境中,可以使用machine.Timer
類來實現定時器功能。machine.Timer
類允許你創建一個或多個定時器,這些定時器可以在指定的時間間隔后執行回調函數。以下是一個使用ESP32-MicroPython實現定時器功能的示例代碼和介紹:
ESP32 - Micropython 定時器
示例代碼
from machine import Timer
import time# 定義一個回調函數,當定時器觸發時被調用
def timer_callback(timer):print("Timer triggered!")# 這里可以添加你想要在定時器觸發時執行的代碼# 創建一個定時器對象,并設置其觸發周期和回調函數
# 第一個參數是定時器編號,通常為0或1,但某些平臺可能支持更多
# 第二個參數是觸發周期,單位為毫秒(ms)
# 第三個參數是定時器模式,machine.Timer.PERIODIC表示周期性觸發
# 第四個參數是回調函數
tim = Timer(0) # 假設使用定時器0
tim.init(period=1000, mode=Timer.PERIODIC, callback=timer_callback)# 等待一段時間,以便觀察定時器的觸發情況
print("Waiting for timer to trigger...")
time.sleep(5) # 等待5秒# 停止并刪除定時器
tim.deinit()
print("Timer stopped.")
代碼介紹
-
導入必要的模塊:從
machine
模塊中導入Timer
類,并導入time
模塊以便使用time.sleep()
函數。 -
定義回調函數:創建一個名為
timer_callback
的函數,該函數將在定時器觸發時被調用。在這個示例中,回調函數只是簡單地打印一條消息,但你可以在這里添加任何你想要在定時器觸發時執行的代碼。 -
創建和配置定時器:使用
Timer
類創建一個定時器對象(在這個例子中,我們假設使用定時器0)。然后,使用init()
方法配置定時器的參數。這些參數包括定時器的觸發周期(以毫秒為單位)、定時器模式(在這個例子中,我們使用Timer.PERIODIC
來設置定時器周期性觸發)以及回調函數。 -
等待定時器觸發:為了觀察定時器的觸發情況,我們在主程序中添加了一個簡單的等待循環,使用
time.sleep(5)
讓程序暫停5秒鐘。在這段時間內,你應該能夠看到定時器每隔1秒觸發一次,并打印出"Timer triggered!"的消息。 -
停止和刪除定時器:在等待結束后,我們調用
deinit()
方法來停止并刪除定時器。這將釋放與定時器相關的資源,并停止定時器的觸發。
請注意,具體的定時器編號(在Timer()
構造函數中作為第一個參數傳遞)可能因硬件平臺和MicroPython版本而異。在某些平臺上,可能只能使用特定的定時器編號,或者可能有更多的定時器可用。因此,在實際應用中,請參考使用的開發板和MicroPython版本的文檔來了解可用的定時器編號和限制。
ESP32 - IDF 定時器
示例代碼
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/timer.h"
#include "esp_log.h"#define TIMER_GROUP 0
#define TIMER_IDX 0
#define TIMER_INTERVAL_MS 1000 // 定時器間隔為1秒static const char *TAG = "timer_example";// 定時器回調函數
static void IRAM_ATTR timer_group0_handler(void *arg)
{// 這里可以添加定時器觸發時需要執行的代碼ESP_LOGI(TAG, "Timer handler triggered");
}void app_main(void)
{// 初始化定時器timer_config_t config = {.alarm_en = true,.auto_reload = true,.divider = TIMER_BASE_CLK / 1000, // 計數器時鐘分頻系數.counter_dir = TIMER_COUNT_UP,.intr_type = TIMER_INTR_LEVEL,.intr_enable = true,};// 配置定時器timer_init(TIMER_GROUP, TIMER_IDX, &config);// 設置定時器超時時間timer_set_counter_value(TIMER_GROUP, TIMER_IDX, 0x00000000ULL);timer_set_alarm_value(TIMER_GROUP, TIMER_IDX, TIMER_INTERVAL_MS * config.divider);// 安裝定時器中斷服務例程timer_isr_register(TIMER_GROUP, &timer_group0_handler, NULL, ESP_INTR_FLAG_IRAM, NULL);// 啟動定時器timer_start(TIMER_GROUP, TIMER_IDX);// 主循環,在這里可以添加其他任務while (1) {// ...vTaskDelay(pdMS_TO_TICKS(1000)); // 延時1秒,保持主循環運行}
}
代碼解釋
-
頭文件引入:引入了FreeRTOS和ESP-IDF中用于定時器的頭文件。
-
宏定義:定義了定時器組(
TIMER_GROUP
)、定時器索引(TIMER_IDX
)和定時器間隔(TIMER_INTERVAL_MS
)。 -
日志標簽:定義了日志標簽
TAG
,用于在日志輸出中標識此示例。 -
定時器回調函數:定義了
timer_group0_handler
函數,該函數在定時器觸發時被調用。使用IRAM_ATTR
屬性確保該函數位于IRAM中,因為中斷服務例程需要快速響應。 -
app_main函數:這是ESP32應用的主入口函數。
-
定時器初始化:使用
timer_config_t
結構體配置定時器,包括是否啟用鬧鐘、是否自動重載、計數器時鐘分頻系數、計數方向、中斷類型和是否啟用中斷。 -
配置定時器:調用
timer_init
函數來根據配置初始化定時器。 -
設置定時器超時時間:使用
timer_set_counter_value
設置計數器的初始值,使用timer_set_alarm_value
設置鬧鐘值(即定時器觸發的時間)。 -
安裝定時器中斷服務例程:使用
timer_isr_register
函數將中斷服務例程與定時器關聯起來。 -
啟動定時器:調用
timer_start
函數啟動定時器。 -
主循環:使用FreeRTOS的
vTaskDelay
函數保持主循環運行,并可以添加其他任務。
-
ESP32-IDF定時器使用介紹
ESP32-IDF提供了硬件定時器的API,允許配置和使用ESP32的定時器硬件。每個定時器組包含多個定時器,可以配置定時器的各種參數,如分頻系數、計數方向、中斷類型等。
使用ESP32-IDF的定時器,需要:
-
配置定時器:使用
timer_config_t
結構體配置定時器的參數。 -
初始化定時器:調用
timer_init
函數初始化定時器。 -
設置定時器超時時間:使用`timer_set_counter_value