Bài viết 7 thuộc series STM32F103C8T6 tập trung theo hướng “học để làm được việc”. Với chủ đề PWM trên STM32F103C8T6: điều khiển độ sáng LED và tốc độ động cơ DC, 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.

PWM là kỹ thuật cốt lõi trong điều khiển công suất thấp và trung bình. Từ làm mờ LED đến điều tốc motor DC, việc chọn tần số và duty cycle đúng ảnh hưởng trực tiếp đến chất lượng hệ thống.

PWM điều khiển LED và động cơ
Minh họa cho bài 7: PWM trên STM32F103C8T6: điều khiển độ sáng LED và tốc độ động cơ DC.

1. Mục tiêu bài học

Bài hướng tới khả năng thiết kế PWM có chủ đích: đúng tần số cho từng tải, đúng dải điều khiển và đúng chiến lược lọc nhiễu.

  • Hiểu bản chất PWM và mối quan hệ duty cycle - công suất.
  • Cấu hình timer PWM mode bằng HAL.
  • Điều khiển mượt LED và động cơ DC qua driver ngoài.
  • Đánh giá nhiễu và chọn tần số PWM phù hợp ứng dụ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.

  • Tần số PWM ảnh hưởng thị giác và âm thanh động cơ.
  • Duty cycle phần trăm và giá trị compare trong timer.
  • Vai trò driver công suất như L298N trong cách ly tải.
  • Nguyên tắc cấp nguồn riêng cho tải công suất.

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 tần số PWM và dải duty

PWM frequency phụ thuộc clock timer, prescaler và ARR. Chọn ARR lớn cho độ phân giải duty tốt hơn, nhưng cần cân bằng với giới hạn tần số yêu cầu của tải để tránh rung hoặc tiếng ồn khó chịu.

  • LED thường dùng tần số vài trăm Hz đến vài kHz.
  • Motor DC có thể cần dải cao hơn để giảm tiếng rít.
  • Kiểm tra độ mượt khi thay đổi duty theo bước nhỏ.

PWM cho LED và cảm nhận thị giác

Dù duty tăng tuyến tính, độ sáng cảm nhận của mắt người không tuyến tính. Vì vậy có thể cần bảng gamma hoặc ánh xạ phi tuyến để hiệu ứng fade tự nhiên hơn trong ứng dụng giao diện.

  • Tạo bảng LUT duty để hiệu chỉnh độ sáng.
  • Dùng timer interrupt hoặc DMA cho hiệu ứng mượt.
  • Giữ code hiệu ứng tách khỏi driver PWM.

PWM cho động cơ DC qua L298N

L298N đơn giản và phổ biến nhưng có sụt áp tương đối lớn. Khi điều tốc, cần xét thêm quán tính cơ học và giới hạn dòng tải để tránh nóng driver hoặc sụt nguồn MCU gây reset.

  • PWM đặt vào chân EN của driver.
  • Chân IN1/IN2 điều khiển chiều quay motor.
  • Bổ sung tụ lọc nguồn gần driver và MCU.

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

Với motor DC, cần kiểm tra đồng thời nguồn, driver và tín hiệu PWM; không nên debug phần mềm khi phần cứng công suất chưa ổn.

  1. Cấu hình timer ở PWM mode với tần số mục tiêu.
  2. Map chân PWM đúng alternate function trên STM32F103C8T6.
  3. Viết API set_duty(percent) và kiểm tra giới hạn đầu vào.
  4. Test fade LED để đánh giá độ phân giải duty.
  5. Kết nối L298N, điều chỉnh duty theo biến trở hoặc UART command.
  6. Đo nhiệt driver và độ ổn định nguồn khi tải cao.

Ở 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ụ API đặt duty cycle cho TIM3 CH1

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 PWM_SetDuty(uint8_t duty_percent)
{
    if (duty_percent > 100) duty_percent = 100;
    uint32_t arr = __HAL_TIM_GET_AUTORELOAD(&htim3);
    uint32_t ccr = (arr * duty_percent) / 100;
    __HAL_TIM_SET_COMPARE(&htim3, TIM_CHANNEL_1, ccr);
}

// Khởi động PWM
HAL_TIM_PWM_Start(&htim3, TIM_CHANNEL_1);
PWM_SetDuty(45);

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 tần số PWM quá thấp gây nhấp nháy LED hoặc rung motor.
  • Không giới hạn duty đầu vào làm compare vượt ARR.
  • Dùng chung nguồn không đủ dòng cho MCU và motor.
  • Không thêm lọc nhiễu gây reset ngẫu nhiên khi tải đổi nhanh.
  • Quên cấu hình alternate function cho chân PWM.

Luôn tách lớp “set duty” và lớp “điều khiển mục tiêu” để dễ nâng cấp lên PID sau này.

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ế.

  1. Tạo hiệu ứng breathing LED có gamma correction.
  2. Điều khiển tốc độ motor theo lệnh UART dạng phần trăm duty.
  3. Viết ramp tăng/giảm duty mềm để tránh giật cơ khí.
  4. So sánh chất lượng điều khiển khi dùng 2 mức tần số PWM khác nhau.

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.