ESP32 Timer Interrupt – Ngắt ESP32 là gì?

Khi sử dụng ESP32, bạn nên biết đến khái niệm ESP32 Timer Interrupt – tính năng giúp thực hiện tác vụ nào đó theo đúng thời gian. Bạn có thể hình dung nó như một loại ngắt – một chiếc đồng hồ giúp đo lường và kiểm soát các sự kiện thời gian, thông qua việc cung cấp độ trễ chính xác.

Đa số các bộ vi điều khiển hiện nay đều có sẵn có bộ hẹn giờ, chúng không chỉ dùng để tạo ra độ trễ thời gian mà còn giúp tạo ra một bộ đếm, phù hợp sử dụng trong nhiều ứng dụng.

Ngắt ESP32 Timer Interrupt là gì?

Ngắt hẹn giờ là cách hiệu quả để đảm bảo các sự kiện diễn ra chính xác tại thời điểm quy định đến từng mili giây, cho phép bạn tinh chỉnh các hoạt động của xung nhịp trên mạch.

Ngắt hẹn giờ trong ESP32 cho phép chúng ta thực hiện tác vụ trong các khoảng thời gian cụ thể, bất kỳ code của bạn đang xảy ra chuyện gì. Chúng tương tự như các ngắt bên ngoài, nhưng thay vì kích hoạt bởi sự kiện bên ngoài thì chúng được kích hoạt bằng bộ đếm thời gian.

ESP32 Timer Interrupt hoạt động dựa trên phần cứng, nên tất cả thời gian đều phụ thuộc vào đồng hồ của bộ hẹn giờ. Bạn có thể tính tốc độ hẹn giờ theo công thức sau:

tốc độ hẹn giờ (Hz) = Tốc độ xung nhịp hẹn giờ (Mhz) / bộ đếm gộp trước (prescaler)

Ví dụ: Khi ESP32 đang chạy ở tốc độ xung nhịp 80MHz thì tốc độ hẹn giờ như sau:

  • Tốc độ của bộ hẹn giờ sẽ là 80 MHz hoặc 8000000 MHz đối với giá trị bộ đếm gộp trước là 1. (Tốc độ = 80/1 = 80)
  • Tốc độ hẹn giờ ESP32 là 1MHz hoặc 1000000Hz khi giá trị bộ đếm gộp trước là 80 (Tốc độ = 80/80 = 1)

Trong khái niệm ngắt ESP32, prescaler là tần số được chia để tạo thành một “tích tắc” trong bộ đếm thời gian.

Ví dụ về ngắt ESP32 – Nhấp nháy đèn LED

Mình sẽ dùng dự án nhấp nháy đèn LED để minh họa cho ví dụ ESP32 Timer Interrupt này, chứ không sử dụng độ trễ như trước đây nữa.

Trước tiên, bạn kết nối ESP32 với đèn LED như hình:

Ví dụ về ESP32 Timer Interrupt - Nhấp nháy đèn LED

Bạn hãy kết nối Anode của đèn LED với chân GPIO 21 và kết nối cực âm với chân GND, thông qua điện trở 220 Ohms.

Code mẫu

Dưới đây là đoạn code mẫu:

#define LED 21
hw_timer_t *My_timer = NULL;
void IRAM_ATTR onTimer(){
digitalWrite(LED, !digitalRead(LED));
}
void setup() {
pinMode(LED, OUTPUT);
My_timer = timerBegin(0, 80, true);
timerAttachInterrupt(My_timer, &onTimer, true);
timerAlarmWrite(My_timer, 1000000, true);
timerAlarmEnable(My_timer); //Just Enable
}
void loop() {
}

Giải thích chương trình

Khai báo LED được kết nối với chân GPIO 21, tạo biến con trỏ có tên My_timer thuộc loại hw_timer_t để cấu hình bộ hẹn giờ ESP32 Timer Interrupt:

#define LED 21 
hw_timer_t *My_timer = NULL;

Tạo ISR để ngắt ESP32 bằng hẹn giờ. Trong ISR có sẵn một hàm để đảo ngược trạng thái của GPIO 21, chúng sẽ được thực thi khi xảy ra tình trạng ngắt ESP32:

void IRAM_ATTR onTimer(){
digitalWrite(LED, !digitalRead(LED));
}

Khởi tạo GPIO 21 thành đầu ra để điều khiển:

void setup() {
pinMode(LED, OUTPUT)
My_timer = timerBegin(0, 80, true);
timerAttachInterrupt(My_timer, &onTimer, true);
timerAlarmWrite(My_timer, 1000000, true);
timerAlarmEnable(My_timer);
}
void loop() {
}

Sử dụng hàm hẹn giờ, bắt đầu với 3 thông số sau:

  • Số đầu tiên: Bộ định thời mà chúng ta đang muốn dùng (có giá trị từ 0 đến 3, vì ESP32 chỉ có 4 bộ định thời gian)
  • Số thứ hai: Giá trị của bộ đếm gộp trước
  • Số cuối cùng: Giá trị này cho biết bộ đếm nên đếm tăng lên (true) hay giảm xuống (false).

Trong đoạn code này, IoTZone sử dụng bộ đếm thời gian số 0, bộ đếm gộp trước là 80 và cho phép hệ thống đếm tăng lên:

My_timer = timerBegin(0, 80, true);

Trước khi kích hoạt ESP32 Timer Interrupt, chúng ta gắn nó vào ISR – hành vi được thực thi khi quá trình ngắt diễn ra. Trong code này, chúng ta gắn hàm ISR có tên onTimer vào bộ ngắt:

timerAttachInterrupt(My_timer, &onTimer, true);

Bộ hẹn giờ AlarmWrite được dùng để chỉ định giá trị bộ đếm để tạo ra bộ hẹn giờ. Trong ví dụ mẫu này, chúng ta sẽ tạo ra ngắt mỗi giây, nên chúng ta dùng giá trị 1000000 micro giây (tương đương 1 giây). Đối với số thứ ba, chúng ta chuyển giả trị true, và bộ đếm sẽ tải lại từ đầu, tạo ra một vòng lặp ngắt định kỳ liên tục:

timerAlarmWrite(My_timer, 1000000, true);

Cuối cùng, chúng ta kích hoạt bộ ngắt của ESP32 bằng cách sử dụng chức năng hẹn giờ:

timerAlarmEnable(My_timer);

Lời kết

Trên đây là hướng dẫn chi tiết với ESP32 Timer Interrupt kèm theo code mẫu, chúc các bạn thực hiện thành công!

IoTZone – Chuyên cung cấp thiết bị điện tử & tài liệu cho Makers

Trả lời

Email của bạn sẽ không được hiển thị công khai. Các trường bắt buộc được đánh dấu *