您尚未登录。

楼主 # 2022-09-18 17:42:55

XMGroupe.
会员
注册时间: 2022-08-22
已发帖子: 12
积分: 237

[XMG助力国产]基于三角波调制的带死区的互补PWM

[XMG助力国产生态]
@XMGroupe.

本文介绍使用MC3172实现基于三角波调制的带死区的互补PWM产生方法。

常见的PWM调制方法有三种,即向上计数 向下计数 向上-向下计数,此demo使用向上向下计数,MC3172的PWM输出方法比较灵活,能够满足不同的需要,但是其每个timer只有四个compare让其使用存在一定局限,希望下一代能够增加到至少六个compare。

1.初始化
此demo使用timer3的P0和P1当作EPWM的P和N。

#define Dead_time   1000                //死区时间设置

void Pwm_Init(u32 timer_sel,u32 Arr,u32 Cmp)
{
    INTDEV_SET_CLK_RST(timer_sel,(INTDEV_RUN|INTDEV_IS_GROUP0|INTDEV_CLK_IS_CORECLK));

    TIMER_SET_OVERRIDE_GPIO(timer_sel,(TIMER_P3_OVERRIDE_GPIO|TIMER_P3_PULL_UP| \
                                        TIMER_P2_OVERRIDE_GPIO|TIMER_P2_PULL_UP| \
                                        TIMER_P1_OVERRIDE_GPIO|TIMER_P1_PULL_UP| \
                                        TIMER_P0_OVERRIDE_GPIO|TIMER_P0_PULL_UP) \
                           );

    TIMER_SET_OUTPUT_EN(timer_sel,(TIMER_P0_OUTPUT_ENABLE |TIMER_P1_OUTPUT_ENABLE |TIMER_P2_OUTPUT_ENABLE |TIMER_P3_OUTPUT_ENABLE| \
								));
    //分为四组,做两对互补
    TIMER_SET_OUT_PORT(timer_sel,(TIMER_P0_IS_COMPARER0|TIMER_P1_IS_COMPARER1| \
                                    TIMER_P2_IS_COMPARER2|TIMER_P3_IS_COMPARER3| \
									));

    TIMER_SET_COMPARER_MODE(timer_sel,(TIMER_COMPARER3_NOT_FORCE|TIMER_COMPARER2_NOT_FORCE|TIMER_COMPARER1_NOT_FORCE|TIMER_COMPARER0_NOT_FORCE));

    //下面四条用于控制频率
    TIMER_SET_MAIN_CNT_BEGIN_VALUE0(timer_sel,TIMER_MAIN_CNT_COUNT_UP,0);
    TIMER_SET_MAIN_CNT_END_VALUE0(timer_sel,Arr);
    TIMER_SET_MAIN_CNT_BEGIN_VALUE1(timer_sel,TIMER_MAIN_CNT_COUNT_DOWN,Arr);
    TIMER_SET_MAIN_CNT_END_VALUE1(timer_sel,0);

    TIMER_SET_CMD(timer_sel,TIMER_CMD_RESTART);

    TIMER_SET_COMPARER0_VALUE0_0(timer_sel,TIMER_COMPARER_OUTPUT1,0x00);
    TIMER_SET_COMPARER0_VALUE0_1(timer_sel,TIMER_COMPARER_OUTPUT0,(Cmp-Dead_time));
    TIMER_SET_COMPARER0_VALUE1_0(timer_sel,TIMER_COMPARER_OUTPUT1,(Cmp-Dead_time));
    TIMER_SET_COMPARER0_VALUE1_1(timer_sel,TIMER_COMPARER_OUTPUT0,0x00);

    TIMER_SET_COMPARER1_VALUE0_0(timer_sel,TIMER_COMPARER_OUTPUT0,0x00);
    TIMER_SET_COMPARER1_VALUE0_1(timer_sel,TIMER_COMPARER_OUTPUT1,(Cmp+Dead_time));
    TIMER_SET_COMPARER1_VALUE1_0(timer_sel,TIMER_COMPARER_OUTPUT0,(Cmp+Dead_time));
    TIMER_SET_COMPARER1_VALUE1_1(timer_sel,TIMER_COMPARER_OUTPUT1,0x00);

    TIMER_SET_CMD(timer_sel,TIMER_CMD_RUN);
}

需要注意,采用向上-向下计数方法,其PWM频率为 系统频率/ARR/2,因此死区时间为 Dead_time * (2/系统频率)
此实验采用200M外部有源晶振,因此demo的PWM频率为100 000 000/ARR,死区时间为 1000*10ns = 10us(正常不需要这么大,此处为了验证EPWM在大占空比时能否实现强制输出)。

2.占空比修改函数

void Set_PWM_Duty(u32 timer_sel,u32 Arr,float Duty1)
{
    static u8 flag_set = 0;
    static float Duty_old = 0.0;
    static u32 Compare_old = 0;
    static u32 Cmp = 0;
    u32 CNT = 0;
    u8 RP = 0;

    if(Duty_old != Duty1)
    {
        Duty_old = Duty1;
        Cmp = (u32)(Duty1*Arr);
        flag_set = 0x80;        //最高位置1,开启修改占空比
    }
    if((flag_set & 0x80) != 0)      //判断最高位
    {
        if((Cmp > Dead_time)&&((Arr - Cmp) > Dead_time))     //P、N脚正常输出
        {
            TIMER_SET_COMPARER_MODE(timer_sel,(TIMER_COMPARER3_NOT_FORCE|TIMER_COMPARER2_NOT_FORCE| \
                    TIMER_COMPARER1_NOT_FORCE|TIMER_COMPARER0_NOT_FORCE));
        }
        else if(Cmp <= Dead_time)                            //P脚关闭输出
        {
            TIMER_SET_COMPARER_MODE(timer_sel,(TIMER_COMPARER3_NOT_FORCE|TIMER_COMPARER2_NOT_FORCE| \
                                TIMER_COMPARER1_NOT_FORCE|TIMER_COMPARER0_FORCE0));
        }
        else if(((Arr - Cmp) <= Dead_time))                  //N脚关闭输出
        {
            TIMER_SET_COMPARER_MODE(timer_sel,(TIMER_COMPARER3_NOT_FORCE|TIMER_COMPARER2_NOT_FORCE| \
                                TIMER_COMPARER1_FORCE0|TIMER_COMPARER0_NOT_FORCE));
        }

        TIMER_GET_MAIN_CNT_ALL(timer_sel,CNT,RP);
        if(RP == 1)         //不在规则区0,修改规则区0
        {
            if(flag_set == 0x80)   //第一次修改
            {
                flag_set = 0x81;   //修改标志位,规则0 次序1
                //compare0
                TIMER_SET_COMPARER0_VALUE0_0(timer_sel,TIMER_COMPARER_OUTPUT1,0x00);
                TIMER_SET_COMPARER0_VALUE0_1(timer_sel,TIMER_COMPARER_OUTPUT0,(Cmp-Dead_time));
                //compare1
                TIMER_SET_COMPARER1_VALUE0_0(timer_sel,TIMER_COMPARER_OUTPUT0,0x00);
                TIMER_SET_COMPARER1_VALUE0_1(timer_sel,TIMER_COMPARER_OUTPUT1,(Cmp+Dead_time));
            }
            else if(flag_set == 0x82)      //第二修改
            {
                flag_set = 0;   //修改标志位
                //compare0
                TIMER_SET_COMPARER0_VALUE0_0(timer_sel,TIMER_COMPARER_OUTPUT1,0x00);
                TIMER_SET_COMPARER0_VALUE0_1(timer_sel,TIMER_COMPARER_OUTPUT0,(Cmp-Dead_time));
                //compare1
                TIMER_SET_COMPARER1_VALUE0_0(timer_sel,TIMER_COMPARER_OUTPUT0,0x00);
                TIMER_SET_COMPARER1_VALUE0_1(timer_sel,TIMER_COMPARER_OUTPUT1,(Cmp+Dead_time));
            }
        }
        //修改规则1区
        else
        {
            if(flag_set == 0x80)   //第一修改
            {
                flag_set = 0x82;   //修改标志位,规则1 次序1
                //compare0
                TIMER_SET_COMPARER0_VALUE1_0(timer_sel,TIMER_COMPARER_OUTPUT1,(Cmp-Dead_time));
                TIMER_SET_COMPARER0_VALUE1_1(timer_sel,TIMER_COMPARER_OUTPUT0,0x00);
                //compare1
                TIMER_SET_COMPARER1_VALUE1_0(timer_sel,TIMER_COMPARER_OUTPUT0,(Cmp+Dead_time));
                TIMER_SET_COMPARER1_VALUE1_1(timer_sel,TIMER_COMPARER_OUTPUT1,0x00);
            }
            else if(flag_set == 0x81)      //第二修改,修改结束
            {
                flag_set = 0;   //修改标志位
                //compare0
                TIMER_SET_COMPARER0_VALUE1_0(timer_sel,TIMER_COMPARER_OUTPUT1,(Cmp-Dead_time));
                TIMER_SET_COMPARER0_VALUE1_1(timer_sel,TIMER_COMPARER_OUTPUT0,0x00);
                //compare1
                TIMER_SET_COMPARER1_VALUE1_0(timer_sel,TIMER_COMPARER_OUTPUT0,(Cmp+Dead_time));
                TIMER_SET_COMPARER1_VALUE1_1(timer_sel,TIMER_COMPARER_OUTPUT1,0x00);
            }
        }
    }
}

上面的函数实现了EPWM的占空比设置和死区校验,防止出现占空比寄存数大于死区时间时输出高电平的现象。

3.输出PWM
输出的PWM如下图所示
Snipaste_2022-09-18_17-40-36.jpg
在其占空比较小时,其输出电平被强制输出为低电平
Snipaste_2022-09-18_17-40-44.jpg

离线

#1 2022-09-18 21:05:50

support_gxchip
Moderator
注册时间: 2022-07-26
已发帖子: 58
积分: 103

Re: [XMG助力国产]基于三角波调制的带死区的互补PWM

大佬真是啥都会

离线

页脚

工信部备案:粤ICP备20025096号 Powered by FluxBB

感谢为中文互联网持续输出优质内容的各位老铁们。 QQ: 516333132, 微信(wechat): whycan_cn (哇酷网/挖坑网/填坑网) service@whycan.cn