Lập trình STM32F103 Thanh Ghi: Cấu hình Timer Mode STM32F103RCT6

Trong lập trình vi điều khiển STM32 thanh ghi, Cấu hình timer mode là một trong những chức năng quan trọng nhất, được sử dụng để tạo delay chính xác, đo thời gian, tạo ngắt định kỳ, PWM, encoder và nhiều ứng dụng thời gian thực khác.

Trong bài viết này, chúng ta sẽ lập trình STM32F103RCT6 ở mức thanh ghi (bare-metal) để cấu hình Timer mode STM32F103, cụ thể là TIM2 tạo ngắt mỗi 1ms.
Từ đó xây dựng biến millis tương tự Arduino và sử dụng nó để đếm thời gian chính xác theo giây, điều khiển LED nhấp nháy 1Hz.

👉 Bài viết tập trung vào:

  • Hiểu bản chất Timer mode STM32F103
  • Cách tính Prescaler (PSC)Auto Reload Register (ARR)
  • Cơ chế ngắt Timer (Timer Interrupt)
  • Kiểm chứng độ chính xác thời gian trong thực tế

Tổng quan về Timer Mode trên STM32F103

STM32F103RCT6 sở hữu nhiều timer đa năng, trong đó TIM2 là timer 32-bit, hỗ trợ các chế độ:

  • Đếm lên (up-counter)
  • Đếm xuống (down-counter)
  • Center-aligned mode

Timer mode STM32F103 thường được sử dụng để tạo sự kiện định kỳ, giúp vi điều khiển xử lý tác vụ theo thời gian mà không cần polling liên tục, từ đó tiết kiệm tài nguyên CPU.

Trong bài viết này, chúng ta tập trung vào chế độ cơ bản nhất: tạo ngắt định kỳ 1ms với tần số hệ thống 72MHz, rất phù hợp cho:

  • Xây dựng hàm millis
  • Delay chính xác
  • Đồng bộ thời gian
  • Scheduler đơn giản

Giới thiệu Timer 2 (TIM2)

Timer 2 (TIM2) là một timer 32-bit trên STM32F103RCT6, được sử dụng để tạo ngắt định kỳ.

Cấu hình cơ bản:

  • Bật clock: RCC->APB1ENR.TIM2EN = 1
  • Prescaler: PSC = 71 → 72MHz / 72 = 1MHz
  • Auto Reload: ARR = 999 → 1kHz = 1ms
  • Kích hoạt ngắt khi đếm xong một chu kỳ

Mục tiêu cấu hình Timer Mode STM32F103

Cấu hình TIM2 với Timer mode STM32F103 với các yêu cầu:

  • TIM2 tạo ngắt mỗi 1ms
  • Sử dụng clock hệ thống 72MHz
  • Tăng biến millis trong hàm ngắt
  • Dùng millis để đếm 1 giây (1000ms) và toggle LED

Define struct các thanh ghi TIMx cho hướng dẫn lập trình STM32F103 thanh ghi

Dựa trên RM0008, Section 15.4 (trang 404-408):

Define struct TIMx Control Register 1

Define struct TIM Control Register 1 cho hướng dẫn lâp trình STM32F103 thanh ghi cấu hình Timer Mode STM32F103RCT6
TIMx Control Register 1

Define struct TIMx Slave Mode Control Register

Define struct TIM Slave Mode Control Register trong lập trình STM32F103 thanh ghi cấu hình TIMx STM32F103RCT6
TIMx Slave Mode Control Register

Define struct TIMx Status Register

Define struct TIMx Status Register trong lập trình STM32F103 thanh ghi cấu hình các mode TIMx STM32F103RCT6
TIMx Status Register

Bản đồ thanh ghi TIMx (TIMx register map)

Bản đồ thanh ghi TIMx (TIMx register map) STM32F103 - Hướng dẫn lập trình STM32F103 thanh ghi
Bản đồ thanh ghi TIMx (TIMx register map)

#define TIM2 ((TIM_TypeDef *)0x40000000UL)

Giải thích:

  • CR1: Điều khiển bộ đếm (CEN, DIR, ARPE; Section 15.4.1, trang 404).
  • SMCR: Chọn chế độ slave và trigger (SMS, TS; Section 15.4.3, trang 407).
  • SR: Cờ trạng thái (UIF, CCxIF; Section 15.4.5, trang 410).

Clock Timer và bus APB1

Timer mode STM32F103 hoạt động dựa trên clock từ bus APB1.

Với cấu hình:

  • SYSCLK = 72MHz
  • APB1 prescaler = 1

➡️ Clock cấp cho TIM2 là 72MHz

Lưu ý: Nếu APB1 prescaler ≠ 1, clock timer sẽ được nhân đôi theo quy tắc trong RM0008.

Bật clock cho TIM2

Thanh ghi RCC->APB1ENR điều khiển clock cho các ngoại vi trên bus APB1, trong đó TIM2 thuộc nhóm này.

Đặt bit TIM2EN = 1 để bật clock cho TIM2.

RCC->APB1ENR.TIM2EN = 1;

⚠️ Nếu không bật clock, timer sẽ không hoạt động, counter không tăng – đây là lỗi rất thường gặp khi lập trình STM32 thanh ghi.

Cấu hình Prescaler (PSC)

Lập trình STM32F103 thanh ghi: Cấu hình Timer Mode STM32F103 - Thanh ghi PSC (Prescaler) STM32F103
Thanh ghi PSC (Prescaler)

Vai trò Prescaler

Prescaler chia tần số clock đầu vào của timer để tạo tần số đếm thấp hơn.

Tính toán Prescaler

  • Clock TIM2 = 72MHz
  • Chọn PSC = 71

Công thức:

T_tick = (PSC + 1) / f_clock
= 72 / 72MHz
= 1µs

➡️ Sau prescaler, timer đếm với chu kỳ 1µs (1MHz).

TIM2->PSC = 71;

Lưu ý: Giá trị PSC chỉ được cập nhật khi có update event, vì vậy nên set PSC trước khi bật timer.

Cấu hình Auto Reload Register (ARR)

Lập trình STM32F103 thanh ghi: Cấu hình Timer Mode STM32F103 - Thanh ghi TIMx Auto-Reload Register (ARR) STM32F103
Thanh ghi TIMx Auto-Reload Register (ARR)

Vai trò ARR

ARR xác định giá trị tối đa mà timer đếm tới trước khi:

  • Tràn
  • Reload về 0
  • Tạo update event (và ngắt nếu được bật)

Tính toán ARR

  • Chu kỳ đếm = 1µs
  • 1ms = 1000µs

Vì timer đếm từ 0 → ARR:

ARR + 1 = 1000
ARR = 999
TIM2->ARR = 999;

➡️ Timer đếm từ 0 đến 999 → đúng 1ms cho mỗi chu kỳ.

Kích hoạt ngắt Timer

Thanh ghi DIER (DMA/Interrupt Enable Register) điều khiển các nguồn ngắt của timer.

  • Bit 0: UIE – Update Interrupt Enable

TIM2->DIER |= (1 << 0);

Update event xảy ra khi timer tràn từ ARR về 0, tức là mỗi 1ms trong cấu hình này.

Bật Timer

Thanh ghi CR1 điều khiển hoạt động của timer.

  • Bit CEN = 1 → bật bộ đếm
TIM2->CR1.CEN = 1;

Sau khi bật:

  • Timer bắt đầu đếm từ 0
  • Mỗi 1µs tăng 1
  • Khi đạt 999 → tràn → tạo ngắt

Cơ chế hoạt động của Timer Mode STM32F103

  • TIM2 đếm từ 0 → 999
  • Mỗi lần đếm = 1µs
  • Sau 1000 lần (1ms):
    • Cờ UIF trong TIM2->SR được set
    • Nếu UIE = 1 → CPU nhảy vào TIM2_IRQHandler()

⚠️ Trong hàm ngắt bắt buộc phải xóa cờ UIF, nếu không ngắt sẽ lặp vô hạn.

TIM2->SR &= ~(1 << 0); // Clear UIF

Code cấu hình Timer 2 (1ms Interrupt)

Hàm ngắt TIM2

Ứng dụng: Đếm thời gian 1 giây và nhấp nháy LED

Ý tưởng

  • TIM2 tạo ngắt mỗi 1ms → tăng millis
  • So sánh millis với mốc thời gian
  • Mỗi 1000ms → tăng biến đếm giây và toggle LED

Code main

Mức ưu tiên 5 là mức trung bình, thấp hơn các ngắt thời gian quan trọng như SysTick (nếu sử dụng).

Link Github: Download chương trình cấu hình STM32F103 timer mode 1ms TIM2

Ý nghĩa chương trình

  • Timer mode STM32F103 tạo tick 1ms chính xác
  • millis là bộ đếm thời gian toàn cục
  • countevery1second:
    • Đếm số giây đã trôi qua
    • Dùng để kiểm chứng độ chính xác timer
  • LED nhấp nháy 1Hz
  • NVIC_Interrupt_Enable(TIM2_IRQ): cho phép CPU nhận ngắt từ TIM2
  • NVIC_Set_Interrupt_Priority(28, 5): Đặt mức ưu tiên 5 cho ngắt từ TIM2

Kiểm chứng thực tế (Real Test)

Lập trình nhúng STM32F013 thanh ghi: Hướng dẫn cấu hình TIM2 với Timer mode 1ms - Kiểm tra hoạt động Timer 1ms
Kiểm tra hoạt động cấu hình Timer Mode STM32F103RCT6: Thời điểm bắt đầu check timer 1ms
  • Thời điểm bắt đầu: 12:03:00
Lập trình nhúng STM32F013 thanh ghi: Hướng dẫn cấu hình TIM2 với Timer mode 1ms - Kiểm tra hoạt động Timer 1ms sau 2 phút
Kiểm tra cấu hình TIM2 với Timer mode STM32F103RCT6 1ms: Kiểm tra tại timer 1ms sau 2 phút
  • Thời điểm sau 2 phút: 12:05:00
  • Giá trị countevery1second = 120

➡️ Timer 2 hoạt động chính xác trong 120 giây, sai số gần như bằng 0.

Kết luận

Qua bài viết này, bạn đã nắm vững:

  • Cách cấu hình Timer mode trong lập trình STM32F103 bằng thanh ghi
  • Hiểu rõ PSC, ARR và cơ chế update interrupt
  • Tự xây dựng hệ thống đo thời gian 1ms / 1s
  • Kiểm chứng timer trong điều kiện thực tế

Đây là nền tảng quan trọng để phát triển các ứng dụng thời gian thực trên STM32 như scheduler, delay không blocking hoặc RTOS.

Viết một bình luận

This site uses Akismet to reduce spam. Learn how your comment data is processed.