我想输出两路PWm,然后相位可调的,实现功能需要PWM输出几百毫秒再暂停,这样轮询输出。现在出现的问题是每次暂停再开始时使用中断的那个引脚会提前输出两个PWM波形。有没有大哥知道啥情况
`uchar mode=1;
#define MAIN_Fosc 11059200L //定义主时钟
uchar PWMB_ISR_En; //每个通道可以单独允许中断处理, bit4:通道4, bit3:通道3, bit2:通道2, bit1:通道1, bit0:更新中断.0000
#define PWMB_DUTY MAIN_Fosc/12/45 //周期45
#define PWMB_DUTY90 MAIN_Fosc/12/90 //周期90
//#define PWMB_DUTY MAIN_Fosc/12/90 //周期90
#define PWMB_PHASE2 (PWMB_DUTY/2) //通道2相位差
#define PWMB_PHASE290 (PWMB_DUTY90/360) //通道2相位差
uint pwmb1; //PWMB1(PWM5)输出高电平时间
uint pwmb2; //PWMB2(PWM6)输出高电平时间
uint pwmb3; //PWMB1(PWM5)输出高电平时间
uint pwmb4; //PWMB2(PWM6)输出高电平时间
bit B_OutState; //中断使用, 用户层不可见.
bit B_OutState2; //中断使用, 用户层不可见.
void PWMB_config(void)
{
uchar ccer1;
uchar ccer2;
uchar ps;
uchar eno;
P_SW2 |= 0x80; //SFR enable
PWMB_CCMR1 = 0x00; // 通道模式配置, 匹配模式1, 禁止预装载, 匹配时输出高
PWMB_CCMR2 = 0x00; // 通道模式配置, 匹配模式1, 禁止预装载, 匹配时输出高
PWMB_CCMR3 = 0x00; // 通道模式配置, 匹配模式1, 禁止预装载, 匹配时输出高
PWMB_CCMR4 = 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_CCMR3 = 0x68; // 通道模式配置, PWM模式1, 预装载允许
PWMB_CCR7 = pwmb3; // 比较值, 控制占空比(高电平时钟数)
ccer2 |= 0x05; // 开启比较输出, 高电平有效0x01
ps |= 0x20; // 选择IO, 0:选择P2.0, 1:选择P1.7, 2:选择P0.0, 3:选择P7.4,
eno |= 0x10; // IO输出允许, bit6: ENO8P, bit4: ENO7P, bit2: ENO6P, bit0: ENO5P
PWMB_CCMR4 = 0x40; // 通道模式配置, PWM模式1, 预装载允许
// PWMB_CCR8 = PWMB_PHASE2; // 比较值, 控制占空比(高电平时钟数)
PWMB_CCR8 = 0; // 比较值, 控制占空比(高电平时钟数)
ccer2 |= 0x50; // 开启比较输出, 高电平有效
ps |= 0x80; // 选择IO, 0:选择P2.0, 1:选择P1.7, 2:选择P0.0, 3:选择P7.4,
eno |= 0x40; // IO输出允许, bit6: ENO8P, bit4: ENO7P, bit2: ENO6P, bit0: ENO5P
PWMB_ISR_En |= 0x10; // 使能中断
//////////////////////////////////////
// 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 = 0; // 允许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
{
uchar sr1;
uchar sr2;
sr1 = PWMB_SR1; //为了快速, 中断标志用一个局部变量处理
PWMB_SR1 = 0; //清除中断标志
sr2 = PWMB_SR2; //为了快速, 中断标志用一个局部变量处理
PWMB_SR2 = 0; //清除中断标志
sr1 &= PWMB_ISR_En; //每个通道可以单独允许中断处理
sr2 &= PWMB_ISR_En; //每个通道可以单独允许中断处理
if(sr1 & 0x01) //更新中断标志
{
PWMB_CCR7 = pwmb3; // 匹配值
// if((mode == 3) || (mode == 6) || (mode == 9))PWMB_CCR8 = PWMB_PHASE290; // 匹配值
if((mode == 3) || (mode == 6) || (mode == 9))PWMB_CCR8 = pwmb3+10; // 匹配值
else PWMB_CCR8 = PWMB_PHASE2; // 匹配值
PWMB_CCMR4 = 0x70; // 通道模式配置, PWM模式2, 禁止预装载, 匹配时输出高
B_OutState2 = 0;
}
if(sr1 & 0x10) //通道2匹配中断标志
{
if(!B_OutState2)
{
B_OutState2 = 1;
PWMB_CCMR4 = 0x50; // 通道模式配置, 强制为有效电平
// if((mode == 3) || (mode == 6) || (mode == 9))PWMB_CCR8 = PWMB_PHASE290 + pwmb4; // 匹配值, PWM6在400时刻输出低电平
if((mode == 3) || (mode == 6) || (mode == 9))PWMB_CCR8 = pwmb3+pwmb4+10; // 匹配值, PWM6在400时刻输出低电平
else PWMB_CCR8 = PWMB_PHASE2 + pwmb4;
PWMB_CCMR4 = 0x60; // 通道模式配置, PWM模式1, 匹配时输出低电平
}
else PWMB_CCMR4 = 0x40; // 通道模式配置, 强制为无效电平
}
} `
void PWM_Mode()
{
if(power&&qiangdu&&time)
{
if((mode==1) || (mode==4) || (mode==7) || (mode==10))
{
PWMB_ENO =0X50;
pwmb3 =8+(qiangdu *5);
pwmb4 =8+(qiangdu *5);
}
else if((mode==2) || (mode==5) || (mode==8))
{
tim_pwm++;
if(tim_pwm >=1212)tim_pwm =0;
if(tim_pwm < 950)
{
PWMB_ENO =0X50;
pwmb3 =8+(qiangdu *5);
pwmb4 =8+(qiangdu *5);
}
else
{
PWMB_ENO =0;
P02 =0; P03 =0;
pwmb3 =0; pwmb4 =0;
}
}
else if((mode==3) || (mode==6) || (mode==9))
{
tim_pwm++;
if(tim_pwm >=600)tim_pwm =0;
if(tim_pwm < 251)
{
PWMB_ENO =0X50;
pwmb3 =8+(qiangdu *5);
pwmb4 =8+(qiangdu *5);
}
else
{
PWMB_ENO =0;
P02 =0; P03 =0;
pwmb3 =0; pwmb4 =0;
}
}
}
else
{
tim_pwm =0;
PWMB_ENO &=~0x50;
P02 =0; P03 =0;
pwmb3 =0; pwmb4 =0;
}
}
上面的是PWM配置,下面的是调用


图二是将图一前面多出来的波形放大看的,多出2个波形,占空比小的是固定占空比,占空比大的跟后面输出的占空比一样。