Hãy tưởng tượng MCU chính là bạn, Sau khi khởi tạo các công việc hàng ngày như Thức dậy, ăn sáng, vệ sinh cá nhân …. Đó là các hàm được viết sau main().
Bạn đi đến công ty và làm việc các công việc trong while(1) cứ như vậy lặp đi lặp lại. Quá trình này trong lập trình gọi là Polling, việc nào đến trước làm trước, đến sau làm sau và không có sự ưu tiên việc nào làm trước.
Trong quá trình làm việc bỗng bạn nhận được nhiệm vụ từ xếp đó là “Đi gặp khách hàng”, công việc này phải ưu tiên hoàn thành trước, sau khi làm xong mới bắt đầu làm tiếp công việc thường này.
Sự kiện này trong lập trình gọi là Ngắt ( Interrupts)
Trong lập trình hiện nay, hiếm có chương trình nào ko sử dụng ngắt, vì có các dữ liệu phải được xử lý tức thì nếu không sẽ dẫn đến sai hoặc mất dữ liệu.
Các ngắt đều có 1 trị số priority ( Sự ưu tiên) cho phép người lập trình có thể ưu tiên xử lý ngắt nào trước nếu sảy ra ngắt chồng nhau.
Lấy ví dụ: Trong khi bạn đang gặp khách hàng lại được tin “ vợ đẻ “, nếu sự kiện “vợ đẻ” có priority cao hơn “Đi gặp khách hàng” thì chắc chắn bạn sẽ đi đón vợ đẻ trước, sau đó mới đi gặp khách hàng. Và chắc chắn việc gặp khách hàng sẽ chậm hơn 1 chút.
Trong STM32 việc quản lý các ngắt đó được điều khiển bằng bộ NVIC tạm dịch là bộ điều khiển ngắt lồng nhau.
Thông số của NVIC như sau:
Các vector ngắt được trình bày trong phần 10.1.2 reference manual
EXTI (External Interupts) tạm dịch là ngắt ngoài hay ngắt sự kiện bên ngoài. Ngắt EXTI được kích hoạt khi có sự kiện từ bên ngoài tác động vào chân EXTI đó, tùy theo sự kiện đó có phù hợp với điều kiện ngắt không thì ngắt ngoài mới sảy ra.
Ngắt ngoài STM32 được mô tả như sau:
Các tham số (Main Features):
Các bạn tham khảo thêm 10.2.1 và 10.2.2 phần Block diagram
Các Line ngắt ngoài được tổ chức như sau:
Các chân PA0,PB0,…,PG0 sẽ chung là line EXTI0, Tiếp tục như vậy đến EXTI15 chúng ta có 16 ngắt.
4 ngắt ngoài đặc biệt đó là:
Trong bài này chúng ta sẽ cấu hình 3 nút nhấn gồm các chân PA0, PB3, PA1 sau đó phân biệt các sự kiện đó trong ngắt rồi điều khiển led.
PA0 Led sáng
PA1 Led tắt
PB3 Led nhấp nháy
Oke các bạn mở CubeMX lên chọn chip STM32f103c8 và tạo project
Nếu các bạn chưa biết tạo thì vui lòng đọc Bài 3 nhé
Trong SYS chọn Debug: Serial Wire , RCC giữ nguyên nhé.
Trong GPIO chọn các chân PA0,PA1,PB3 là GPIO_EXTI
Trong mục Configuration có các lựa chọn sau:
GPIO mode:
Trong bài này chúng ta sẽ chọn chế độ ngắt phát hiện xung xuống.
External Interrupt Mode Falling edge
GPIO Pull: Có dùng trở kéo lên hoặc xuống không. Ta chọn trở kéo lên Pull UP
User Label ko cần sử dụng
Trong Tab Nvic Tick vào các ô Enable để bật ngắt đó lên
Chọn PC13 là Output. Sau đó chuyển Tab project manager đặt tên và Gen code
Trong Keil C các bạn nhấn F7 để IDE Build chương trình mới tạo ra
Vào File Stm32F1xx_it.c sẽ thấy 3 chương trình phục vụ ngắt được sinh ra đó là:
EXT0_IRQHanler, EXT1_IRQHanler , EXT2_IRQHanler
Các bạn nhấn Chuột phải vào tên và Define tới nơi viết chương trình phục vụ ngắt đó.
Trong hàm phục vụ ngắt sẽ có 1 câu lênh kiểm tra cờ ngắt tại tham số là GPIO_Pin truyền vào.
Nếu sảy ra ngắt sẽ xóa cờ ngắt để sẵn sàng cho ngắt tiếp theo xảy ra
Sau đó gọi tới hàm Callback
Các bạn chuyên qua Tab Functions chọn file stm32f1xx_hal_gpio.c Tìm đến hàm
HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
Copy cả hàm đó và bỏ từ khóa __weak
Paste vào khu tiền xử lý trên hàm main() và code vào trong hàm này như sau
Giải thích: Vì mọi ngắt ngoại tại các Line khác nhau đều gọi tới một hàm xử lý ngắt, chỉ khác tham số truyền vào là PIN nào vậy nên chúng ta so sánh PIN truyền vào với các PIN tương ứng với Line 0, 1, 3 để xác định ngắt xảy ra tại đâu.
Sau đó gọi hàm bật tắt led theo đúng yêu cầu bên trên .
Tiếp đó Build bằng F7 và Nạp code vào mạch bằng F8.
Kết nối nút nhấn vào 3 chân PA0, PA1, PA3, sau đó nhấn nút. Bạn sẽ thấy Led nháy tương ứng với ngắt tại chân đó