![]() |
你这种相位差180度的输出,占空比一定要小于50%,否则就会有重叠,PWM会输不出来的。 |
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硬件移相程序可以参考: 配置代码
|
问题已经解决,换成pwm互补输出加死区调节的方式实现目标波形输出 |
可以用带PWM硬件移相功能的STC8H2K32U系列 |
从问题描述来看,你在24MHz时钟下尝试实现85kHz频率且占空比20%-40%的输出,但发现占空比设为50%时另一路信号在单周期内仅翻转一次,这可能与定时器计数机制及PWM生成逻辑有关。85kHz频率对应的周期约为11.76μs,24MHz时钟下每个计数周期为41.67ns,理论上定时器需计数约282次(24MHz/85kHz≈282.35)完成一个周期。若采用向上计数模式,占空比由比较值与周期值的比例决定,当比较值设为周期值一半(如141或142)时理论上应输出50%占空比,但实际出现异常,可能是定时器工作模式(如是否支持中心对齐PWM)或输出逻辑配置导致。 另一路信号单周期仅翻转一次,可能是因为该通道采用了不同的输出模式(如仅在计数到顶或底时翻转),或与主通道存在时序耦合。例如,若两路PWM共享定时器资源且配置为互补输出,当占空比设为50%时,可能因死区时间设置或输出极性配置导致信号翻转频率减半。此外,若定时器工作在向上/向下计数模式(中心对齐PWM),比较值设为周期值一半时应生成对称波形,但若配置为向上计数模式(边沿对齐PWM),50%占空比需精确设置比较值为周期值的一半,且需确保输出模式为“匹配时置位/清零”而非“翻转”模式,后者会导致每匹配一次翻转一次,使占空比固定为50%但频率减半。 要实现目标输出,可尝试以下方案:首先确认定时器工作模式及PWM生成方式,若使用边沿对齐PWM,确保周期值N与比较值C满足C=N×占空比(如20%占空比时C=0.2N),且输出模式配置为“匹配时清零/置位”而非翻转;若需50%占空比且频率不变,可改用中心对齐PWM模式,通过设置比较值为N/2来生成对称波形。此外,可独立配置两路PWM使用不同定时器资源,避免时序干扰,并通过示波器测量定时器计数寄存器与输出引脚的时序关系,定位比较值设置与输出翻转的实际对应关系,从而优化参数配置。 |
是不是输出叠加了,频率不一样 |
参考官方示例中带死区控制的PWM互补输出,控制死区时间即可达到图A-B的波形变化。 |