Vi điều khiển 328PB, nền tảng của bộ điều khiển GBRL, sở hữu khả năng tạo tín hiệu PWM 16 bit ở nhiều tần số khác nhau. Tuy nhiên, để khai thác tính năng này, cần hiểu rõ cách lập trình Pwm Register (thanh ghi PWM).
Sự phức tạp trong việc lập trình 328PB nằm ở cấu trúc đa hợp của nó. Việc thiếu hụt chân và thanh ghi cũng như vị trí đặt không thuận tiện của chúng gây khó khăn cho người dùng. Ví dụ, để truy cập chân PWM (Timer 3 hoặc 4), cần phải thay đổi cổng USB.
Bên trong vi điều khiển, việc chia sẻ và sử dụng chung các thanh ghi buộc người dùng phải lựa chọn cẩn thận các cổng xuất. Một thanh ghi có thể được dùng để tải giá trị PWM nhưng lại mất khả năng điều khiển đầu ra (ví dụ: OCR4A). Tính năng đa hợp này được mô tả khá phức tạp trong datasheet, dễ gây khó hiểu cho người dùng. Bài viết này sẽ giúp bạn hiểu rõ hơn về PWM register và cách thức hoạt động của nó.
Các chế độ PWM bao gồm: PWM chỉnh tần số, PWM chỉnh pha, PWM chỉnh cả tần số và pha, và PWM nhanh.
PWM chỉnh tần số và chỉnh pha đảm bảo tín hiệu đồng hồ và tín hiệu đầu ra hoàn chỉnh, không bỏ qua xung nhịp hoặc pha khi giá trị PWM thay đổi. Kỹ thuật dual slope (độ dốc kép) được sử dụng để đạt được điều này. Bộ đếm sẽ đếm lên và bật đầu ra tại một giá trị đặt trước. Sau khi đạt đến giá trị tối đa (TOP), bộ đếm sẽ đếm xuống và tắt đầu ra tại cùng giá trị đặt trước đó. Dual slope chính là quá trình đếm lên và đếm xuống cho một chu kỳ đầu ra. Điều này chia tín hiệu đồng hồ cho 2, do đó tất cả tần số PWM cho chế độ chỉnh tần số/pha bằng một nửa tần số tạo PWM độ dốc đơn. PWM nhanh chỉ sử dụng độ dốc đơn, tức là chỉ đếm lên đến giá trị TOP và khởi động lại. Tần số đầu ra PWM nhanh gấp đôi tần số PWM chỉnh tần số/pha.
Tần số PWM được tạo ra bởi bộ chia tần số đồng hồ, chia tần số CPU cho 1, 8, 64, 256 hoặc 1024 chu kỳ. Điều này cho phép thiết lập tần số PWM phù hợp với hệ thống nhận, ví dụ như nguồn cấp laser. Do mạch điều khiển đơn giản, hệ thống này chỉ chấp nhận dải tần số hẹp (60 đến 244 Hz).
Để hiểu rõ cách lập trình PWM register, cần xem xét sơ đồ khối thanh ghi dưới đây. Sơ đồ được chia thành ba cấu hình khác nhau, mỗi cấu hình sử dụng một nhóm PWM register cụ thể cho từng chế độ PWM.
Cấu hình thanh ghi so sánh PWM nhanh (COM4A1, giả sử COM4A0 = 0 lúc khởi tạo) được thể hiện trong hình bên dưới.
Cấu hình thanh ghi so sánh cho PWM chỉnh pha/tần số và PWM chỉnh cả pha và tần số (COM4A1, giả sử COM4A0 = 0) với WGM (Timer Number)3,2,1,0 (ví dụ: WGM43,42,41,40) được trình bày trong hai bảng sau:
Mã Gerbil đã triển khai điều khiển PWM register như thế nào? File CPU_map.h đã cấu hình sẵn các mặt nạ thanh ghi để lựa chọn chế độ mong muốn (cài đặt $28 trong Grbl). Giả sử sử dụng timer 4 với đầu ra PWM trên D1. Đoạn mã trong CPU_map.h định nghĩa các thanh ghi và chân điều khiển PWM:
#define SPINDLE_TCCRA_REGISTER TCCR4A // Sử dụng timer 4
#define SPINDLE_TCCRB_REGISTER TCCR4B // Sử dụng timer 4
#define SPINDLE_OCR_REGISTER OCR4A // Sử dụng timer 4 - giá trị PWM
#define SPINDLE_COMB_BIT COM4A1 // Sử dụng so sánh timer 4
Đoạn mã trong spindle_control.c khởi tạo và thiết lập chế độ PWM dựa trên giá trị pwm_mode
:
void spindle_init(uint8_t pwm_mode) {
SPINDLE_TCCRA_REGISTER = SPINDLE_TCCRA_INIT_MASK_1;
switch (pwm_mode) {
case 0:
SPINDLE_TCCRB_REGISTER = SPINDLE_TCCRB_INIT_MASK_A;
break;
case 1:
SPINDLE_TCCRB_REGISTER = SPINDLE_TCCRB_INIT_MASK_B;
break;
// ... Các case khác
}
}
Để đảm bảo giá trị PWM ở định dạng 16 bit, cần khai báo biến pwm_value
với kiểu dữ liệu uint16_t
.
uint16_t pwm_value; // Thay thế uint8_t bằng uint16_t