Bài này chúng ta sẽ nói về lập trình Ngắt ngoài STM32 (EXTI), Ngắt là gì, cách hoạt động của ngắt. Ngắt ngoài là gì, cách lập trình ngắt ngoài STM32
Bài 4 trong Serie Học lập trình STM32 từ A tới Z
Ngắt (Interrupts) là gì?
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.
Bộ điều khiển ngắt lồng nhau NVIC trong STM32
Thông số của NVIC như sau:
- Bao gồm 68 ngắt ( chưa gồm 16 ngắt hệ thống)
- Lập trình 16 mức ưu tiên ngắt (4 bit được sử dụng)
- Độ trễ thấp
- Quản lý năng lượng tiêu hao
Các vector ngắt được trình bày trong phần 10.1.2 reference manual
Ngắt ngoài STM32 EXTI
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):
- Kích hoạt độc lập trên mỗi dòng ngắt (Line Interrupts)
- Truy cập đến từng Bit trong mỗi dòng ngắt
- Tạo ra tối đa 20 sự kiện/ngắt
- Tín hiệu phải có độ rộng xung thấp hơn chu kì xung nhịp của APB2 (vì APB2 cấp xung cho GPIO)
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à:
- EXTI line 16: dùng cho PVD output
- EXTI line 17: dùng cho sự kiện báo thức của bộ RTC
- EXTI line 18: dùng cho sự kiện thức dậy của USB
- EXTI line 19: dùng cho sự kiện thức dậy của ngoại vi Ethernet
Cấu hình Ngắt ngoài STM32 trên CubeMX
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:
- External Interrupt Mode Rising edge: Ngắt ngoài chế độ phát hiện xung lên
- External Interrupt Mode Falling edge: Ngắt ngoài chế độ phát hiện xung xuống
- External Interrupt Mode Rising/Falling: Ngắt cả sườn lên và xuống
- Exteral Event Mode Rising edge: Sự kiện ngoài phát hiện xung lên
- Exteral Event Mode Falling edge: Sự kiện ngoài phát hiện xung xuống
- External Event Mode Rising/Falling: Sự kiện cả sườn lên và xuống
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
Cấu hình Ngắt ngoài STM32 trên Keil C
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 đó
Lưu ý:
Mỗi Line chỉ sử dụng được 1 chân: Ví dụ Line 0 dùng chân PA0 thì PB0 sẽ ko thể sử dụng làm chân ngắt nữa
Kết
Ngắt ngoài STM32 được sử dụng rất rộng rãi, nhất là trong các ứng dụng Low power, khi đó MCU sẽ phải rơi vào trạng thái Sleep, khi có tác động từ bên ngoài, ngắt ngoài sẽ xảy ra và báo MCU hoạt động trở lại