Bài viết 2 thuộc series STM32F103C8T6 tập trung theo hướng “học để làm được việc”. Với chủ đề Cấu trúc phần cứng STM32F103C8T6: CPU, Flash, SRAM, clock và ngoại vi, 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.
Khi hiểu cấu trúc phần cứng, bạn sẽ biết vì sao cùng một đoạn code nhưng hiệu năng có thể khác nhau rất nhiều giữa các cách cấu hình. Datasheet và RM0008 không chỉ để tra thông số, mà là bản đồ thiết kế firmware chuẩn.
1. Mục tiêu bài học
Bài tập trung vào mối quan hệ CPU - bộ nhớ - bus - clock - ngoại vi, từ đó giúp bạn chọn kiến trúc code phù hợp cho ứng dụng đo lường và điều khiển thời gian thực.
- Đọc được sơ đồ khối chip STM32F103C8T6 và định vị các ngoại vi chính.
- Hiểu cơ chế truy cập bộ nhớ và ảnh hưởng đến tối ưu firmware.
- Nắm cấu trúc clock tree để cấu hình hệ thống 72MHz ổn định.
- Liên hệ thông số phần cứng với quyết định thiết kế phần mềm.
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.
- Tổ chức pipeline và thanh ghi lõi Cortex-M3.
- Vai trò của Flash, SRAM và vector table trong quá trình boot.
- Bus AHB/APB và sự khác biệt băng thông giữa các miền.
- Tổng quan NVIC, DMA và ngoại vi truyền thông.
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
CPU Cortex-M3 và pipeline xử lý
Cortex-M3 hỗ trợ tập lệnh Thumb-2, ngắt nhanh và cơ chế ưu tiên ngắt linh hoạt. Với ứng dụng công nghiệp, điểm quan trọng nhất là bảo đảm interrupt latency ổn định và không để ISR chứa logic nặng.
- Dùng SysTick cho nhịp thời gian hệ thống.
- Giữ ISR ngắn, chuyển xử lý dài về main loop/task.
- Tách module driver để tránh phụ thuộc chéo.
Clock tree và miền ngoại vi
Clock tree quyết định trực tiếp tốc độ timer, UART, ADC. Nếu cấu hình APB1/APB2 không đúng, tần số ngoại vi sẽ lệch so với tính toán khiến giao tiếp lỗi hoặc PWM không đạt mục tiêu.
- Xác nhận nguồn HSI/HSE trước khi bật PLL.
- Kiểm tra lại clock thực bằng MCO hoặc logic analyzer.
- Tài liệu hóa công thức tính timer clock cho từng project.
Ngoại vi trọng yếu cho hệ điều khiển
GPIO, ADC, timer, USART, SPI, I2C, DMA và NVIC tạo thành bộ công cụ cốt lõi để xây mọi project nhúng. Cách phối hợp các ngoại vi này quyết định độ ổn định của vòng điều khiển và chất lượng dữ liệu đo.
- Ưu tiên cấu trúc driver có API rõ ràng.
- Thiết kế timeout cho mọi giao tiếp ngoài.
- Dự phòng cơ chế lỗi để hệ thống tự phục hồi.
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
Trước khi viết firmware dài, hãy kiểm tra sơ đồ clock, giới hạn bus và tần số ngoại vi. Đây là bước quan trọng để tránh lỗi “chạy được nhưng sai timing” khi tích hợp hệ thống.
- Đọc datasheet STM32F103x8/B và đánh dấu thông số cần cho project.
- Lập bảng tài nguyên: chân I/O, timer channel, UART, ADC channel.
- Thiết kế clock tree trong CubeMX, xác nhận các miền xung ngoại vi.
- Tạo firmware mẫu kiểm tra từng ngoại vi độc lập theo checklist.
- Tổng hợp kết quả test thành bản đồ phần cứng dùng cho cả nhóm.
- Khóa cấu hình chuẩn để giảm sai khác giữa các lần build.
Ở 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ụ kiểm tra clock hệ thống và bus
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.
void PrintClockInfo(void)
{
uint32_t sys = HAL_RCC_GetSysClockFreq();
uint32_t hclk = HAL_RCC_GetHCLKFreq();
uint32_t pclk1 = HAL_RCC_GetPCLK1Freq();
uint32_t pclk2 = HAL_RCC_GetPCLK2Freq();
printf("SYS=%lu HCLK=%lu PCLK1=%lu PCLK2=%lu\r\n", sys, hclk, pclk1, pclk2);
}
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õ.
- Nhầm timer clock khi APB prescaler > 1.
- Bật quá nhiều ngoại vi dù không dùng gây tăng tải hệ thống.
- Không khóa version CubeMX khiến cấu hình thay đổi giữa các máy.
- Không thống nhất naming pin/clock trong tài liệu dự án.
- Xem nhẹ kiểm thử timing nên lỗi chỉ xuất hiện khi chạy dài.
Luôn lưu một trang “hardware profile” cho từng project: clock, chân dùng, bus dùng, giới hạn tài nguyên.
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ế.
- Vẽ lại sơ đồ khối chip và chú thích miền clock của từng ngoại vi.
- So sánh hiệu năng khi chạy SYSCLK 36MHz và 72MHz.
- Thiết kế bảng mapping chân cho project đọc 4 cảm biến + 2 UART.
- Viết báo cáo ngắn giải thích vì sao nên dùng DMA cho luồng dữ liệu 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.