This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

请教一个 28377S SPWM 波形莫名地周期性出现满占空比的问题

Other Parts Discussed in Thread: CONTROLSUITE

主时钟100MHz,经EPWMCLKDIV二分频,HSPCLKDIV二分频,CLKDIV二分频,相当于ePWM的TBCLK时钟为12.5MHz,使用查表法产生SPWM,然而在检查正弦表无误的情况下,波形有一定的瑕疵,周期性地出现满占空比的情况,如图(请忽略噪声尖峰的问题):

以前用MSP430做SPWM波形,也出现过这个问题,最后把定时器时钟设置得远远慢于主时钟才得以解决。MSP430功能不适合做SPWM,这也就算了,但是C2000应该不至于出现这种问题把?我以前用STM32,主时钟72MHz,定时器36MHz都不会出现这种满占空比的问题。请问这种情况该如何解决?或者官方有没有提供SPWM的源程序?在controlSUITE暂时没找到。

  • 满占空比的原因是因为你的表里的duty和周期值一样大了。和芯片本身没有关系。

  • 你这个看的不是很明显     没有表现是SPWM波的情况啊  

    我以前做看着效果很好   LC滤波输出效果很好

    我觉得应该是你的正弦波不太好吧

  • 所以我特别说了下,检查了正弦表数据无误,我把代码贴出来吧......

    #include "F28x_Project.h"

    unsigned int sinetable[]=
    {
    317,322,327,332,336,341,346,351,356,361,366,370,375,380,385,389,394,399,404,408,413,418,422,427,431,436,440,445,449,453,458,462,466,471,475,479,483,487,491,495,499,503,507,511,514,518,522,525,529,532,536,539,542,546,549,552,555,558,561,564,567,570,572,575,578,580,583,585,587,590,592,594,596,598,600,602,603,605,607,608,610,611,612,614,615,616,617,618,619,620,620,621,622,622,623,623,623,623,623,623,623,623,623,623,623,622,622,621,620,620,619,618,617,616,615,614,612,611,610,608,607,605,603,602,600,598,596,594,592,590,587,585,583,580,578,575,572,570,567,564,561,558,555,552,549,546,542,539,536,532,529,525,522,518,514,511,507,503,499,495,491,487,483,479,475,471,466,462,458,453,449,445,440,436,431,427,422,418,413,408,404,399,394,389,385,380,375,370,366,361,356,351,346,341,336,332,327,322,317,312,307,302,297,292,288,283,278,273,268,263,258,254,249,244,239,235,230,225,220,216,211,206,202,197,193,188,184,179,175,171,166,162,158,153,149,145,141,137,133,129,125,121,117,113,110,106,102,99,95,92,88,85,82,78,75,72,69,66,63,60,57,54,52,49,46,44,41,39,37,34,32,30,28,26,24,22,21,19,17,16,14,13,12,10,9,8,7,6,5,4,4,3,2,2,1,1,1,1,1,1,1,1,1,1,1,2,2,3,4,4,5,6,7,8,9,10,12,13,14,16,17,19,21,22,24,26,28,30,32,34,37,39,41,44,46,49,52,54,57,60,63,66,69,72,75,78,82,85,88,92,95,99,102,106,110,113,117,121,125,129,133,137,141,145,149,153,158,162,166,171,175,179,184,188,193,197,202,206,211,216,220,225,230,235,239,244,249,254,258,263,268,273,278,283,288,292,297,302,307,312

    };
    unsigned char i=0;

    void InitEPwm2Example(void);
    __interrupt void epwm2_isr(void);
    void update_compare();

    #define EPWM2_TIMER_TBPRD 624 // Period register
    #define EPWM_CMP_UP 1
    #define EPWM_CMP_DOWN 0

    void main(void)
    {
    InitSysCtrl();
    InitEPwm2Gpio();
    DINT;
    InitPieCtrl();
    IER = 0x0000;
    IFR = 0x0000;
    InitPieVectTable();

    EALLOW; // This is needed to write to EALLOW protected registers
    PieVectTable.EPWM2_INT = &epwm2_isr;
    EDIS; // This is needed to disable write to EALLOW protected registers

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =0;
    EDIS;

    InitEPwm2Example();

    EALLOW;
    CpuSysRegs.PCLKCR0.bit.TBCLKSYNC =1;
    EDIS;

    IER |= M_INT3;
    PieCtrlRegs.PIEIER3.bit.INTx2 = 1;

    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM

    for(;;)
    {

    }
    }

    __interrupt void epwm2_isr(void)
    {
    // Update the CMPA and CMPB values
    update_compare();
    // Clear INT flag for this timer
    EPwm2Regs.ETCLR.bit.INT = 1;
    // Acknowledge this interrupt to receive more interrupts from group 3
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
    }

    void InitEPwm2Example()
    {
    // Setup TBCLK
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
    EPwm2Regs.TBPRD = EPWM2_TIMER_TBPRD; // Set timer period
    EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
    EPwm2Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0
    EPwm2Regs.TBCTR = 0x0000; // Clear counter
    EPwm2Regs.TBCTL.bit.HSPCLKDIV =1;// TB_DIV2; // Clock ratio to SYSCLKOUT
    EPwm2Regs.TBCTL.bit.CLKDIV =1;// TB_DIV2;

    // Setup shadow register load on ZERO
    EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    // Set Compare values
    EPwm2Regs.CMPA.bit.CMPA = sinetable[i]; // Set compare A value
    EPwm2Regs.CMPB.bit.CMPB = sinetable[i]; // Set Compare B value

    // Set actions
    EPwm2Regs.AQCTLA.bit.PRD = AQ_CLEAR; // Clear PWM2A on Period
    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM2A on event A, up count

    EPwm2Regs.AQCTLB.bit.PRD = AQ_CLEAR; // Clear PWM2B on Period
    EPwm2Regs.AQCTLB.bit.CBU = AQ_SET; // Set PWM2B on event B, up count

    // Interrupt where we will change the Compare Values
    EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
    EPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INT
    EPwm2Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event

    }

    void update_compare()
    {
    EPwm2Regs.CMPA.bit.CMPA = sinetable[++i]; // Set compare A value
    EPwm2Regs.CMPB.bit.CMPB = sinetable[++i]; // Set Compare B value
    if(i>=400) i=0;
    }

  • 可否能分享一下代码呢?我的意思就是我产生的的SPWM波形会产生在明明不该出现满占空比的地方出现满占空比,而且确实不是正弦表的问题.....

  • 我把波形出错的地方标记出来了:

    三张图是依次放大的。我被这个问题困扰很久了,很希望能有人帮忙被解决下......

  • 你的计数模式配置有问题,一般SPWM都是增减计数,你没有设置,那默认是单增,周期应该Period寄存器值-1,所以在623时就会满值。你设置一下增减计数,然后改一下以下地方

    void InitEPwm2Example()
    {
    // Setup TBCLK
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
    EPwm2Regs.TBPRD = EPWM2_TIMER_TBPRD; // Set timer period
    EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
    EPwm2Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0
    EPwm2Regs.TBCTR = 0x0000; // Clear counter
    EPwm2Regs.TBCTL.bit.HSPCLKDIV =1;// TB_DIV2; // Clock ratio to SYSCLKOUT
    EPwm2Regs.TBCTL.bit.CLKDIV =1;// TB_DIV2;

    // Setup shadow register load on ZERO
    EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
    EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;

    // Set Compare values
    EPwm2Regs.CMPA.bit.CMPA = sinetable[i]; // Set compare A value
    EPwm2Regs.CMPB.bit.CMPB = sinetable[i]; // Set Compare B value

    // Set actions
    EPwm2Regs.AQCTLA.bit.CAD= AQ_CLEAR; // Clear PWM2A on Period
    EPwm2Regs.AQCTLA.bit.CAU = AQ_SET; // Set PWM2A on event A, up count

    EPwm2Regs.AQCTLB.bit.CBD= AQ_CLEAR; // Clear PWM2B on Period
    EPwm2Regs.AQCTLB.bit.CBU = AQ_SET; // Set PWM2B on event B, up count

    // Interrupt where we will change the Compare Values
    EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
    EPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INT
    EPwm2Regs.ETPS.bit.INTPRD = ET_3RD; // Generate INT on 3rd event

    }

  • 另外你可以不用CMPB,直接用CMAP然后输出到死区直接反向就可以了。

    更正一下,刚刚红色的地方,CAD和CAU的set 和clear还要反一下,

  • 谢谢你啊~~但是我照着你说的修改之后还是有这个问题,不过因为是增减计数,现在周期性出现错误满占空比的情况变成了出现50%占空比,如图:

    如果可以的话还是请发一份您写的SPWM程序吧....多谢了!

  • 你的周期值是不是改成原来的一倍了?按照你原来的CMPA值,肯定会有最中间的几个周期是满占空比的。因为如果是单增模式,

    TPWM = (TBPRD + 1) x TTBCLK

    如果是增减模式:TPWM = 2 x TBPRD x TTBCLK,所以你只要改成增减模式就可以。

    可以先固定CMPA=623看一下是不是满占空比

  •  先生您好,今天我调试,带软启动的电压闭环程序,为什么这样写程序不能实现,在按下开关后软启动程序先起作用,然后在开始PI运算的功能呢?麻烦您帮我看一下哪地方写的不合适?

    Uint16 Voltage1[10];
    Uint16 Voltage2[10];
    Uint16 ConversionCount;
    Uint16 count;//用以表示EPWM1INT中断开始工作
    Uint32 ss_count;
    Uint16 ss_flag;

    _iq U_Kp=_IQ(1),U_Ki=_IQ(0); //Ki=12000*Tsample Ki乘以采样周期定标
    _iq Ue0=0,Ue1=0,Ue2=0,Uref=0,Up=0,Ui=0,Uo0=0,Uo1=0,Uo2=0,Ureal=0;
    long U1,I1;
    long CA,CB;
    long temp1,temp2;
    int U_Ref= 265 ;


    void Init_Gpio(void) //初始化GPIO

    {
    EALLOW;
    GpioCtrlRegs.GPAMUX1.bit.GPIO4=1; //设置GPIO4口为EPWM3A波形输出引脚
    GpioCtrlRegs.GPADIR.bit.GPIO4=1; //设置GPIO4口方向为输出
    GpioCtrlRegs.GPAMUX1.bit.GPIO5=1; //设置GPIO5口为EPWM3B波形输出引脚
    GpioCtrlRegs.GPADIR.bit.GPIO5=1; //设置GPIO5口方向为输出

    GpioCtrlRegs.GPAMUX1.bit.GPIO10=01; //设置GPIO10口为EPWM6A波形输出引脚
    GpioCtrlRegs.GPADIR.bit.GPIO10=1; //设置GPIO10口方向为输出
    GpioCtrlRegs.GPAMUX1.bit.GPIO11=01; //设置GPIO11口为EPWM6B波形输出引脚
    GpioCtrlRegs.GPADIR.bit.GPIO11=1; //设置GPIO11口方向为输出

    GpioCtrlRegs.GPAMUX2.bit.GPIO17 = 0; // 0:GPIO 1:Peripheral
    GpioCtrlRegs.GPADIR.bit.GPIO17 = 1; // 0:Input 1:Output

    GpioCtrlRegs.GPAMUX2.bit.GPIO18 = 0; // 0:GPIO 1:Peripheral
    GpioCtrlRegs.GPADIR.bit.GPIO18 = 1; // 0:Input 1:Output


    GpioCtrlRegs.GPBMUX1.bit.GPIO34 = 0; // 0:GPIO 1:Peripheral
    GpioCtrlRegs.GPBDIR.bit.GPIO34 = 0; // 0:Input 1:Output
    GpioCtrlRegs.GPBCTRL.bit.QUALPRD0 = 1;//两个机器周期检测一次
    GpioCtrlRegs.GPBQSEL1.bit.GPIO34 = 2; //使用6次采样鉴定
    GpioCtrlRegs.GPAPUD.all = 0x0000; //上拉
    EDIS;
    }
    /*
    void GPIO0()
    {
    EALLOW;
    GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0; // Enable pullup on GPIO3(上拉电阻是做什么的?一般情况下都是会设置成使用上拉电阻模式)
    GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 0; // GPIO0 = GPIO0
    GpioCtrlRegs.GPADIR.bit.GPIO0 = 1; // GPIO0 = output
    EDIS;
    }

    void Init_Adc(void) //初始化ADC模块
    {
    EALLOW;
    AdcRegs.ADCCTL1.bit.ADCBGPWD = 1; // Power ADC BG ADCCTL1的位6 带隙上电
    AdcRegs.ADCCTL1.bit.ADCREFPWD = 1; // Power reference ADCCTL1的位5 参考上电
    AdcRegs.ADCCTL1.bit.ADCPWDN = 1; // Power ADC ADCCTL1的位7 Power up rest of ADC除带隙和参考上电以外的上电
    AdcRegs.ADCCTL1.bit.ADCENABLE = 1; // Enable ADC ADCCTL1的位14
    AdcRegs.ADCCTL1.bit.ADCREFSEL = 0; // Select interal BG 建议使用内部基准 内部基准一般就是指3.3v ( Digital Value = 4096 [(Input – VREFLO)/3.3v] when 0v < Input < 3.3v)


    DELAY_US(ADC_usDELAY);

    //选择序列采样模式
    AdcRegs.ADCSAMPLEMODE.bit.SIMULEN0=0; //SOC0和SOC1
    AdcRegs.ADCSAMPLEMODE.bit.SIMULEN2=0; //SOC2和SOC3
    AdcRegs.ADCSAMPLEMODE.bit.SIMULEN4=0; //SOC4和SOC5
    AdcRegs.ADCSAMPLEMODE.bit.SIMULEN6=0; //SOC6和SOC7


    AdcRegs.ADCSOC7CTL.bit.CHSEL = 7; //set SOC7 channel select to ADCINA7 SOC1选择ADCINA1通道 A1通道采U1 SOC1的结果存于ADCRETSULT1寄存器中


    AdcRegs.ADCSOC7CTL.bit.TRIGSEL = 9; // SOC7的触发源选择EPWM3A


    AdcRegs.ADCSOC7CTL.bit.ACQPS = 6; //set SOC7 S/H Window to 7 ADC Clock Cycles, (6 ACQPS plus 1) SOC1的采样窗口为7个周期长度

    EDIS;
    // Assumes ePWM1 clock is already enabled in InitSysCtrl();
    EPwm3Regs.ETSEL.bit.SOCAEN = 1; // Enable SOC on A group 使能ADC开始转换A(EPEMxSOCA)脉冲
    EPwm3Regs.ETSEL.bit.SOCASEL = 4; // Select SOC from from CPMA on upcount 使能事件,当定时器递增时时间基准计数器等于CMPA
    EPwm3Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event 在第一个件上生成ePWMxSOCA脉冲:ETPS[SOCACNT]=0,1

    }

    void Init_EPwm3(void)
    {
    // Initialization Timer
    EPwm3Regs.TBPRD = 300; // Period = 2*300 TBCLK counts
    EPwm3Regs.TBPHS. half.TBPHS= 0; // Set Phase register to zero
    EPwm3Regs.TBCTR = 0; // clear TB counter
    EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetric
    EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Phase loading disabled
    EPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW;
    EPwm3Regs.TBCTL.bit.SYNCOSEL = 00;
    EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
    EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = Zero
    EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR = Zero
    EPwm3Regs.AQCTLA.bit.ZRO = AQ_SET; // set actions for EPWM1A
    EPwm3Regs.AQCTLA.bit.PRD = AQ_CLEAR; //S1
    EPwm3Regs.AQCTLB.bit.ZRO = AQ_CLEAR;
    EPwm3Regs.AQCTLB.bit.PRD = AQ_SET; //S2
    //
    //Run Time
    // = = = = = = = = = = = = = = = = = = = = = = = =
    // EPwm1Regs.CMPA.half.CMPA = 360; // adjust duty for output EPWM1A
    // EPwm1Regs.CMPB=75; // adjust duty for output EPWM1B 移向45度
    EPwm3Regs.DBCTL.bit.OUT_MODE=DB_FULL_ENABLE; //11
    EPwm3Regs.DBCTL.bit.POLSEL=DB_ACTV_HIC; //10
    EPwm3Regs.DBCTL.bit.IN_MODE=00; //选Epwm1A为下降沿和上升沿延迟输入源
    EPwm3Regs.DBRED=30; //上升沿延迟时间
    EPwm3Regs.DBFED=30; //下降沿延迟时间

    EPwm3Regs.TZSEL.bit.OSHT1=1;
    EPwm3Regs.TZCTL.bit.TZA=TZ_FORCE_LO;
    EPwm3Regs.TZCTL.bit.TZB=TZ_FORCE_LO;

    //产生EPWM3INT3中断
    EPwm3Regs.ETSEL.bit.INTSEL=ET_CTR_ZERO; //当时基计数器等于0时产生EPWM3INT1中断
    EPwm3Regs.ETPS.bit.INTPRD =ET_3RD; //在第3个事件时产生中断
    EPwm3Regs.ETSEL.bit.INTEN=1; //EPWM1 INT中断使能


    }
    void Init_EPwm6(void) //初始化EPWM2 开关管S3,S4
    {
    // Initialization Timer
    EPwm6Regs.TBPRD = 300; // Period = 2*300 TBCLK counts
    EPwm6Regs.TBPHS. half.TBPHS= 0; // Set Phase register to zero
    EPwm6Regs.TBCTR = 0; // clear TB counter
    EPwm6Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Symmetric
    EPwm6Regs.TBCTL.bit.PHSEN = TB_ENABLE; // Phase loading disabled
    EPwm6Regs.TBCTL.bit.PRDLD = TB_SHADOW;
    EPwm6Regs.TBCTL.bit.SYNCOSEL = 00;
    EPwm6Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // TBCLK = SYSCLKOUT
    EPwm6Regs.TBCTL.bit.CLKDIV = TB_DIV1;
    EPwm6Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
    EPwm6Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
    EPwm6Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR = Zero
    EPwm6Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR = Zero
    EPwm6Regs.AQCTLA.bit.CAU = AQ_SET; // set actions for EPWM3A
    EPwm6Regs.AQCTLA.bit.CBD = AQ_CLEAR; //S5
    EPwm6Regs.AQCTLB.bit.CAU = AQ_CLEAR;
    EPwm6Regs.AQCTLB.bit.CBD = AQ_SET; //S6
    //
    //Run Time
    // = = = = = = = = = = = = = = = = = = = = = = = =
    //EPwm6Regs.CMPA.half.CMPA =0;
    //EPwm6Regs.CMPB=0;


    EPwm6Regs.DBCTL.bit.OUT_MODE=DB_FULL_ENABLE; //11
    EPwm6Regs.DBCTL.bit.POLSEL=DB_ACTV_HIC; //10
    EPwm6Regs.DBCTL.bit.IN_MODE=0; //选Epwm2A为下降沿和上升沿延迟输入源
    EPwm6Regs.DBRED=30; //上升沿延迟时间
    EPwm6Regs.DBFED=30; //下降延迟时间

    EPwm6Regs.TZSEL.bit.OSHT1=1;
    EPwm6Regs.TZCTL.bit.TZA=TZ_FORCE_LO;
    EPwm6Regs.TZCTL.bit.TZB=TZ_FORCE_LO;



    }

    void delay()
    {
    Uint16 i=0, j=0;
    for(i=0; i<1000; i++)
    for(j=0; j<10; j++);
    }

    void main(void)
    {

    InitSysCtrl();
    Init_Gpio();
    // For this case just init GPIO pins for ePWM1, ePWM2, and TZ1 pins


    DINT;
    InitPieCtrl(); // 初始化 PIE 控制寄存器
    IER = 0x0000; // 禁止 CPU 中断
    IFR = 0x0000; //清除 CPU 中断标志
    InitPieVectTable(); // 初始化 中断向量表

    EALLOW;
    PieVectTable.EPWM3_INT = &epwm3_isr;//&表示取地址,此句表示设置EPWM3_INT中断服务程序的入口地址为epwm1_isr

    EDIS;
    IER |= M_INT3;
    // Enable EPWM INT1 in the PIE: Group 3 interrupt 1,且使能group 1 interrupt 1
    PieCtrlRegs.PIEIER3.bit.INTx3 = 1;
    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;//停止每个已使能EPWM模块内的时基时钟(TBCLK)(默认状态)。

    EDIS; //但是,如果PCLKCR1寄存器的EPWM时钟使能位被置位,那么EPWM模块仍然由SYSCLKOUT来计时,即使TBCLKSYNC为0。

    delay();
    Init_Adc(); // For this example, init the ADC
    Init_EPwm3();
    Init_EPwm6();

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;//所有已使能的EPWM模块的时钟在已校准的TBCLK的第一个上升沿启动。为了得到完美同
    //步的TBCLK,每个EPWM模块的TBCLK寄存器中的预分频器位必须设置相同。使能EPWM时钟的正确过程如下所示:在PCLKCR1寄存器中
    //使能EPWM模块时钟;将TBCLKSYNC设置为0;配置预分频器值和EPWM模式;将TBCLKSYNC设置为1。
    EDIS;

    Restart_Begining:

    GpioDataRegs.GPADAT.bit.GPIO17 = 0;
    DELAY_US(10L);
    GpioDataRegs.GPADAT.bit.GPIO18 = 0;


    CA=0,CB=0;
    count=0;
    temp1=0;
    temp2=0;
    ss_count=0;
    ss_flag=0;
    EPwm6Regs.CMPA.half.CMPA =0;
    EPwm6Regs.CMPB=0;
    EALLOW;
    EPwm6Regs.TZFRC.bit.OST = 1;
    EPwm3Regs.TZFRC.bit.OST = 1;
    EDIS;


    //检测开关是否闭合,开始软启动
    while(1)
    {
    if(GpioDataRegs.GPBDAT.bit.GPIO34 == 0)
    {
    delay();
    if(GpioDataRegs.GPBDAT.bit.GPIO34 == 0) break;
    }
    }
    ss_flag = 1;


    EALLOW;
    EPwm3Regs.TZCLR.bit.OST = 1;
    EPwm6Regs.TZCLR.bit.OST = 1;
    EDIS;


    // Step 7. IDLE loop. Just sit and loop forever (optional):
    for(;;)
    {
    if(GpioDataRegs.GPBDAT.bit.GPIO34 == 1)
    {
    delay();
    if(GpioDataRegs.GPBDAT.bit.GPIO34 == 1)
    goto Restart_Begining;
    }


    }

    }


    interrupt void epwm3_isr(void)
    {


    if(ss_flag == 1)
    {
    if(ss_count<=307200)
    {
    ss_count++;
    temp1=(long)((ss_count)>>11);

    EPwm6Regs.CMPA.half.CMPA =300-temp1;
    EPwm6Regs.CMPB=temp1;

    }
    }


    U1= AdcResult.ADCRESULT7; //U1电压, A7通道采U1
    Voltage1[ConversionCount] = AdcResult.ADCRESULT7; //ADC的最近10次采样结果放在Voltage1数组中

    // If 10 conversions have been logged, start over
    if(ConversionCount == 9)
    {
    ConversionCount = 0;

    }
    else //AD采样值是经过10次求平均得到的

    {
    ConversionCount++;
    }


    //pi程序
    Ureal=_IQ(U1);

    Uref=_IQ(U_Ref); //300缩放为2.3,对应数字量为2855

    Ue1=Uref-Ureal ;

    Ue2=Ue1-Ue0; //两者的误差

    Up=_IQmpy(U_Kp,Ue2);

    Ui=_IQmpy(U_Ki,Ue1);

    Uo1=Uo0+Up+Ui;

    Ue0=Ue1;

    Uo0=Uo1;

    if(Uo1>=_IQ(EPwm3Regs.TBPRD*0.9)) Uo1 =_IQ(EPwm3Regs.TBPRD*0.9); // PI 输出上限幅

    if(Uo1<=_IQ(1)) Uo1 =_IQ(1); // PI 输出下限幅

    temp2=(long)((Uo1)>>18); //调制波得到数据

    if ( temp2>=270) { temp2=270; EPwm6Regs.CMPA.half.CMPA = temp2; EPwm6Regs.CMPB=300-temp2; }
    else if ( temp2<=0) { temp2=1; EPwm6Regs.CMPA.half.CMPA = temp2; EPwm6Regs.CMPB=300-temp2; } //设置移向角范围为0.6度到90

    CA=temp2;
    CB=300-temp2;
    EPwm6Regs.CMPA.half.CMPA =CA; //移向角
    EPwm6Regs.CMPB=CB;

    // I1= AdcResult.ADCRESULT0; //I1电压, A0通道采I1

    count++;
    GpioDataRegs.GPATOGGLE.bit.GPIO0=1;
    /*

    */
    GpioDataRegs.GPATOGGLE.bit.GPIO0=0;
    EPwm3Regs.ETCLR.bit.INT = 1; //清除EPWM1 INT的中断标志位
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;

    }

  • 对,改成增减模式后,只是把TBPRD改成了625,周期指确实相当于变成原来的一倍了,但是我出现满占空比的地方不是在那几个623的地方,二是在其他地方,正如图中一样,经查表,该是623的地方就是623,但是不该是623的地方也出现了满占空(增模式)或50%占空(增减模式)的情况,而不是对应出现正弦表中数值对应的占空比。其实如果能有2837x 的SPWM源程序供我参考研究下就最好了....

  • 你可以参考下以下例程,是一个单项DC/AC的功能。不是用查表法,是用TMU算的

    C:\TI\controlSUITE\development_kits\HV_1PH_DCAC

  • 谢谢啊,不过自己已经习惯查表法了,控制起来熟悉些,请问有查表法的例程吗?

  • f2837x的TMU很强大,速度不比查表的慢。所以没有查表法来做DC/AC的例程

  • 嗯嗯....我知道确实很厉害......但是现在还不太懂TMU,而且对查表法比较熟悉,调频调压也方便些....如果可以的话还是想请求一份查表法的例程.....谢谢啦