Ở bài viết trước, chúng ta đã hiểu Timer hoạt động như một chiếc đồng hồ bấm giờ dựa trên xung nhịp nội. Nhưng trong thực tế, vi điều khiển thường xuyên phải đối mặt với các bài toán như: “Động cơ đang quay bao nhiêu vòng/phút?” hay “Có bao nhiêu sản phẩm đã chạy qua băng chuyền?”. Để trả lời những câu hỏi này, chúng ta cần sử dụng Timer ở chế độ Counter (Bộ đếm).
🎯 Mục tiêu bài học
- Phân biệt bản chất giữa Timer Mode và Counter Mode.
- Tìm hiểu các nguồn xung nhịp ngoại: External Clock Mode 1 và Mode 2.
- Khám phá Encoder Mode – Kỹ thuật đọc vị trí động cơ đỉnh cao.
- Thực hành cấu hình bộ đếm sự kiện trên STM32.
1. Timer vs Counter: Khác biệt nằm ở nguồn xung (Clock Source)
Cấu trúc bên trong của bộ đếm TIMx_CNT là không đổi, sự khác biệt duy nhất nằm ở việc cái gì làm cho nó tăng giá trị:
- Timer Mode: Nguồn xung là Internal Clock (CK_INT) từ hệ thống. Vì tần số này cực kỳ ổn định, việc đếm xung tương đương với việc đo thời gian.
- Counter Mode: Nguồn xung là các Tín hiệu ngoại đưa vào thông qua các chân GPIO (ví dụ chân ETR hoặc các kênh TI1, TI2). Lúc này, bộ đếm sẽ tăng lên mỗi khi có một xung điện (sườn lên hoặc sườn xuống) từ cảm biến bên ngoài đưa vào.
2. Các chế độ đếm xung ngoại trên STM32
Dòng STM32 hỗ trợ hai cách chính để cấu hình bộ đếm xung ngoại thông qua bộ kết nối Slave Mode Controller:
a) External Clock Mode 1
Trong chế độ này, bộ đếm có thể nhận xung từ các kênh đầu vào của chính nó (TI1 hoặc TI2).
- Ứng dụng: Đếm xung từ các cảm biến tiệm cận, cảm biến quang.
- Ưu điểm: Có thể sử dụng các bộ lọc số (Digital Filter) tích hợp sẵn để loại bỏ nhiễu của tín hiệu đầu vào trước khi đếm.
b) External Clock Mode 2 (ETR – External Trigger Input)
Đây là chế độ đếm chuyên dụng sử dụng chân ETR của Timer.
- Cơ chế: Xung ngoại đi trực tiếp vào bộ chia tần (Prescaler của ETR) rồi làm tăng bộ đếm.
- Ứng dụng: Đếm các xung có tần số cao hoặc các tín hiệu trigger độc lập.
3. Encoder Mode – “Vũ khí” cho Robot và Động cơ
Đây là một chế độ Counter đặc biệt và mạnh mẽ nhất của General Purpose Timer. Thay vì chỉ đếm xung đơn thuần, nó sử dụng hai tín hiệu (Phase A và Phase B) từ Incremental Encoder.
- Tự động nhận diện chiều quay: Nếu Phase A dẫn trước Phase B, Timer tự động đếm lên (Up). Nếu Phase B dẫn trước Phase A, Timer tự động đếm xuống (Down).
- Độ phân giải X4: Bộ đếm có thể tăng ở cả sườn lên và sườn xuống của cả hai kênh, giúp tăng độ chính xác lên gấp 4 lần so với cách đếm thông thường.
4. Thực hành: Cấu hình bộ đếm sự kiện (ETR) trên STM32CubeMX
Giả sử chúng ta muốn đếm số lần nhấn nút (hoặc xung từ cảm biến) đưa vào chân PA12 (TIM1_ETR).
- Pinout & Configuration: Chọn Timer 1.
- Slave Mode: Chọn
External Clock Mode 2.
- Clock Source: Lúc này sẽ tự động chuyển sang
ETR2.
- Cấu hình bộ lọc (Filter): Nhập giá trị từ 1-15 để tránh việc bộ đếm tăng nhiều lần do rung động cơ học (Debounce).
- Counter Period (ARR): Đặt giá trị tối đa (65535) nếu bạn muốn đếm liên tục.
Code xử lý giá trị bộ đếm:
/* Khởi động Timer ở chế độ đếm xung ngoại */
HAL_TIM_Base_Start(&htim1);
uint32_t count_value = 0;
while (1)
{
// Đọc giá trị hiện tại của bộ đếm
count_value = __HAL_TIM_GET_COUNTER(&htim1);
// Nếu muốn reset bộ đếm về 0
if(count_value > 1000) {
__HAL_TIM_SET_COUNTER(&htim1, 0);
}
HAL_Delay(100);
}
💡 Ứng dụng thực tế: Đo vận tốc động cơ (Tachometer)
Để đo vận tốc (vòng/phút), chúng ta kết hợp cả 2 Timer:
- Timer 1: Cấu hình ở chế độ Counter để đếm tổng số xung từ Encoder.
- Timer 2: Cấu hình ở chế độ Timer tạo ngắt định kỳ mỗi 1 giây.
- Công thức: Trong ngắt 1 giây của Timer 2, ta đọc giá trị của Timer 1, sau đó reset Timer 1 về 0. Số xung đọc được chính là tần số (Hz). Từ đó tính ra RPM.
🚀 Bài tập nâng cao
- Đếm sản phẩm: Sử dụng 1 cảm biến quang nối vào chân ETR của Timer. Viết chương trình đếm sản phẩm trên băng chuyền. Khi đủ 10 sản phẩm (ARR = 9), hãy kích hoạt ngắt để dừng động cơ băng chuyền.
- Đọc Encoder: Kết nối Encoder của động cơ DC vào chân TI1 và TI2 của Timer 2. Cấu hình Encoder Mode và in giá trị đếm lên màn hình máy tính qua UART. Quan sát giá trị tăng khi xoay thuận và giảm khi xoay nghịch.
📝 Tóm tắt: Timer là một công cụ đa năng. Khi bạn cung cấp cho nó một nhịp điệu đều đặn, nó là một chiếc đồng hồ. Khi bạn đưa cho nó các sự kiện hỗn loạn từ bên ngoài, nó trở thành một bộ đếm trung thành. Việc hiểu rõ cách cấu hình nguồn xung (Clock Source) là chìa khóa để làm chủ ngoại vi này.
“Trong lập trình nhúng, đôi khi chúng ta không đo thời gian, chúng ta đếm những khoảnh khắc.”
Gợi ý bài tiếp theo: Giao Tiếp Với Thế Giới Tương Tự: Làm Chủ ADC Và DAC Trên STM32.