🌱 STM32 - 19. Systick Timer - Examples

🌱 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ả 😅

Systick Tips

    👉 Để 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. 

Systick

    💚 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.    

Register

    💚 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.

Systick

    💚 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().

Delayus

    💬 Ở đâ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. 

ISR

    💬 Có hàm Delay_us rồi thì hàm Delay_ms cũng rất đơn giản, 1ms = 1000us.

Delayms

    Các bạn có thể DOWNLOAD Code Tại đây!

>>>= Follow ngay =<<<

Để nhận được những bài học miễn phí mới nhất nhé 😊

Chúc các bạn học tập tốt 😊

                                        

Nguyễn Văn Nghĩa

Mình là một người thích học hỏi và chia sẻ các kiến thức về Nhúng IOT.

6 Nhận xét

  1. 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
  2. à em thấy cái hàm ở dưới r ạ, nãy em k để ý. cảm ơn anh ạ

    Trả lờiXóa
  3. mình gọi hàm Systick_Handler() ở trong vòng while(usTisks); đúng không ạ

    Trả lờiXóa
    Trả lời
    1. Khô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óa
  4. dạ 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óa
    Trả lời
    1. Em 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
Mới hơn Cũ hơn