Chọn chip và timer, nhập thời gian muốn ngắt, công cụ trả về Prescaler và Counter Period để điền vào STM32CubeMX, kèm clock tree từ SYSCLK tới timer.
Clock của timer đi từ đâu?
Đây là chỗ hay nhầm nhất. Timer không chạy theo SYSCLK mà đi qua ba bước, đúng như trong tab Clock Configuration của STM32CubeMX:
- SYSCLK qua AHB Prescaler thành HCLK.
- HCLK qua APB1 hoặc APB2 Prescaler thành clock ngoại vi PCLK1 hoặc PCLK2.
- Nếu APB Prescaler khác 1, phần cứng nhân 2 trước khi đưa vào timer. Đó là ô APB1 Timer clocks và APB2 Timer clocks trong CubeMX.
Ví dụ STM32F103 chạy 72 MHz: APB1 chia 2 nên PCLK1 chỉ 36 MHz, nhưng TIM2, TIM3, TIM4 vẫn nhận 72 MHz. Ai lấy 36 MHz để tính sẽ ra thời gian ngắt sai gấp đôi.
Công thức thời gian ngắt
T_ngắt = (PSC + 1) × (ARR + 1) / f_TIM
Timer chia clock qua Prescaler (PSC), rồi đếm từ 0 tới Counter Period (ARR). Mỗi lần đếm tràn, timer sinh ngắt update. Cộng 1 vào PSC và ARR vì cả hai đều đếm từ 0.
Ví dụ: ngắt mỗi 1 ms trên Blue Pill
TIM2 nhận 72 MHz. Chọn PSC = 71 thì timer đếm 1 MHz (1 µs mỗi tick). Cần 1000 tick cho 1 ms nên ARR = 999.
(71 + 1) × (999 + 1) / 72 000 000 = 0.001 s = 1 ms
Trong CubeMX nhớ bật NVIC Settings → TIM2 global interrupt, sau đó gọi HAL_TIM_Base_Start_IT(&htim2) và viết code trong HAL_TIM_PeriodElapsedCallback().
Timer 16-bit và 32-bit
PSC và ARR của hầu hết timer là 16-bit (0 – 65535). Với 72 MHz, timer 16-bit ngắt chậm nhất khoảng 59.6 giây một lần. TIM2 và TIM5 trên F401, F411, F407 có ARR 32-bit nên đếm được lâu hơn rất nhiều.
