Lab 2: Ngắt Timer & Quét LED
Tổng quan
Timer cho phép chúng ta chạy mã ở những khoảng thời gian chính xác mà không bị chặn (blocking). Bài lab này cấu hình một ngắt Timer 2 mỗi 10 ms và dùng nó để quét nhiều màn hình 7 đoạn, xây dựng một đồng hồ số, và tạo một software timer không chặn. Một ma trận LED 8×8 tùy chọn sẽ mở rộng ý tưởng này.
Mục tiêu
- Cấu hình một ngắt Timer 2 kích hoạt mỗi 10 ms.
- Quét (multiplex) nhiều màn hình 7 đoạn sao cho chúng trông như sáng đồng thời.
- Thay thế
HAL_Delaygây chặn bằng một software timer điều khiển bởi ngắt.
Thiết lập timer
Với clock 8 MHz, đặt Prescaler = 7999 và Counter Period = 9:
8 MHz / (7999+1) = 1000 Hz, chia cho 10 → 100 Hz → một ngắt 10 ms. Bật ngắt toàn cục TIM2
(NVIC), khởi động nó bằng HAL_TIM_Base_Start_IT(&htim2), và đặt mã định kỳ của bạn vào callback.
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim) {
if (htim->Instance == TIM2) {
// runs every 10 ms
}
}
Các LED được quét nhanh hơn ~30 Hz sẽ trông như sáng liên tục; trên Proteus dùng tần số thấp (ví dụ 1 Hz) vì trình mô phỏng không thể chạy ở tốc độ tối đa.
Bài tập
- Hiển thị "1" và "2" trên hai LED 7 đoạn, chuyển đổi mỗi 0.5 s.
- Mở rộng lên bốn LED 7 đoạn + hai LED DOT (PA4); nhấp nháy DOT mỗi giây.
- Triển khai
update7SEG(int index)điều khiển bằng một buffer 4 phần tử. - Đặt tần số quét 4 chữ số là 1 Hz; vẫn giữ DOT nhấp nháy.
- Một đồng hồ số (giờ/phút) qua
updateClockBuffer(). - Tạo một software timer (
setTimer0,timer_run,timer0_flag) để loại bỏHAL_Delay. - Viết lại đồng hồ ở Bài 5 dùng software timer; chuyển DOT sang
main. - Chuyển
update7SEG()sangmain; ngắt chỉ phục vụ các software timer. - (Mở rộng) Thêm một ma trận LED 8×8 (MATRIX-8X8-RED + ULN2803); hiển thị ký tự "A".
- Tạo hiệu ứng cho ma trận (ví dụ cuộn ký tự sang trái).
Báo cáo & Nộp bài
Trình bày sơ đồ Proteus và mã nguồn liên quan (callback / main). Với software timer, giải thích
điều gì xảy ra với setTimer0(1), setTimer0(10) và khi thiếu lời gọi khởi tạo ban đầu.