🌱 STM32 - 19. Systick Timer - Examples
Ở post trước, mình đã giới thiệu với các bạn về Systick Timer - Overview & Registers, post này sẽ lấy một ví dụ điển hình để các bạn có thể sử dụng Systick.
👉 Tham khảo tài liệu Core Cortex M4 Device Generic User Guide, chúng ta có hẳn một phần Hints & Tips, mà không cần tham khảo ông nào trên mạng cả 😅
👉 Để cấu hình cho Systick Timer, chúng ta sẽ làm theo 3 bước trên:
- Đặt giá trị đếm ban đầu - Reload Value bằng thanh ghi SYST_RVR.
- Xóa giá trị đếm hiện tại trên thanh ghi SYST_CVR.
- Cấu hình hoạt động cho Systick Timer bằng thanh ghi Control SYST_CSR.
- Chọn nguồn cấp xung Clock cho Systick bằng Bit[2] - CLKSOURCE.
- Cho phép ngắt Systick (nếu sử dụng ngắt) bằng Bit[1] - TICKINT.
- Cho phép bộ đếm Systick hoạt động bằng Bit[0] - ENABLE.
👉 Example - myHAL_Delay()
Ví dụ này mình sẽ sử dụng ngắt systick để tạo 2 hàm delay (delay ms và delay us). Ý tưởng giống như hàm HAL_Delay nhưng đơn giản hơn.
Vậy đầu tiên mình cần tính toán về Clock, hãy tính làm sao cho mỗi lần Systick Timer tràn, thì chúng ta đã đếm được 1us. Mình sẽ triển khai tính toán trên Vi điều khiển STM32F401 của mình như sau:
💚 Đầu tiên cấu hình Clock sử dụng là Internal Clock HSI (Xem bài RCC và cấu hình Clock tại đây)
Mình chọn tần số clock là 16Mhz và bus AHB cấp cho Systick cũng mang tần số này.
💚 Define các thanh ghi Systick
Các bạn có thể tham khảo tài liệu Core để xem địa chỉ các thanh ghi của Systick, ở post trước về Systick Registers mình cũng đã nói qua.
💚 Cấu hình cho Systick Timer
Mình sẽ chọn Clock Source cho Systick là Extenal Clock, tức là AHB/8 = 16Mhz/8 = 2Mhz. Như vậy, mỗi một chu kỳ xung clock sẽ là 1/2Mhz = 0.5us. Vậy để đếm được 1us, chúng ta chỉ cần 2 chu kỳ clock là đủ.
⇒ Cần nạp thanh ghi Reload giá trị là 2.
Sau đó chúng ta cho phép ngắt Systick bằng thanh ghi SYST_RVR.
💚 Cấu hình cho hàm Delay
Cho phép bộ đếm chạy và bắt đầu đếm số lần tràn của Systick Timer bằng chương trình phục vụ ngắt Systick_Handler().
💬 Ở đây mỗi tick chúng ta sẽ nhảy vào Systick_Handler(). Mỗi microsecond sẽ tương ứng là 2 tick. Khi nhảy vào ISR, chúng ta sẽ giảm tick này đi, cho đến khi usTicks này bằng 0 thì dừng và disable Systick.
💬 Có hàm Delay_us rồi thì hàm Delay_ms cũng rất đơn giản, 1ms = 1000us.
Các bạn có thể DOWNLOAD Code Tại đây!
dạ anh cho em hỏi ở hàm Systick_Handler() chỗ while(usTisks); mình truyền usTicks bằng 1000 thì làm sao để chương trình thoát được vòng while đó ạ
Trả lờiXóaà em thấy cái hàm ở dưới r ạ, nãy em k để ý. cảm ơn anh ạ
Trả lờiXóamình gọi hàm Systick_Handler() ở trong vòng while(usTisks); đúng không ạ
Trả lờiXóaKhông nhé, Systick_Handler() là hàm phục vụ ngắt và sẽ được thực thi khi ngắt Systick xảy ra
Xóadạ anh cho em hỏi làm sao để chương trình gọi hàm Systick_Handler() khi có ngắt xảy ra vậy ạ
Trả lờiXóaEm tìm hiểu về flow của ngắt nhé, khi ngắt xảy ra CPU sẽ tìm tới vector table và lấy được địa chỉ của hàm Systick_Handler
Xóa