Nội Dung Bài Viết
Cấu hình Counter Mode trên STM32F103RCT6 là một kỹ thuật quan trọng trong lập trình thanh ghi STM32F103, giúp timer hoạt động như một bộ đếm sự kiện từ tín hiệu ngoài. Trong bài viết này, chúng ta sẽ khám phá chi tiết cách cấu hình Counter Mode STM32F103, từ việc bật clock đến đọc giá trị đếm, kèm theo mã nguồn mẫu. Nếu bạn đang tìm hiểu cấu hình Counter Mode STM32F103RCT6, đây là hướng dẫn thực tế để áp dụng vào các dự án như đếm xung encoder hoặc cảm biến tốc độ.
Giới thiệu về Counter Mode trên STM32F103
Counter Mode (external signal on TI2) là chế độ mà timer (như TIM2) không sử dụng clock nội bộ mà đếm dựa trên tín hiệu ngoài. Ví dụ điển hình là cấu hình Counter Mode STM32F103 với SMS = 7 (external clock mode 1), TS = 6 (TI2FP2). Trong chế độ này, timer hoạt động như một bộ đếm (counter) thay vì tạo tín hiệu định kỳ như Timer Mode. Thay vì sử dụng clock nội bộ (đồng hồ hệ thống), bạn có thể cấu hình timer để đếm các sự kiện từ một tín hiệu ngoài (external signal) thông qua các chân đầu vào như TI1 hoặc TI2.
Ví dụ: Mỗi khi có 1 xung logic (ví dụ: rising edge) ở chân PA1 (TIM2_CH2), thanh ghi đếm CNT của TIM2 sẽ tăng lên 1. Điều này làm cho cấu hình Counter Mode STM32F103RCT6 trở nên lý tưởng cho các ứng dụng thực tế, giúp tối ưu hóa hiệu suất hệ thống mà không cần phần mềm can thiệp liên tục.
Ứng dụng của Counter Mode
Cấu hình Counter Mode STM32F103 được áp dụng rộng rãi trong các lĩnh vực sau:
- Đếm số xung encoder (bánh xe quay) để đo lường vị trí hoặc tốc độ quay.
- Đếm số sản phẩm (sensor quang, cảm biến hồng ngoại) trong dây chuyền sản xuất tự động.
- Đếm tần số hoặc xung từ cảm biến tốc độ, hữu ích trong hệ thống giám sát xe hơi hoặc máy móc công nghiệp.
- Theo dõi sự kiện từ các thiết bị ngoại vi như nút bấm hoặc cảm biến chuyển động, giúp giảm tải cho CPU.
Bằng cách sử dụng cấu hình Counter Mode STM32F103RCT6, bạn có thể xử lý dữ liệu thời gian thực mà không làm gián đoạn các nhiệm vụ khác của microcontroller.
Các bước cấu hình TIM2 Counter Mode trên STM32F103RCT6

Dưới đây là hướng dẫn chi tiết cấu hình Counter Mode STM32F103, tập trung vào việc sử dụng thanh ghi trực tiếp để kiểm soát phần cứng. Quy trình này đảm bảo tính chính xác và hiệu quả cao.
Bật clock cho TIM2
Thanh ghi APB1ENR bật clock cho các ngoại vi trên bus APB1, bao gồm TIM2. Đặt TIM2EN = 1 kích hoạt clock cho TIM2, với tần số clock là 72MHz (Nếu SYSCLK = 72MHz và APB1 prescaler = 1). Bước này là nền tảng cho mọi cấu hình Counter Mode STM32F103RCT6, vì không có clock, timer sẽ không hoạt động.
1 | RCC->APB1ENR.TIM2EN = 1; |
Cấu hình chân PA1 làm đầu vào cho TIM2_CH2
- Chân PA1 có thể được cấu hình làm đầu vào cho kênh 2 của TIM2 (TIM2_CH2).
- RCC->APB2ENR.IOPAEN = 1: Bật clock cho cổng GPIOA.
- GPIOA->CRL.MODE1 = 0: Đặt chế độ input (mode 00) cho bit 1 (PA1).
- GPIOA->CRL.CNF1 = 1 (cụ thể là CNF1[1:0] = 01 trong cấu hình 4-bit): Chọn chế độ floating input (không kéo lên/kéo xuống), phù hợp để nhận tín hiệu ngoài.
- Mục đích: PA1 được sử dụng làm nguồn tín hiệu đầu vào cho TI2, nơi tín hiệu ngoài sẽ được đọc.
1 2 3 | RCC->APB2ENR.IOPAEN = 1; GPIOA->CRL.MODE1 = 0; // Input mode GPIOA->CRL.CNF1 = 1; // Floating input |
Trong cấu hình Counter Mode STM32F103, việc chọn chế độ floating input giúp tránh nhiễu từ nguồn điện nội bộ, đảm bảo tín hiệu ngoài được đọc chính xác.
Chọn channel 2 input cho TI2
- Thanh ghi TIMx_CCMR1, set CC2S = 01.
1 2 | TIM2->CCMR1 &= ~ (0x3<<8); // Configure channel 2 detect rising edge (CC2S = 01) TIM2->CCMR1 |= (1<<8); |
Bước này định nghĩa kênh đầu vào, là yếu tố then chốt trong cấu hình Counter Mode STM32F103RCT6 để liên kết phần cứng với timer.
Cấu hình lọc nhiễu cho TI2
- Thanh ghi TIMx_CCMR1, set giá trị cho IC2F[3:0].
- Giữ IC2F = 0000 nếu không cần lọc nhiễu cho TI2.
1 2 | TIM2->CCMR1 &= ~(0xF << 12); // Clear bit 15:12 TIM2->CCMR1 |= (0x8 << 12); // filter TI2, IC2F = 0x8 |
Để nâng cao độ tin cậy, bạn có thể điều chỉnh IC2F lên giá trị cao hơn (như 0x8) nếu môi trường có nhiễu điện từ, giúp cấu hình Counter Mode STM32F103 hoạt động ổn định hơn trong ứng dụng thực tế.
Chọn cấu hình xung đếm cho counter (cạnh lên hay cạnh xuống)
- Thanh ghi TIMx_CCER, set CC2P = 0 nếu cấu hình đếm cạnh lên.
- Set CC2P = 1 nếu cấu hình đếm cạnh xuống.
1 | TIM2->CCER &= ~(1 << 5); // Select rising edge polarity CC2p = 0 |
Lựa chọn này tùy thuộc vào loại tín hiệu ngoài, ví dụ rising edge phổ biến cho encoder.
Cấu hình TIM2 cho External Clock Mode 1
Thanh ghi TIMx_SMCR (Slave Mode Control Register) điều khiển chế độ hoạt động của timer khi sử dụng tín hiệu ngoài.
- Set SMS = 111 (tức 7).
- Giá trị SMS = 7 chọn External Clock Mode 1, trong đó timer đếm các sự kiện từ một tín hiệu ngoài được chọn làm trigger.
- Trong chế độ này, mỗi lần tín hiệu ngoài (sau khi lọc và điều chỉnh) chuyển từ mức thấp sang mức cao (rising edge) hoặc mức thấp (falling edge), bộ đếm (CNT) tăng 1.
1 | TIM2->SMCR.SMS = 7; // External clock mode 1 |
Cấu hình input source TI2
- Thanh ghi TIMx_SMCR, set TS = 110 (tức 6):
- TS (Trigger Selection) chọn nguồn trigger. Giá trị 110 tương ứng với TI2FP2 (Filtered Timer Input 2), nghĩa là tín hiệu từ chân TI2 (PA1) được sử dụng sau khi qua bộ lọc (filter) để loại nhiễu.
- TI2FP2 là tín hiệu đã được xử lý từ TI2, phụ thuộc vào cấu hình bộ lọc (ICxF) trong thanh ghi CCMR1.
1 | TIM2->SMCR.TS = 6; // Trigger source TI2FP2 |
Bật bộ đếm (counter)
- Thanh ghi CR1 (Control Register 1) điều khiển hoạt động của timer. Đặt CEN (Counter Enable) = 1 khởi động bộ đếm.
- Sau khi bật, timer sẽ đếm các sự kiện rising edge hoặc falling edge từ tín hiệu ngoài trên PA1 (TI2FP2), và giá trị đếm được lưu trong TIM2->CNT.
1 | TIM2->CR1.CEN = 1; // Enable counter |
Đọc giá trị đếm
- Thanh ghi CNT (Counter Register) chứa giá trị hiện tại của bộ đếm. Bạn có thể đọc TIM2->CNT bất kỳ lúc nào để lấy số lượng sự kiện (rising edge) đã được đếm từ tín hiệu ngoài.
1 | countEncoderChannelB = TIM2->CNT; |
Code chương trình mẫu cho Cấu hình Counter Mode STM32F103RCT6
Dưới đây là chương trình mẫu sử dụng cấu hình Counter Mode STM32F103 để đếm tín hiệu channel B của Encoder với xung cạnh lên. Mã này được viết bằng C, sử dụng thư viện thanh ghi trực tiếp.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | void TIM2_Counter_Config(void) { // Enable TIM2 clock RCC->APB1ENR.TIM2EN = 1; // Configure PA1 as input for TIM2_CH2 RCC->APB2ENR.IOPAEN = 1; GPIOA->CRL.MODE1 = 0; // Input mode GPIOA->CRL.CNF1 = 1; // Floating input // Disable counter before configuration TIM2->CR1.CEN = 0; TIM2->CCMR1 &= ~ (0x3<<8); // Configure channel 2 detect rising edge (CC2S = 01) TIM2->CCMR1 |= (1<<8); TIM2->CCMR1 &= ~(0xF << 12); // Clear bit 15:12 TIM2->CCMR1 |= (0x8 << 12); // filter TI2, IC2F = 0x8 TIM2->CCER &= ~(1 << 5); // Select rising edge polarity CC2p = 0 TIM2->SMCR.SMS = 7; // External clock mode 1 TIM2->SMCR.TS = 6; // Trigger source TI2FP2 TIM2->CR1.CEN = 1; // Enable counter } uint32_t countEncoderChannelB = 0; int main(void) { SystemClock_Config(); // Initialize system clock TIM2_Counter_Config(); while (1) { countEncoderChannelB = TIM2->CNT; } } |
Mã này minh họa rõ ràng cấu hình Counter Mode STM32F103RCT6, với các bước được thực hiện theo thứ tự logic để tránh lỗi.
Link Github: Download chương trình cấu hình Counter Mode STM32F103RCT6
Sơ đồ kết nối board STM32F103RCT6 mini và Encoder rotary cho cấu hình Counter Mode STM32F103
Với chế độ counter mode, chỉ cần kết nối một kênh encoder như một đầu vào đếm xung.
| Board STM32F103RCT6 mini | Encoder Rotary |
| Chân 3v3 | Chân VDD (+) |
| Chân GND | Chân GND |
| Chân PA1 | Chân VDD |

Hướng dẫn kiểm tra kết quả đếm xung encoder với counter mode trên Keil C
Thiết lập cửa sổ Watch luôn cập nhật giá trị variable trong Keil C: Vào menu View >> Tick chọn Periodic Window Update

Mỗi lần quay encoder, xung sẽ được đếm và giá trị sẽ được cập nhật và biểu thị qua biến countEncoderChannelB trong cửa sổ Watch 1 trên Keil C

Lợi ích và lưu ý khi sử dụng Counter Mode trên STM32F103
Sử dụng cấu hình Counter Mode STM32F103 mang lại nhiều lợi ích như giảm tải CPU, độ chính xác cao trong đếm sự kiện thời gian thực, và dễ dàng tích hợp với các cảm biến ngoại vi. Tuy nhiên, hãy lưu ý:
- Kiểm tra tần số tín hiệu ngoài không vượt quá giới hạn của timer (thường lên đến 72MHz).
- Nếu gặp nhiễu, tăng giá trị lọc IC2F để ổn định.
- Trong dự án lớn, kết hợp với interrupt để xử lý overflow của CNT (khi đạt 0xFFFF).
Nếu bạn gặp vấn đề trong cấu hình Counter Mode STM32F103RCT6, tham khảo tài liệu Reference Manual RM0008 của STMicroelectronics để có thêm chi tiết.
Kết luận
Tóm lại, cấu hình Counter Mode STM32F103 là một công cụ mạnh mẽ giúp tận dụng timer để đếm sự kiện thời gian thực từ tín hiệu ngoài, mang lại hiệu suất cao và giảm tải cho CPU trong các dự án nhúng. Từ việc đếm xung encoder đến giám sát cảm biến tốc độ, Counter Mode trên STM32F103RCT6 không chỉ đơn giản hóa quy trình lập trình mà còn mở ra nhiều ứng dụng thực tế trong lĩnh vực tự động hóa và IoT. Với hướng dẫn chi tiết thông qua lập trình thanh ghi trực tiếp, mã nguồn mẫu và các lưu ý quan trọng, bạn hoàn toàn có thể triển khai ngay hôm nay. Nếu bạn đang phát triển dự án trên STM32F103, hãy thử nghiệm Counter Mode để tối ưu hóa hệ thống của mình.
Bài viết này cung cấp hướng dẫn toàn diện về cấu hình Counter Mode STM32F103 trong chuỗi bài hướng dẫn lập trình STM32F103 thanh ghi, giúp bạn áp dụng nhanh chóng vào dự án. Nếu cần thêm ví dụ hoặc mã nguồn mở rộng, hãy để lại bình luận!
Câu hỏi thường gặp (FAQ) về Counter Mode STM32F103
❓ Counter Mode khác gì Encoder Mode trên STM32F103?
Counter Mode sử dụng timer để đếm xung từ một kênh duy nhất (TI1 hoặc TI2), phù hợp cho các ứng dụng như đếm sản phẩm, đo tần số hoặc đếm xung encoder đơn kênh.
Trong khi đó, Encoder Mode sử dụng hai kênh TI1 và TI2, cho phép xác định cả số xung lẫn chiều quay, thường dùng cho encoder quadrature (X2, X4).
👉 Nếu chỉ cần đếm số xung → dùng Counter Mode
👉 Nếu cần xác định hướng quay → dùng Encoder Mode
❓ TIM2 trong Counter Mode STM32F103 đếm tối đa bao nhiêu xung?
TIM2 là timer 16-bit, vì vậy trong Counter Mode STM32F103, thanh ghi CNT có thể đếm từ:
Khi CNT tràn, timer sẽ quay về 0. Trong các ứng dụng cần đếm lâu dài, nên kết hợp interrupt tràn (update interrupt) để mở rộng số xung đếm.
❓ Khi nào nên sử dụng bộ lọc IC2F trong Counter Mode?
Bộ lọc IC2F nên được sử dụng khi:
- Tín hiệu ngoài có nhiễu hoặc rung xung
- Encoder cơ hoặc cảm biến quang đặt trong môi trường công nghiệp
- Dây tín hiệu dài hoặc không được che chắn tốt
Nếu tín hiệu sạch (logic TTL rõ ràng), có thể đặt IC2F = 0 để tăng tốc độ đáp ứng.
Ngược lại, khi môi trường nhiễu, nên tăng IC2F (ví dụ IC2F = 0x8) để đảm bảo Counter Mode STM32F103RCT6 hoạt động ổn định.
