1、參考這個程序:15A-PWMB-2個相位差180度的PWM輸出P2口-匹配翻轉輸出
void main(void)
{
P_SW2 = 0x80;
/*
XOSCCR = 0xc0; //啟動外部晶振
while (!(XOSCCR & 1)); //等待時鐘穩定
CLKDIV = 0x00; //時鐘不分頻
CLKSEL = 0x01; //選擇外部晶振
*/
pwmb1 = 200; //通道1(PWM5)占空比
pwmb2 = 200; //通道2(PWM6)占空比
PWMB_config();
EA = 1;
while (1)
{
}
}
//========================================================================
// 函數: void PWMB_config(void)
// 描述: PWM配置函數。
// 參數: noe.
// 返回: none.
// 版本: V1.0, 2022-3-15
// 備注:
//========================================================================
void PWMB_config(void)
{
u8 ccer1;
u8 ccer2;
u8 ps;
u8 eno;
P_SW2 |= 0x80; //SFR enable
PWMB_CCMR1 = 0x00; // 通道模式配置, 匹配模式1, 禁止預裝載, 匹配時輸出高
PWMB_CCMR2 = 0x00; // 通道模式配置, 匹配模式1, 禁止預裝載, 匹配時輸出高
PWMB_ENO = 0; // IO輸出禁止
PWMB_IER = 0; // 禁止中斷
PWMB_SR1 = 0; // 清除狀態
PWMB_SR2 = 0; // 清除狀態
PWMB_CR1 = 0; // 清除控制寄存器
PWMB_CR2 = 0; // 清除控制寄存器
ccer1 = 0;
ccer2 = 0;
ps = 0;
eno = 0;
PWMB_ISR_En = 0;
PWMB_PSCR = 11; // 預分頻寄存器, PWM時鐘 = 12MHz/(11+1)=1MHz, 分頻 Fck_cnt = Fck_psc/(PSCR[15:0}+1), 邊沿對齊PWM頻率 = SYSclk/((PSCR+1)*(AAR+1)), 中央對齊PWM頻率 = SYSclk/((PSCR+1)*(AAR+1)*2).
PWMB_DTR = 0; // 死區寄存器, PWMB無效
PWMB_ARR = PWMB_DUTY-1; // 自動重裝載寄存器, 控制PWM周期
PWMB_ISR_En |= 0x01; // 使能更新中斷
PWMB_CCMR1 = 0x68; // 通道模式配置, PWM模式1, 預裝載允許
PWMB_CCR1 = pwmb1; // 比較值, 控制占空比(高電平時鐘數)
ccer1 |= 0x05; // 開啟比較輸出, 高電平有效
ps |= 0; // 選擇IO, 0:選擇P2.0, 1:選擇P1.7, 2:選擇P0.0, 3:選擇P7.4,
eno |= 0x01; // IO輸出允許, bit6: ENO8P, bit4: ENO7P, bit2: ENO6P, bit0: ENO5P
// PWMB_ISR_En |= 0x02; // 使能PWMB1(PWM5)中斷
PWMB_CCMR2 = 0x30; // 通道模式配置, 匹配模式3, 禁止預裝載, 匹配時取反輸出
PWMB_CCR2 = PWMB_PHASE2; // 匹配值
ccer1 |= 0x50; // 開啟比較輸出, 高電平有效
ps |= (0<<2); // 選擇IO, 0:選擇P2.1, 1:選擇P5.4, 2:選擇P0.1, 3:選擇P7.5
eno |= 0x04; // IO輸出允許, bit6: ENO8P, bit4: ENO7P, bit2: ENO6P, bit0: ENO5P
PWMB_ISR_En |= 0x04; // 使能PWMB2(PWM6)中斷
PWMB_CCER1 = ccer1; // 捕獲/比較使能寄存器1
PWMB_CCER2 = ccer2; // 捕獲/比較使能寄存器2
PWMB_PS = ps; // 選擇IO
PWMB_IER = PWMB_ISR_En; //設置允許通道1~4中斷處理
PWMB_BKR = 0x80; // 主輸出使能 相當于總開關
PWMB_CR1 = 0x81; // 使能計數器, 允許自動重裝載寄存器緩沖, 邊沿對齊模式, 向上計數, bit7=1:寫自動重裝載寄存器緩沖(本周期不會被打擾), =0:直接寫自動重裝載寄存器本(周期可能會亂掉)
PWMB_EGR = 0x01; //產生一次更新事件, 清除計數器和預分頻計數器, 裝載預分頻寄存器的值
PWMB_ENO = eno; // 允許IO輸出
}
// PWMB_PS = (0<<6)+(0<<4)+(0<<2)+0; //選擇IO, 4項從高到低(從左到右)對應PWM8 PWM7 PWM6 PWM5
// PWMB_PS PWM8 PWM7 PWM6 PWM5
// 00 P2.3 P2.2 P2.1 P2.0
// 01 P3.4 P3.3 P5.4 P1.7
// 02 P0.3 P0.2 P0.1 P0.0
// 03 P7.7 P7.6 P7.5 P7.4
//========================================================================
// 函數: void PWMB_ISR(void) interrupt PWMB_VECTOR
// 描述: PWMA中斷處理程序.
// 參數: None
// 返回: none.
// 版本: V1.0, 2021-6-1
//========================================================================
void PWMB_ISR(void) interrupt PWMB_VECTOR
{
u8 sr1;
// u8 sr2;
sr1 = PWMB_SR1; //為了快速, 中斷標志用一個局部變量處理
PWMB_SR1 = 0; //清除中斷標志
// sr2 = PWMB_SR2; //為了快速, 中斷標志用一個局部變量處理
PWMB_SR2 = 0; //清除中斷標志
sr1 &= PWMB_ISR_En; //每個通道可以單獨允許中斷處理
if(sr1 & 0x01) //更新中斷標志
{
PWMB_CCR2 = PWMB_PHASE2; // 通道2匹配值, 匹配時取反輸出
}
if(sr1 & 0x04) //通道2匹配中斷標志
{
PWMB_CCR2 = PWMB_PHASE2+pwmb2; // 通道2匹配值, 匹配時取反輸出
}
}
2、下面是STC8H2K系列PWM硬件移相程序可以參考:
配置代碼- PWMA_PSCRH = 0x00; //預分頻器
- PWMA_PSCRL = 0x00;
- PWM_PERIOD = 1000; //設置周期值
- PWMA_CCER1 = 0x00; //寫 CCMRx 前必須先清零 CCxE 關閉通道
- PWMA_CCER2 = 0x00;
- PWMA_CCMR1X = 0x00;//通道1:PWM1模式
- PWMA_CCMR1 = 0x60;
- PWMA_CCMR3X = 0x01;//通道3:組合PWM2模式
- PWMA_CCMR3 = 0x50;
- PWMA_CCMR4X = 0x00;//通道4:PWM1模式
- PWMA_CCMR4 = 0x60;
- PWMA_CCER1 = 0x55; //配置通道輸出使能和極性
- PWMA_CCER2 = 0x55;
- PWMA_ARRH = (u8)(PWM_PERIOD >> 8); //設置周期時間
- PWMA_ARRL = (u8)PWM_PERIOD;
- PWMA_ENO = 0x00;
- PWMA_ENO |= ENO1P; //使能輸出
主函數里的改變PWM的代碼
- if( dir==0 )
- {
- pul++;
- if( pul>=495 )
- dir =1;
- }
- else
- {
- pul--;
- if( pul<=5 )
- dir =0;
- }
- PWM_SET(pul);
- Delay3ms();
|