Bài viết 5 thuộc series STM32F103C8T6 tập trung theo hướng “học để làm được việc”. Với chủ đề Ngắt ngoài EXTI trên STM32F103C8T6, bạn sẽ đi từ lý thuyết cốt lõi đến quy trình triển khai thực tế trong phòng lab. Nội dung được thiết kế để sinh viên, kỹ thuật viên bảo trì và người mới chuyển từ PLC sang Embedded đều có thể áp dụng ngay vào project mẫu.
Ngắt ngoài giúp hệ thống phản ứng theo sự kiện thay vì liên tục polling, từ đó tiết kiệm CPU và cải thiện độ đáp ứng. Tuy nhiên thiết kế ISR không đúng sẽ gây treo hoặc mất sự kiện.
1. Mục tiêu bài học
Bài tập trung vào luồng EXTI -> NVIC -> callback ứng dụng, đồng thời hướng dẫn chống dội để tín hiệu nút nhấn ngoài đời thực không phá logic chương trình.
- Hiểu mapping EXTI line và cấu hình trigger cạnh lên/xuống.
- Nắm cơ chế ưu tiên NVIC khi hệ thống có nhiều nguồn ngắt.
- Triển khai chống dội phím trong mô hình interrupt.
- Tạo kiến trúc event flag để xử lý ổn định ở main loop.
Sau khi hoàn thành, bạn nên tự trả lời được ba câu hỏi: hệ thống cần đo/điều khiển đại lượng gì, vòng đời xử lý dữ liệu chạy theo chu kỳ nào, và cơ chế bảo vệ lỗi nào cần có để hệ thống ổn định khi chạy liên tục ngoài hiện trường.
2. Kiến thức nền tảng
STM32F103C8T6 dùng lõi ARM Cortex-M3, phù hợp để học đồng thời kiến trúc MCU và phương pháp lập trình thời gian thực. Khi học theo lộ trình chuẩn, bạn nên nắm đồng thời phần cứng (clock, GPIO, bus, nguồn), firmware (HAL/LL, ngắt, timer), và phương pháp test (scope, logic analyzer, UART log). Việc kết hợp đủ ba lớp kiến thức giúp quá trình debug nhanh hơn nhiều so với chỉ học code thuần.
- Khái niệm latency, jitter và ảnh hưởng của ISR dài.
- Sự khác biệt giữa polling, interrupt và DMA.
- Cơ chế pending flag trong EXTI/NVIC.
- Nguyên tắc bảo vệ biến chia sẻ giữa ISR và main.
Trong quá trình thực hành, bạn nên duy trì checklist kiểm thử ở từng vòng: xác nhận wiring, xác nhận xung clock, xác nhận trạng thái ngoại vi, sau đó mới kiểm tra thuật toán. Cách làm này giảm đáng kể lỗi dây chuyền và giúp nhóm dự án phối hợp hiệu quả giữa phần cứng và phần mềm.
3. Phân tích kỹ thuật
Ánh xạ EXTI line và trigger
Mỗi line EXTI có thể ánh xạ từ nhiều port nhưng chỉ một nguồn tại một thời điểm. Cần xác định rõ chân tín hiệu và chọn trigger phù hợp (rising/falling/both) theo đặc tính phần cứng để giảm nhiễu giả.
- Nút pull-up thường bắt cạnh xuống khi nhấn.
- Cảm biến open-collector cần kiểm tra mức idle trước khi set trigger.
- Kiểm soát nhiễu dây dài bằng RC hoặc Schmitt trigger ngoài nếu cần.
NVIC priority và xung đột nhiều ngắt
Khi hệ thống đồng thời có UART, timer và EXTI, thứ tự ưu tiên ngắt sẽ quyết định tính ổn định. Nếu cấu hình không hợp lý, tác vụ quan trọng có thể bị trễ hoặc mất dữ liệu.
- Đặt ngắt thời gian cứng ở ưu tiên cao hơn giao diện người dùng.
- Không gọi hàm blocking trong callback EXTI.
- Dùng cờ sự kiện để main xử lý nghiệp vụ.
Chiến lược debounce trong ngắt
Debounce bằng cách khóa ngắt tạm thời hoặc xác nhận lại trạng thái sau một khoảng timer ngắn. Phương pháp kết hợp EXTI + timer mềm thường cho kết quả tốt trong hệ thống có nhiều nút.
- Đánh dấu thời điểm ngắt bằng tick counter.
- Bỏ qua sự kiện nếu khoảng cách thời gian quá ngắn.
- Xác nhận lại mức chân trước khi tạo event chính thức.
Từ góc nhìn hệ thống, chủ đề này không chỉ là “chạy được chức năng”, mà còn là bài toán tối ưu độ tin cậy, độ trễ xử lý, khả năng mở rộng khi thêm cảm biến hoặc thêm kênh truyền thông. Nếu ngay từ đầu bạn chuẩn hóa cấu trúc code theo module driver/app/service thì giai đoạn mở rộng về sau sẽ nhẹ hơn rất nhiều.
4. Các bước thực hiện
Mục tiêu quan trọng nhất là giữ ISR cực ngắn và an toàn; mọi xử lý dài phải chuyển về luồng nền.
- Chọn chân GPIO hỗ trợ EXTI và cấu hình mode input phù hợp.
- Set trigger cạnh, enable line và clear pending flag ban đầu.
- Cấu hình NVIC priority theo vai trò hệ thống.
- Trong callback chỉ set event flag + timestamp.
- Xử lý logic chính trong main loop hoặc task nền.
- Test bằng cách nhấn nhanh/chậm để đánh giá debounce.
Ở mỗi bước, bạn nên lưu log kỹ thuật (ảnh wiring, ảnh cấu hình CubeMX, thông số timer/UART/ADC, snapshot kết quả đo). Bộ log này giúp giảng viên hoặc trưởng nhóm đánh giá tiến độ nhanh và giảm thời gian trao đổi khi cần hỗ trợ từ xa.
5. Ví dụ EXTI callback với chống dội theo thời gian
Code dưới đây là mẫu rút gọn theo HAL Library, tập trung phần cốt lõi để bạn nhìn rõ luồng xử lý. Khi đưa vào dự án thực, hãy tách code thành các module rõ ràng, thêm kiểm tra lỗi trả về và timeout cho mọi giao tiếp ngoại vi.
volatile uint32_t btn_tick = 0;
volatile uint8_t btn_event = 0;
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
if (GPIO_Pin == GPIO_PIN_0) {
uint32_t now = HAL_GetTick();
if ((now - btn_tick) > 40) {
btn_tick = now;
btn_event = 1;
}
}
}
Nguyên tắc quan trọng: giữ hàm ngắt ngắn gọn, xử lý nặng chuyển về vòng lặp chính hoặc task nền; dùng biến trạng thái rõ ràng để tránh race condition; thêm timeout cho mọi thao tác có thể block. Đây là nền tảng để firmware ổn định khi chạy lâu dài.
6. Lỗi thường gặp
Phần lớn lỗi trong STM32F103C8T6 đến từ cấu hình chưa đồng bộ giữa clock, ngoại vi và wiring thực tế. Nếu bạn xử lý theo thứ tự “đọc triệu chứng -> khoanh vùng lớp lỗi -> test độc lập từng khối”, thời gian debug sẽ giảm rất rõ.
- Đặt xử lý nặng trong callback gây trễ toàn hệ thống.
- Không clear hoặc không xử lý pending flag đúng cách.
- Ưu tiên ngắt lộn xộn khiến timer/UART mất ổn định.
- Debounce không đủ nên sự kiện bị nhân đôi.
- Không khai báo volatile cho biến chia sẻ ISR-main.
Hãy xem ISR như “cổng báo sự kiện”, không phải nơi xử lý nghiệp vụ.
7. Bài tập thực hành
Để chuyển từ mức “hiểu lý thuyết” sang “làm chủ kỹ năng”, bạn nên làm các bài tập sau theo đúng thứ tự từ dễ đến khó, sau mỗi bài đều ghi lại tiêu chí đạt/chưa đạt và thông số đo thực tế.
- Viết module event queue nhận sự kiện từ EXTI cho 3 nút nhấn.
- So sánh 2 chiến lược debounce: theo tick và theo timer xác nhận lại.
- Mô phỏng xung nhiễu và đánh giá tỷ lệ false trigger.
- Tích hợp EXTI với UART log để ghi timeline sự kiện.
Khuyến nghị chấm bài theo rubric: đúng chức năng (40%), độ ổn định 30 phút chạy liên tục (30%), chất lượng cấu trúc code (20%), tài liệu kỹ thuật và báo cáo đo kiểm (10%).
Tài liệu tham khảo
- STMicroelectronics, STM32F103x8/B Datasheet.
- STMicroelectronics, RM0008 Reference Manual: STM32F10xxx advanced ARM-based 32-bit MCUs.
- STMicroelectronics, UM1850 STM32CubeMX user manual và tài liệu STM32Cube liên quan.
- ARM, Cortex-M3 Technical Reference Manual.
- STMicroelectronics Application Notes về GPIO, ADC, Timer, UART, I2C, SPI, DMA và Watchdog.