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.

TMS320F28335: 关于buck控制问题

Part Number: TMS320F28335
  1. 我同时启动ADC和epwm,并启动epwm的中断,但出来的波形占空比一直在90%,请问该怎么办,求大佬解惑
  • 波形的占空比跟ADC、ePWM中断是否启用没什么特别直接的关系啊。主要是看你CMPA、CMPB等等寄存器的设置。

    你可以看一下芯片TRM第247页开始的一些例子,里面讲了占空比控制

  • 显然是代码写错了,不如贴一下初始化EPWM的代码。

  • void EPWM1_Init(Uint16 tbprd)
    {
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Disable TBCLK within the ePWM
    SysCtrlRegs.PCLKCR1.bit.EPWM1ENCLK = 1; // ePWM1
    EDIS;

    // ePWM频率=TBCLK/(2*TBPRD)=150000000/(2*50000)

    // Interrupts that are used in this example are re-mapped to
    // ISR functions found within this file.
    EALLOW; // This is needed to write to EALLOW protected registers
    //PieVectTable.EPWM1_INT = &epwm1_timer_isr;
    EDIS; // This is needed to disable write to EALLOW protected registers

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Stop all the TB clocks
    EDIS;
    InitEPwm1Gpio();

    // Setup Sync
    EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through

    // Allow each timer to be sync'ed
    EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;// 失能关闭(如使能为将相依移位值装载到计数器)

    EPwm1Regs.TBPHS.half.TBPHS = 0;

    EPwm1Regs.TBPRD = tbprd;
    EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
    EPwm1Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;
    EPwm1Regs.TBCTL.bit.CLKDIV=TB_DIV1;
    // ePWM频率=TBCLK/(2*TBPRD)=150000000/(2*50000)
    EPwm1Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
    EPwm1Regs.ETSEL.bit.INTEN = 1; // Enable INT
    EPwm1Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event 在第一个事件中产生INT

    EPwm1Regs.CMPA.half.CMPA =375;
    EPwm1Regs.AQCTLA.bit.ZRO = AQ_CLEAR;//时基计数器的值等于0时输出低电平
    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;//向上计数时,时基计数器的值与cmpa寄存器的值相等不动作时输出高电平

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced 启动所有同步的定时器
    EDIS;

    // Enable CPU INT3 which is connected to EPWM1-6 INT: 启用与EPWM1-6 INT相连的CPU INT3。
    IER |= M_INT3;

    // Enable EPWM INTn in the PIE: Group 3 interrupt 1-6启用PIE中的EPWM INTn:第3组中断1-6
    PieCtrlRegs.PIEIER3.bit.INTx1 = 1;

    // Enable global Interrupts and higher priority real-time debug events:
    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM
    }
    void EPWM2_Init(Uint16 tbprd)
    {
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Disable TBCLK within the ePWM
    SysCtrlRegs.PCLKCR1.bit.EPWM2ENCLK = 1; // ePWM2
    EDIS;

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

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; // Stop all the TB clocks
    EDIS;
    InitEPwm2Gpio();

    // Setup Sync
    EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN; // Pass through

    EPwm2Regs.TBCTL.bit.PHSEN = TB_DISABLE;// 失能关闭(如使能为将相依移位值装载到计数器)

    EPwm2Regs.TBPHS.half.TBPHS = 0;

    EPwm2Regs.TBPRD = tbprd;
    EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Count up
    EPwm2Regs.TBCTL.bit.HSPCLKDIV=TB_DIV1;
    EPwm2Regs.TBCTL.bit.CLKDIV=TB_DIV1;
    EPwm2Regs.ETSEL.bit.INTSEL = ET_CTR_ZERO; // Select INT on Zero event
    EPwm2Regs.ETSEL.bit.INTEN = 1; // Enable INT
    EPwm2Regs.ETPS.bit.INTPRD = ET_1ST; // Generate INT on 1st event 在第一个事件中产生INT

    EPwm2Regs.CMPA.half.CMPA =0;
    EPwm2Regs.CMPB = 0;
    EPwm2Regs.AQCTLA.bit.ZRO = AQ_SET;//时基计数器的值等于0时输出高电平
    EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;//向上计数时,时基计数器的值与cmpa寄存器的值相等不动作时输出低电平


    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1; // Start all the timers synced 启动所有同步的定时器
    EDIS;

    // Enable CPU INT3 which is connected to EPWM1-6 INT: 启用与EPWM1-6 INT相连的CPU INT3。
    IER |= M_INT3;

    // Enable EPWM INTn in the PIE: Group 3 interrupt 1-6启用PIE中的EPWM INTn:第3组中断1-6
    PieCtrlRegs.PIEIER3.bit.INTx2 = 3;

    // Enable global Interrupts and higher priority real-time debug events:
    EINT; // Enable Global interrupt INTM
    ERTM; // Enable Global realtime interrupt DBGM
    }
    interrupt void epwm1_timer_isr(void)
    {
    Uint16 pwmval;
    result1=(AdcRegs.ADCRESULT3)>>4;
    t1=(float)result1*(3.3/4095); //转换成电压;
    PID1.sum_error+=(incPIDcalcu(&PID1,t1));
    pwmval=(Uint16)PID1.sum_error;
    EPWM1A_set(pwmval);

    /if(pwmval>=750) pwmval=750;
    if(pwmval<=300) pwmval=300;
    EPWM1A_set(pwmval);


    EPwm1Regs.CMPA.half.CMPA =pwmval;
    // Clear INT flag for this timer
    EPwm1Regs.ETCLR.bit.INT = 1;
    // Acknowledge this interrupt to receive more interrupts from group 3
    PieCtrlRegs.PIEACK.bit.ACK3 = 1;
    LED6_TOGGLE;
    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; //清楚排序器中断位
    asm (" ESTOP0");
    for(;;);
    }

  • 我现在解决了adc采样问题,但这个pwm还是不能用

  • /* interrupt void epwm2_timer_isr(void)
    {
    Uint16 pwmval;
    result2=(AdcRegs.ADCRESULT2)>>4;
    t2=(float)result2*(3.3/4095)*2.34; //转换成电流;

    // if(pwmval<=640)

    //电流环
    PID2.sum_error+=(incPIDcalcu(&PID2,t2));
    pwmval=(Uint16)PID2.sum_error;
    //pwm限幅处理
    if(pwmval>=6700) pwmval=6700; //720*32/36=640 最大输出32V
    if(pwmval<=2000) pwmval=2000; //720*10/36=200 最小输出10v 最小输出10v
    EPWM2A_set(pwmval);
    LED7_TOGGLE;
    // Clear INT flag for this timer
    EPwm2Regs.ETCLR.bit.INT = 1;
    // Acknowledge this interrupt to receive more interrupts from group 3
    PieCtrlRegs.PIEACK.bit.ACK3 = 1;
    AdcRegs.ADCST.bit.INT_SEQ1_CLR = 1; //清楚排序器中断位
    }*/
    void EPWM1A_set(Uint16 val)
    {
    EPwm1Regs.CMPA.half.CMPA = val;
    }

    void EPWM2A_set(Uint16 val)
    {
    EPwm2Regs.CMPA.half.CMPA = val;
    }
    void PID1init(void)
    {
    PID1.setpoint=0; //设定值
    PID1.sum_error=0; //误差累计
    PID1.proportion=0; //比例常熟
    PID1.integral=0; //积分常数
    PID1.differential =0; //微分常数

    PID1.error_1=0; //e(t-1)
    PID1.error_2=0; //e(t-2)

    void PID2init(void)
    {
    PID2.setpoint=0; //设定值
    PID2.sum_error=0; //误差累计
    PID2.proportion=0; //比例常数
    PID2.integral=0; //积分常数
    PID2.differential =0; //微分常数

    PID2.error_1=0; //e(t-1)
    PID2.error_2=0; //e(t-2)
    }

    float incPIDcalcu(PIDtypedef *PIDx,float present_point)
    {
    float ierror,incpid;
    ierror=PIDx->setpoint-present_point;
    //公式一
    // incpid=(PIDx->proportion+PIDx->integral+PIDx->differential) *ierror
    // -(PIDx->proportion+2*PIDx->differential) *(PIDx->error_1)
    // +(PIDx->differential)*(PIDx->error_2);
    //公式二
    incpid= (PIDx->proportion) *(ierror-(PIDx->error_1))
    +(PIDx->integral) *ierror
    +(PIDx->differential) *(ierror-2*(PIDx->error_1)+(PIDx->error_2));

    return (incpid);
    }
    void PID_set(PIDtypedef *PIDx,float Pp,float Ii,float Dd)
    {
    PIDx->proportion=Pp;
    PIDx->integral=Ii;
    PIDx->differential=Dd;
    }

  • 抱歉代码有点多,另外建议上传的时候用回复框里面的“插入” - “代码”,语言选择“C”或者“C++”,否则看起来太累了。

    我的理解,你是希望程序运行过程中实时得修改CMPx的值是吗?运行的时候有没有查看过对应寄存器的值有没有改变?

  • 抱歉,前几天一直再改代码,我已经知道了怎么去修改这个的值了,但新的问题又来了,首先是我的ADC采样电压虽然可以采到值,但因为PID运算问题导致pwm波形不能完全修改,我尝试改变CMPx的值却没有效果,但通过改变TBPRD的值可以修改我的pwm波,但就在刚刚,我的板子又出了点问题,谢谢您的解答。

  • 我的新问题是,采样值经过处理之后的没有值。。。。这令我十分疑惑,但首先我得处理我的板子,这是我的代码,谢谢您的帮助。

  • 最新的问题是:pid的算法问题,它好像完全没有处理