Bài viết 6 thuộc series STM32F103C8T6 tập trung theo hướng “học để làm được việc”. Với chủ đề Timer cơ bản trên STM32F103C8T6, bạn sẽ đi từ lý thuyết cốt lõi đến quy trình triển khai thực tế trong phòng lab. Nội dung được thiết kế để sinh viên, kỹ thuật viên bảo trì và người mới chuyển từ PLC sang Embedded đều có thể áp dụng ngay vào project mẫu.
Timer là trái tim của firmware thời gian thực. Dù project nhỏ hay lớn, chất lượng cấu hình timer quyết định nhịp xử lý, lịch quét cảm biến và khả năng đồng bộ dữ liệu.
1. Mục tiêu bài học
Bài này giúp bạn đi từ công thức tính prescaler/ARR đến cách tổ chức timer interrupt để tạo scheduler mềm ổn định.
- Nắm công thức tính tần số và chu kỳ timer.
- Cấu hình timer base + interrupt trên STM32F103C8T6.
- Dùng timer để tạo task định kỳ cho nhiều tác vụ.
- Đo và đánh giá jitter của chu kỳ timer.
Sau khi hoàn thành, bạn nên tự trả lời được ba câu hỏi: hệ thống cần đo/điều khiển đại lượng gì, vòng đời xử lý dữ liệu chạy theo chu kỳ nào, và cơ chế bảo vệ lỗi nào cần có để hệ thống ổn định khi chạy liên tục ngoài hiện trường.
2. Kiến thức nền tảng
STM32F103C8T6 dùng lõi ARM Cortex-M3, phù hợp để học đồng thời kiến trúc MCU và phương pháp lập trình thời gian thực. Khi học theo lộ trình chuẩn, bạn nên nắm đồng thời phần cứng (clock, GPIO, bus, nguồn), firmware (HAL/LL, ngắt, timer), và phương pháp test (scope, logic analyzer, UART log). Việc kết hợp đủ ba lớp kiến thức giúp quá trình debug nhanh hơn nhiều so với chỉ học code thuần.
- Quan hệ giữa SYSCLK, APB clock và timer clock.
- Ý nghĩa prescaler, counter mode, auto-reload.
- Cơ chế update event và ngắt update.
- Ảnh hưởng ISR dài đến độ chính xác chu kỳ.
Trong quá trình thực hành, bạn nên duy trì checklist kiểm thử ở từng vòng: xác nhận wiring, xác nhận xung clock, xác nhận trạng thái ngoại vi, sau đó mới kiểm tra thuật toán. Cách làm này giảm đáng kể lỗi dây chuyền và giúp nhóm dự án phối hợp hiệu quả giữa phần cứng và phần mềm.
3. Phân tích kỹ thuật
Tính toán prescaler và ARR
Muốn có chu kỳ chuẩn, phải bắt đầu từ timer input clock thật sự. Sau đó chọn prescaler để đưa tần số đếm về mức dễ xử lý, rồi dùng ARR để tạo chu kỳ mong muốn. Cách này dễ kiểm soát và dễ audit lại.
- Luôn ghi rõ công thức trong comment cấu hình.
- Tránh dùng giá trị “mò” không giải thích.
- Kiểm tra overflow khi mở rộng chu kỳ dài.
Timer interrupt cho scheduler mềm
Thay vì để logic nằm trong ISR, nên tạo tick định kỳ và để main loop xử lý theo cờ thời gian. Đây là cách cân bằng giữa tính đáp ứng và độ ổn định, phù hợp cho project học và project ứng dụng thực tế.
- ISR chỉ tăng tick và set cờ tác vụ.
- Main loop đọc cờ và xử lý theo mức ưu tiên.
- Dễ mở rộng thêm tác vụ mà không phá cấu trúc.
Đo độ chính xác và jitter
Kiểm thử timer nên dùng chân debug toggle để đo bằng oscilloscope. Nếu thấy jitter cao, cần kiểm tra ưu tiên ngắt, độ dài ISR hoặc tác vụ chặn trong luồng nền.
- Toggle chân trong callback để đo chu kỳ thực.
- So sánh khi bật/tắt các ngắt khác trong hệ thống.
- Lưu kết quả đo vào báo cáo để tối ưu tiếp.
Từ góc nhìn hệ thống, chủ đề này không chỉ là “chạy được chức năng”, mà còn là bài toán tối ưu độ tin cậy, độ trễ xử lý, khả năng mở rộng khi thêm cảm biến hoặc thêm kênh truyền thông. Nếu ngay từ đầu bạn chuẩn hóa cấu trúc code theo module driver/app/service thì giai đoạn mở rộng về sau sẽ nhẹ hơn rất nhiều.
4. Các bước thực hiện
Hãy luôn xác nhận clock timer thực tế trước khi kết luận sai số do thuật toán.
- Xác định timer clock thực tế từ cấu hình RCC.
- Tính prescaler/ARR theo chu kỳ mục tiêu.
- Enable update interrupt và cấu hình NVIC.
- Viết callback tăng tick hệ thống.
- Tạo scheduler mềm dựa trên tick cho nhiều tác vụ.
- Đo jitter và tinh chỉnh ưu tiên ngắt nếu cần.
Ở mỗi bước, bạn nên lưu log kỹ thuật (ảnh wiring, ảnh cấu hình CubeMX, thông số timer/UART/ADC, snapshot kết quả đo). Bộ log này giúp giảng viên hoặc trưởng nhóm đánh giá tiến độ nhanh và giảm thời gian trao đổi khi cần hỗ trợ từ xa.
5. Ví dụ timer 1 ms tick cho scheduler
Code dưới đây là mẫu rút gọn theo HAL Library, tập trung phần cốt lõi để bạn nhìn rõ luồng xử lý. Khi đưa vào dự án thực, hãy tách code thành các module rõ ràng, thêm kiểm tra lỗi trả về và timeout cho mọi giao tiếp ngoại vi.
volatile uint32_t g_tick_1ms = 0;
void HAL_TIM_PeriodElapsedCallback(TIM_HandleTypeDef *htim)
{
if (htim->Instance == TIM2) {
g_tick_1ms++;
}
}
void App_Task(void)
{
static uint32_t t_led = 0;
if ((g_tick_1ms - t_led) >= 500) {
t_led = g_tick_1ms;
HAL_GPIO_TogglePin(GPIOC, GPIO_PIN_13);
}
}
Nguyên tắc quan trọng: giữ hàm ngắt ngắn gọn, xử lý nặng chuyển về vòng lặp chính hoặc task nền; dùng biến trạng thái rõ ràng để tránh race condition; thêm timeout cho mọi thao tác có thể block. Đây là nền tảng để firmware ổn định khi chạy lâu dài.
6. Lỗi thường gặp
Phần lớn lỗi trong STM32F103C8T6 đến từ cấu hình chưa đồng bộ giữa clock, ngoại vi và wiring thực tế. Nếu bạn xử lý theo thứ tự “đọc triệu chứng -> khoanh vùng lớp lỗi -> test độc lập từng khối”, thời gian debug sẽ giảm rất rõ.
- Tính sai timer clock do không xét APB prescaler.
- Để nhiều logic nặng trong callback timer.
- Không dùng biến volatile cho tick dùng đa ngữ cảnh.
- Gộp nhiều tác vụ nhưng không quản lý deadline.
- Không đo thực tế nên không phát hiện jitter lớn.
Đừng lạm dụng nhiều timer nếu một scheduler tốt có thể gộp nhiệm vụ.
7. Bài tập thực hành
Để chuyển từ mức “hiểu lý thuyết” sang “làm chủ kỹ năng”, bạn nên làm các bài tập sau theo đúng thứ tự từ dễ đến khó, sau mỗi bài đều ghi lại tiêu chí đạt/chưa đạt và thông số đo thực tế.
- Tạo scheduler 1 ms điều khiển 3 tác vụ chu kỳ khác nhau.
- Đo jitter khi thêm UART interrupt và phân tích nguyên nhân.
- Tạo timer 100 us để lấy mẫu tín hiệu và so sánh tải CPU.
- Viết module timer service có API đăng ký callback tác vụ.
Khuyến nghị chấm bài theo rubric: đúng chức năng (40%), độ ổn định 30 phút chạy liên tục (30%), chất lượng cấu trúc code (20%), tài liệu kỹ thuật và báo cáo đo kiểm (10%).
Tài liệu tham khảo
- STMicroelectronics, STM32F103x8/B Datasheet.
- STMicroelectronics, RM0008 Reference Manual: STM32F10xxx advanced ARM-based 32-bit MCUs.
- STMicroelectronics, UM1850 STM32CubeMX user manual và tài liệu STM32Cube liên quan.
- ARM, Cortex-M3 Technical Reference Manual.
- STMicroelectronics Application Notes về GPIO, ADC, Timer, UART, I2C, SPI, DMA và Watchdog.