晶片與時脈設定
- MCU:SH79F166A (12 MHz 晶振)
- PWM 時脈分頻:
PWM_DIVI2 (÷2) → 6 MHz
- 目標頻率:4 kHz → 週期值
V_PWMCYC = 1500 (6M/1500=4k)
- 占空比:50% → 脈衝寬度
V_PWM = 750
暫存器對照表
| 暫存器 | 功能 | 本範例設定 |
PWMLO | 鎖定/解鎖 PWM 群組 | 0x55 解鎖, 0xAA 鎖定 |
PWM0C | 控制暫存器 (分頻、極性等) | 0x00 | PWM_DIVI2 |
PWM0PL/PWM0PH | 週期低/高位元組 | 1500 & 0xFF, 1500 >> 8 |
PWM0DL/PWM0DH | 占空比低/高位元組 | 750 & 0xFF, 750 >> 8 |
PWM0DT | 死區時間 | 0 (無死區) |
PWMEN | PWM 模組總使能 | 0x01 (啟用 PWM0) |
PWMEN1 | 輸出腳位使能 | 0x01 (輸出到 IO), 0x00 (禁止) |
初始化函式
void Init_Pwm(void) {
PWMLO = 0x55; // 解鎖
PWM0C = 0x00 | PWM_DIVI2; // 6 MHz 時脈
PWM0PL = (uint8_t)(1500 & 0xFF); // 週期低位
PWM0PH = (uint8_t)(1500 >> 8); // 週期高位
PWM0DL = (uint8_t)(750 & 0xFF); // 占空比低位
PWM0DH = (uint8_t)(750 >> 8); // 占空比高位
PWM0DT = 0x00; // 無死區
PWMEN = 0x01; // 模組使能
PWMEN1 = 0x01; // 輸出使能 (對應腳位)
PWMLO = 0xAA; // 鎖定保護
}
主程式:週期性啟停輸出
void main(void) {
Init_Pwm(); // 4kHz, 50%
while (1) {
PWMEN1 = 0x01; // 輸出啟用
Delay(); // 延遲函式 (需自行實作)
PWMEN1 = 0x00; // 輸出禁止
Delay();
}
}
關鍵細節提醒
- PWMLO 解鎖/鎖定機制:修改 PWM 群組暫存器前必須寫 0x55 解鎖,修改完寫 0xAA 鎖定,防止誤觸發。
- 占空比計算:
Duty = PWM0D / PWM0P,若週期 1500、占空 750 則為 50%。
- 死區時間:雙邊對齊或互補輸出時需設定,單邊輸出通常設 0。
- 腳位複用:確認 PWM0 輸出腳位已在 GPIO 設定為複用功能。
擴展:動態調整占空比
void Set_Pwm_Duty(uint16_t duty) { // duty 0~1500
PWMLO = 0x55;
PWM0DL = (uint8_t)(duty & 0xFF);
PWM0DH = (uint8_t)(duty >> 8);
PWMLO = 0xAA;
}