Bài viết 19 thuộc series STM32F103C8T6 tập trung theo hướng “học để làm được việc”. Với chủ đề Thiết kế project mẫu STM32F103C8T6 đọc cảm biến và gửi dữ liệu UART, 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.
Sau khi học từng ngoại vi riêng lẻ, bước tiếp theo là ghép chúng thành một project hoàn chỉnh có cấu trúc rõ ràng. Đây là bài mô phỏng cách triển khai mini-project trong lớp đào tạo kỹ sư tự động hóa.
1. Mục tiêu bài học
Mục tiêu là xây một hệ nhỏ nhưng đúng kiến trúc: lấy mẫu định kỳ, xử lý dữ liệu, đóng gói bản tin và truyền thông ổn định.
- Tích hợp ADC, Timer và UART trong cùng firmware.
- Thiết kế pipeline dữ liệu từ sensor đến bản tin UART.
- Xây dựng format bản tin có thể parse tự động.
- Tạo checklist kiểm thử tích hợp cho project nhúng.
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.
- Chu kỳ lấy mẫu và Nyquist ở mức ứng dụng cơ bản.
- Lọc số nhẹ cho dữ liệu sensor.
- Đóng gói chuỗi CSV/JSON đơn giản cho UART.
- Log trạng thái để debug nhanh khi tích hợp.
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
Kiến trúc module và luồng dữ liệu
Firmware nên tách thành các module Sensor, Filter, Protocol, Transport. Luồng dữ liệu rõ ràng giúp tránh phụ thuộc chéo và giảm lỗi khi thay cảm biến hoặc thay kênh truyền thông.
- Sensor module chỉ trả dữ liệu thô và trạng thái.
- Filter module xử lý theo cấu hình runtime.
- Protocol module đóng gói khung chuẩn.
Định thời lấy mẫu bằng timer
Timer tạo nhịp ổn định cho việc lấy mẫu, tránh phụ thuộc vào thời gian chạy vòng lặp chính. Tách nhịp lấy mẫu và nhịp truyền bản tin giúp hệ thống linh hoạt hơn khi tải tăng.
- Tick 10 ms cho lấy mẫu sensor.
- Gửi bản tin mỗi 100 ms để giảm băng thông.
- Giữ timestamp cho mỗi gói dữ liệu.
Giao thức UART dễ mở rộng
Khung bản tin nên có header, payload, checksum tối giản. Cấu trúc rõ giúp parser PC ổn định và dễ mở rộng thêm kênh dữ liệu sau này.
- Ví dụ khung: $S,adc,temp,ts*cs\n
- Checksum XOR đơn giản cho bài học cơ bản.
- Thêm mã lỗi sensor vào payload khi cần.
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
Tập trung vào phân tầng module: hardware driver, data processing, communication protocol.
- Thiết kế sơ đồ khối project và định nghĩa yêu cầu dữ liệu.
- Khởi tạo ADC đọc cảm biến theo timer tick.
- Áp dụng lọc trung bình cho dữ liệu thô.
- Đóng gói bản tin UART theo format chuẩn.
- Viết script PC nhận và hiển thị dữ liệu.
- Kiểm thử 30 phút liên tục và ghi log lỗi.
Ở 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ụ đóng gói khung dữ liệu UART
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.
typedef struct {
uint16_t adc_raw;
float temp_c;
uint32_t ts_ms;
} sensor_packet_t;
void Protocol_Send(const sensor_packet_t *p)
{
char msg[96];
snprintf(msg, sizeof(msg), "$S,%u,%.2f,%lu\n", p->adc_raw, p->temp_c, p->ts_ms);
HAL_UART_Transmit(&huart1, (uint8_t*)msg, strlen(msg), 50);
}
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õ.
- Không tách module nên code rối khi thêm chức năng.
- Lấy mẫu và truyền cùng chu kỳ gây nghẽn UART.
- Không có checksum nên khó phát hiện gói lỗi.
- Thiếu log timestamp làm khó truy vết lỗi.
- Không kiểm thử dài hạn nên bỏ sót lỗi tràn buffer.
Project tốt không chỉ chạy được mà còn phải dễ bảo trì và dễ mở rộng.
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ế.
- Thêm một cảm biến thứ hai và mở rộng format bản tin.
- Chuyển UART TX sang DMA để giảm tải CPU.
- Viết parser Python hiển thị biểu đồ realtime.
- Thiết kế test case tích hợp cho 60 phút chạy liên tục.
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.