找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 187|回复: 6
打印 上一主题 下一主题
收起左侧

STC8H3K48S4的两路PWM相位差180度输出问题

[复制链接]
跳转到指定楼层
楼主




由官方代码修改,时钟为24MHZ,频率为85KHZ,不分频
实际在20-40%占空比为目标输出,但是占空比50时另一路在一个周期才会翻转一次
AB图为目标输出
求解惑为什么无法输出50%占空比,或者有无其他方法实现目标输出,求思

1.jpg (80.75 KB, 下载次数: 0)

1.jpg

2.jpg (34.37 KB, 下载次数: 0)

2.jpg

3.jpg (103.11 KB, 下载次数: 0)

3.jpg

4.jpg (78.17 KB, 下载次数: 0)

4.jpg

5.jpg (57.94 KB, 下载次数: 0)

5.jpg

6.jpg (220.15 KB, 下载次数: 0)

占空比50波形

占空比50波形

7.jpg (19.54 KB, 下载次数: 0)

目标输出

目标输出
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:1133081 发表于 2025-7-5 15:25 | 只看该作者
参考官方示例中带死区控制的PWM互补输出,控制死区时间即可达到图A-B的波形变化。
回复

使用道具 举报

板凳
ID:1089588 发表于 2025-7-5 17:20 | 只看该作者
是不是输出叠加了,频率不一样
回复

使用道具 举报

地板
ID:1137639 发表于 2025-7-6 08:13 | 只看该作者
从问题描述来看,你在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使用不同定时器资源,避免时序干扰,并通过示波器测量定时器计数寄存器与输出引脚的时序关系,定位比较值设置与输出翻转的实际对应关系,从而优化参数配置。
回复

使用道具 举报

5#
ID:1149771 发表于 2025-7-8 09:59 | 只看该作者
可以用带PWM硬件移相功能的STC8H2K32U系列
回复

使用道具 举报

6#
ID:1044977 发表于 2025-7-8 22:44 | 只看该作者
问题已经解决,换成pwm互补输出加死区调节的方式实现目标波形输出
回复

使用道具 举报

7#
ID:1149771 发表于 2025-7-9 10:05 | 只看该作者
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();




回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表