找回密码
 立即注册
查看: 146|回复: 5

请教高速高级(HSPWM)模式下怎么实现(频率-占空比)调节相位差180度PWM信号

[复制链接]
  • TA的每日心情
    开心
    前天 22:39
  • 签到天数: 2 天

    [LV.1]初来乍到

    6

    主题

    22

    回帖

    124

    积分

    注册会员

    积分
    124
    发表于 2024-4-6 23:53:03 | 显示全部楼层 |阅读模式
    本帖最后由 huiyong828 于 2024-4-6 23:55 编辑

    普通PWM模式下,可以正常输出波形
    代码如下:
    1. void        PWMA_config(void)
    2. {
    3.         u8        ccer1;
    4.         u8        ccer2;
    5.         u8        ps;
    6.         u8        eno;
    7.         
    8.         P2M0 = 0xff; P2M1 = 0x00;
    9.         P3M0 = 0x40; P3M1 = 0x00;
    10.         P27 = 0;
    11.         P36 = 0;
    12.         
    13.         P_SW2 |= 0x80;                //SFR enable
    14.         PWMA_ENO    = 0;        // IO输出禁止
    15.         PWMA_IER    = 0;        // 禁止中断
    16.         PWMA_SR1    = 0;        // 清除状态
    17.         PWMA_SR2    = 0;        // 清除状态
    18.         PWMA_CR1    = 0;        // 清除控制寄存器
    19.         PWMA_CR2    = 0;        // 清除控制寄存器
    20.         ccer1 = 0;
    21.         ccer2 = 0;
    22.         ps    = 0;
    23.         eno   = 0;
    24.         PWMA_ISR_En = 0;
    25.         PWMA_PSCRH = 0;                        // 预分频寄存器, 分频 Fck_cnt = Fck_psc/(PSCR[15:0}+1), 边沿对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)), 中央对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)*2).
    26.         PWMA_PSCRL = 5;                // 预分频, PWM时钟 = 12MHz/(11+1)=1MHz
    27.         PWMA_DTR   = 5;                        // 死区时间配置, n=0~127: DTR= n T,   0x80 ~(0x80+n), n=0~63: DTR=(64+n)*2T,
    28.                                                         //                                0xc0 ~(0xc0+n), n=0~31: DTR=(32+n)*8T,   0xE0 ~(0xE0+n), n=0~31: DTR=(32+n)*16T,
    29.         PWMA_ARRH    = (PWMA_PERIOD-1)/256;        // 自动重装载寄存器,  控制PWM周期
    30.         PWMA_ARRL    = (PWMA_PERIOD-1)%256;
    31.         PWMA_ISR_En |= 0x01;                // 使能更新中断
    32.         PWMA_CCMR1  = 0x68;                // 通道模式配置, PWM模式1, 预装载允许
    33.         PWMA_CCR1H  = pwma1/256;        // 比较值, 控制占空比(高电平时钟数)
    34.         PWMA_CCR1L  = pwma1%256;
    35.         ccer1 |= 0x0D;                        // 开启比较输出, 高电平有效    使能PWM1P  PWM1N
    36.         ps    |= 1;                                // 选择IO, 0:选择P1.0 P1.1, 1:选择P2.0 P2.1, 2:选择P6.0 P6.1,
    37.         eno   |= 0x03;                        // IO输出允许,  bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,  bit3: ENO2N,  bit2: ENO2P,  bit1: ENO1N,  bit0: ENO1P
    38. //        PWMA_ISR_En |= 0x02;        // 使能中断
    39.         PWMA_CCMR2 = 0x40;                // 强制输出低
    40.         PWMA_CCR2H = PWMA_PHASE2/256;        // 匹配值
    41.         PWMA_CCR2L = PWMA_PHASE2%256;
    42.         ccer1 |= 0xD0;                        // 开启比较输出, 高电平有效                        使能PWM2P  PWM2N
    43.         ps    |= (1<<2);                // 选择IO, 0:选择P1.2 P1.3, 1:选择P2.2 P2.3, 2:选择P6.2 P6.3,
    44.         eno   |= 0x0C;                        // IO输出允许,  bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,  bit3: ENO2N,  bit2: ENO2P,  bit1: ENO1N,  bit0: ENO1P
    45.         PWMA_ISR_En |= 0x04;        // 使能通道2匹配中断
    46.         PWMA_CCER1  = ccer1;        // 捕获/比较使能寄存器1
    47.         PWMA_CCER2  = ccer2;        // 捕获/比较使能寄存器2
    48.         PWMA_PS     = ps;                // 选择IO
    49.         PWMA_IER    = PWMA_ISR_En;        //设置允许通道1~4中断处理
    50.         PWMA_BKR    = 0x80;                // 主输出使能 相当于总开关
    51.         PWMA_CR1    = 0x81;                // 使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数,  bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)
    52.         PWMA_EGR    = 0x01;                //产生一次更新事件, 清除计数器和预分频计数器, 装载预分频寄存器的值
    53.         PWMA_ENO    = eno;                // 允许IO输出
    54.         PPWMA  = 1;        //PWMA中断设置为最高优先级为3,别的中断优先级都小于3
    55.         PPWMAH = 1;
    56. }
    复制代码
    截图202404062335446283.jpg

    截图202404062334103536.jpg
    上图波形正常。

    工程程序
    PWMA-四路2个相位差180度(PWM1P-PWM1N-PWM2P-PWM2N).rar (43.09 KB, 下载次数: 3)


    改为高速PWM模式,按照上述参数配置,运行不正常

    1. void HSPwmConfig(void)
    2. {
    3.         u8        ccer1;
    4.         u8        ccer2;
    5.         u8        ps;
    6.         u8        eno;
    7.         HSPWMA_CFG = 0x03;                        //使能PWMA相关寄存器异步访问功能
    8.         
    9.         //通过异步方式设置PWMA的相关寄存器
    10.         
    11. //        WritePWMA((u8)&PWMA_ENO, 0x00);                        // IO输出禁止
    12. //        WritePWMA((u8)&PWMA_IER, 0x00);                        // 禁止中断
    13. //        WritePWMA((u8)&PWMA_SR1, 0x00);                        // 清除状态
    14. //        WritePWMA((u8)&PWMA_SR2, 0x00);                        // 清除状态
    15. //        WritePWMA((u8)&PWMA_CR1, 0x00);                        // 清除控制寄存器
    16. //        WritePWMA((u8)&PWMA_CR2, 0x00);                        // 清除控制寄存器
    17.         
    18.         WritePWMA((u8)&PWMA_CCER1, 0x00);
    19.         WritePWMA((u8)&PWMA_CCER2, 0x00);
    20.         
    21.         ccer1 = 0;
    22.         ccer2 = 0;
    23.         ps    = 0;
    24.         eno   = 0;
    25.         PWMA_ISR_En = 0;
    26.         
    27. //        WritePWMA((u8)&PWMA_PSCRH, 0x00);                // 预分频寄存器, 分频 Fck_cnt = Fck_psc/(PSCR[15:0}+1), 边沿对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)), 中央对齐PWM频率 = SYSclk/((PSCR+1)*(AAR+1)*2).
    28. //        WritePWMA((u8)&PWMA_PSCRL, 5);                // 预分频, PWM时钟 = 12MHz/(11+1)=1MHz
    29.         WritePWMA((u8)&PWMA_DTR, 5);                        // 死区时间配置, n=0~127: DTR= n T,   0x80 ~(0x80+n), n=0~63: DTR=(64+n)*2T,
    30.                                                                                                                                                         //                                                        0xc0 ~(0xc0+n), n=0~31: DTR=(32+n)*8T,   0xE0 ~(0xE0+n), n=0~31: DTR=(32+n)*16T,        
    31.         WritePWMA((u8)&PWMA_ARRH, (PWMA_PERIOD-1)/256);                        // 自动重装载寄存器,  控制PWM周期
    32.         WritePWMA((u8)&PWMA_ARRL, (PWMA_PERIOD-1)%256);               
    33.         PWMA_ISR_En |= 0x01;                // 使能更新中断
    34.         
    35.         WritePWMA((u8)&PWMA_CCMR1, 0x68);                                        // 通道模式配置, PWM模式1, 预装载允许
    36.         WritePWMA((u8)&PWMA_CCR1H, (u8)(pwma1/256));        // 比较值, 控制占空比(高电平时钟数)        
    37.         WritePWMA((u8)&PWMA_CCR1L, (u8)(pwma1%256));        
    38.         ccer1 |= 0x0D;                        // 开启比较输出, 高电平有效    使能PWM1P  PWM1N
    39.         ps    |= 1;                                // 选择IO, 0:选择P1.0 P1.1, 1:选择P2.0 P2.1, 2:选择P6.0 P6.1,
    40.         eno   |= 0x03;                        // IO输出允许,  bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,  bit3: ENO2N,  bit2: ENO2P,  bit1: ENO1N,  bit0: ENO1P
    41.         //        PWMA_ISR_En |= 0x02;        // 使能中断
    42.                         
    43.         WritePWMA((u8)&PWMA_CCMR2, 0x40);                                        // 强制输出低
    44.         WritePWMA((u8)&PWMA_CCR2H, (u8)(PWMA_PHASE2/256));        //设置输出PWM的占空比
    45.         WritePWMA((u8)&PWMA_CCR2L, (u8)(PWMA_PHASE2%256));        
    46.         ccer1 |= 0xD0;                        // 开启比较输出, 高电平有效                        使能PWM2P  PWM2N
    47.         ps    |= (1<<2);                // 选择IO, 0:选择P1.2 P1.3, 1:选择P2.2 P2.3, 2:选择P6.2 P6.3,
    48.         eno   |= 0x0C;                        // IO输出允许,  bit7: ENO4N, bit6: ENO4P, bit5: ENO3N, bit4: ENO3P,  bit3: ENO2N,  bit2: ENO2P,  bit1: ENO1N,  bit0: ENO1P
    49.         PWMA_ISR_En |= 0x04;        // 使能通道2匹配中断
    50.         
    51.         WritePWMA((u8)&PWMA_CCER1, ccer1);                        // 捕获/比较使能寄存器1
    52.         WritePWMA((u8)&PWMA_CCER2, ccer2);                        // 捕获/比较使能寄存器2
    53.         PWMA_PS = ps;                                                                                                                // 选择IO               
    54.         
    55.         WritePWMA((u8)&PWMA_IER, PWMA_ISR_En);        //设置允许通道1~4中断处理
    56.         
    57.         WritePWMA((u8)&PWMA_BKR, 0x80);                                        //使能主输出
    58.         WritePWMA((u8)&PWMA_CR1, 0x81);                                        //使能计数器, 允许自动重装载寄存器缓冲, 边沿对齐模式, 向上计数,  bit7=1:写自动重装载寄存器缓冲(本周期不会被打扰), =0:直接写自动重装载寄存器本(周期可能会乱掉)
    59.         WritePWMA((u8)&PWMA_EGR, 0x01);                                        //产生一次更新事件, 清除计数器和预分频计数器, 装载预分频寄存器的值
    60.         WritePWMA((u8)&PWMA_ENO, eno);                                        // 允许IO输出
    61.         
    62. }
    复制代码


    1. void PWMA_ISR(void) interrupt PWMA_VECTOR
    2. {
    3. //        u8        sr2;
    4.         sr1 = ReadPWMA(&PWMA_SR1);        //为了快速, 中断标志用一个局部变量处理
    5.         
    6.         WritePWMA((u8)&PWMA_SR1, 0);
    7.         WritePWMA((u8)&PWMA_SR2, 0);
    8.         PWMA_SR2 = 0;
    9.         PWMA_SR1 = 0;
    10.         
    11. //        sr2 = PWMA_SR2;        //为了快速, 中断标志用一个局部变量处理
    12.         sr1 &= PWMA_ISR_En;        //每个通道可以单独允许中断处理
    13.         P36 = ~P36;                                //测试用
    14.         if(sr1 & 0x01)        //更新中断标志
    15.         {
    16.                
    17.                 WritePWMA((u8)&PWMA_CCR2H, (u8)(PWMA_PHASE2/256));        // 通道2匹配值
    18.                 WritePWMA((u8)&PWMA_CCR2L, (u8)(PWMA_PHASE2%256));        
    19.                 WritePWMA((u8)&PWMA_CCMR2, 0x70);                                                                                // 通道模式配置, PWM模式2, 禁止预装载, 匹配时输出高
    20.                 B_OutState = 0;
    21.         }
    22.         if(sr1 & 0x04)        //通道2匹配中断标志
    23.         {
    24.                 if(!B_OutState)
    25.                 {
    26.                         B_OutState = 1;
    27.                         WritePWMA((u8)&PWMA_CCMR2, 0x50);                                // 通道模式配置, 强制为有效电平        
    28.                         WritePWMA((u8)&PWMA_CCR2H, (u8)((PWMA_PHASE2+pwma1)/256));        // 通道2匹配值
    29.                         WritePWMA((u8)&PWMA_CCR2L, (u8)((PWMA_PHASE2+pwma1)%256));        
    30.                         WritePWMA((u8)&PWMA_CCMR2, 0x60);                                // 通道模式配置, PWM模式1, 匹配时输出低电平
    31.                 }
    32.                 else        WritePWMA((u8)&PWMA_CCMR2, 0x40);                // 通道模式配置, 强制为无效电平        
    33.         }
    34. }
    复制代码
    截图202404062343367037.jpg
    截图202404062346169960.jpg

    PWMA-四路2个相位差180度(PWM1P-PWM1N-PWM2P-PWM2N) - 高速PWM.rar

    65.91 KB, 下载次数: 4

    回复 送花

    使用道具 举报

  • TA的每日心情
    开心
    5 天前
  • 签到天数: 90 天

    [LV.6]常住居民II

    38

    主题

    986

    回帖

    6773

    积分

    荣誉版主

    冲哥视频教程和各种开源资料QQ交流群884047237,可群

    积分
    6773
    QQ
    发表于 2024-4-7 08:13:40 | 显示全部楼层
    频率比较高的时候建议直接用带硬件移相的芯片,例如STC8H2K17U
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    前天 22:39
  • 签到天数: 2 天

    [LV.1]初来乍到

    6

    主题

    22

    回帖

    124

    积分

    注册会员

    积分
    124
     楼主| 发表于 2024-4-7 08:22:48 来自手机 | 显示全部楼层
    本帖最后由 huiyong828 于 2024-4-7 08:24 编辑

    频率最高频率10-100KHz,现在用的是STC32G
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    2024-1-24 13:08
  • 签到天数: 1 天

    [LV.1]初来乍到

    8

    主题

    623

    回帖

    1034

    积分

    超级版主

    积分
    1034
    发表于 2024-4-7 10:10:24 | 显示全部楼层
    RMB0.99 的 USB, STC8H2K08U-45MHz-TSSOP20/SOP16,已开始供货
    51世界火热的夏天全面来临 全面 进入 USB 时代 !
    硬件USB 支持 仿真/下载, RTC 实时时钟, 年/月/日/时/分/秒
    真12位ADC, 144MHz-16位高级PWM新增硬件移相功能

    串口1/串口2:
    ===都支持串口接收硬件超时侦测
    ===都支持帧错误数据检测自动地址识别
    T11,强大的24位低功耗定时器/系统定时器,支持低功耗唤醒
    P1.2口在P5.4口上共享P1.0/P1.1的全部数字功能可以交换
    STC8H2K08U-45MHZ-TSSOP20/SOP16,USB, RMB 0.99
    PWM硬件移相的 I/O :PWMAPS5/P1.3, PWMAPS6/P1.5
    STC8H2K08U要让51成为永恒的经典:钻石恒久远51永流传


    【新提醒】0.99元USB-STC8H2K08U,144MHz-PWM硬件移相,51全面进入USB时代 - 第3页 - 51 发烧友,UAC,极致音频,大国工匠,艺术人生,乐林漫步 - 国芯论坛-STC全球32位8051爱好者互助交流社区 - STC全球32位8051爱好者互助交流社区  https://www.stcaimcu.com/forum.p ... amp;page=3#pid50750

    STC官网:https://www.stcai.com/
    QQ:2593903262
    微信号:18106296598
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    昨天 10:55
  • 签到天数: 131 天

    [LV.7]常住居民III

    26

    主题

    1297

    回帖

    4043

    积分

    论坛元老

    积分
    4043
    发表于 2024-4-7 10:20:28 | 显示全部楼层
    huiyong828 发表于 2024-4-7 08:22
    频率最高频率10-100KHz,现在用的是STC32G

    高速PWM输出频率太高导致调节速度跟不上。
    高速PWM使用异步模式配置寄存器,消耗的时间会更多一些。
    将PWM时钟调低一些试试,例如设置:
    HSCLKDIV = 8;
    回复 支持 反对 送花

    使用道具 举报

  • TA的每日心情
    开心
    前天 22:39
  • 签到天数: 2 天

    [LV.1]初来乍到

    6

    主题

    22

    回帖

    124

    积分

    注册会员

    积分
    124
     楼主| 发表于 2024-4-7 11:49:22 来自手机 | 显示全部楼层
    乘风飞扬 发表于 2024-4-7 10:20
    高速PWM输出频率太高导致调节速度跟不上。
    高速PWM使用异步模式配置寄存器,消耗的时间会更多一些。
    将PW ...

    是这个问题,因为开关频率需要在10KHz到100KHz调节,进入中断后处理异步模式寄存器操作复杂,芯片吃不消导致的问题
    回复 支持 反对 送花

    使用道具 举报

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

    本版积分规则

    QQ|手机版|深圳国芯人工智能有限公司 ( 粤ICP备2022108929号-2 )

    GMT+8, 2024-5-4 11:17 , Processed in 0.067890 second(s), 52 queries .

    Powered by Discuz! X3.5

    © 2001-2024 Discuz! Team.

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