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.

TMS320F28035: ecap与epwm冲突问题

Part Number: TMS320F28035


主要是ecap模块的问题。

我想用f28035的ecap模块捕捉电网频率,ecap模块的配置参照官方例程:Example_2803xECap_Capture_Pwm来弄的,烧录后实测也成功捕捉到电网频率。

但是我把ecap函数添加进主函数后就捕捉不到了,后来一步步排除,发现把epwm模块

SetEPWM1(); // 初始化ePWM1

  SetEPWM2(); // 初始化ePWM2
注释掉后,ecap模块就可以正常工作了。

怀疑是epwm模块和ecap模块有什么不可言状的冲突,但是找了半天也没找到,希望官方人员帮忙解决问题。

谢谢。

另附代码如下:

void main(void)
 {

    InitSysCtrl();

//   SetGpio(); // Initialize GPIO
    InitEPwm1Gpio();
    InitEPwm2Gpio();

    InitECap1Gpio();

    DINT;

    InitPieCtrl();

    IER = 0x0000;
    IFR = 0x0000;

    InitPieVectTable();

    EALLOW;
    PieVectTable.EPWM1_INT = &epwm1_isr;
    PieVectTable.EPWM2_INT = &epwm2_isr;
    PieVectTable.ECAP1_INT = &ecap1_isr;
    PieVectTable.ADCINT1 = &adc_isr;
    EDIS;

    InitAdc();  // For this example, init the ADC
    AdcOffsetSelfCal();

    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0;  // 停止所有ePWM时钟
    EDIS;

    InitECapture1();        //Cap1功能初始化
    SetEPWM1();  // 初始化ePWM1
    SetEPWM2();  // 初始化ePWM2
    InitADC();       
    
    EALLOW;
    SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;  // 启动所有ePWM时钟
    EDIS;

    IER |= M_INT1+M_INT3+M_INT4;                     // Enable CPU Interrupt 1

    PieCtrlRegs.PIEIER1.bit.INTx1 = 1; // Enable INT 1.1 in the PIE
    PieCtrlRegs.PIEIER3.bit.INTx1 = 1;          //使能PWM1中断
    PieCtrlRegs.PIEIER3.bit.INTx2 = 1;          //使能PWM2中断
    PieCtrlRegs.PIEIER4.bit.INTx1 = 1;          //使能ECAP1中断

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

    LoopCount = 0;
    ConversionCount = 0;

    for(;;)
    {
        LoopCount++;

//        EPwm1Regs.CMPA.half.CMPA = (8.6 / ((Ud_REG[0] * 3.3 / 4095) / 0.04782)) * TB_PERIOD;
//        EPwm2Regs.CMPA.half.CMPA = (8.6 / ((Ud_REG[0] * 3.3 / 4095) / 0.04782)) * TB_PERIOD;
        EPwm2Regs.CMPA.half.CMPA = (2 * ((Voltage3[0] * 3.3 / 4095) * 59.64 + 82.59) + 3.5) / ((Ud_REG[0] * 3.3 / 4095) / 0.04782 * 26) * TB_PERIOD;    //110V使用
        EPwm1Regs.CMPA.half.CMPA = (2 * ((Voltage3[0] * 3.3 / 4095) * 59.64 + 82.59) + 3.5) / ((Ud_REG[0] * 3.3 / 4095) / 0.04782 * 26) * TB_PERIOD;    //110V使用
//        EPwm2Regs.CMPA.half.CMPA = (2 * ((Voltage3[0] * 3.3 / 4095) * 59.64 + 82.59) + 3.5) / ((Ud_REG[0] * 3.3 / 4095) / 0.04782 * 26) * TB_PERIOD;    //110V使用
//        EPwm1Regs.CMPA.half.CMPA = (2 * ((Voltage3[0] * 3.3 / 4095) * 59.64 + 82.59) + 3.5) / ((Ud_REG[0] * 3.3 / 4095) / 0.04782 * 52) * TB_PERIOD;    //220V使用
//        EPwm2Regs.CMPA.half.CMPA = (2 * ((Voltage3[0] * 3.3 / 4095) * 59.64 + 82.59) + 3.5) / ((Ud_REG[0] * 3.3 / 4095) / 0.04782 * 52) * TB_PERIOD;    //220V使用

//        nCAP1=ECap1Regs.CAP1;

    }

  • 但是我把ecap函数添加进主函数后就捕捉不到了,

    能描述一下捕捉不到的具体现象是什么吗?从程序的角度来说。

    个别eCAP引脚与ePWM引脚复用,需要注意一下。请看一下sprui10a_TMS320F2803x Microcontrollers Technical Reference Manual (Rev. A)1101.4.5 GPIO and Peripheral Multiplexing (MUX)

  • 我是用ecap来捕捉电网频率,单独的ecap程序能通过高低电平时间正确计算出电网频率,但是我把ecap程序添加进主函数后,高低电平时间是错误的,高低电平的读数不准确,因此无法正确计算出电网频率。

    只有当把epwm的程序注释掉后,ecap的读数才会恢复为正确的读数。因此我怀疑是否epwm和ecap的程序产生了冲突。


    另外epwm的程序用的是gpio0和gpio2,ecap用的是gpio19,应该不存在引脚复用的问题吧?

  • 我看了下您发的技术索引手册110页,发现gpio19对应的是GPAMUX2 Register Bits里的7-6,gpio3对应的同样GPAMUX1 Register Bits里的7-6。我使用了gpio19里的ecap1功能以及gpio3里的epwm2b功能,但是gpio19是MUX2,gpio3是MUX1呀,这会造成引脚复用吗?
    l

  • 我看了下您发的技术索引手册110页,发现gpio19对应的是GPAMUX2 Register Bits里的7-6,gpio3对应的同样GPAMUX1 Register Bits里的7-6。我使用了gpio19里的ecap1功能以及gpio3里的epwm2b功能,但是gpio19是MUX2,gpio3是MUX1呀,这会造成引脚复用吗?

    不会的。根据你的描述来看也是不会的。

    按照你的描述,

    工程可以正常工作-->添加eCAP后度数不准-->注释掉ePWM后正常,

    添加的程序以及注释的程序能大致描述一下吗?

    我建议你可以边添加程序边通过添加断点及单步运行的方式debug一下,看一下具体是哪一部分的代码导致问题产生。注释程序的过程可以通过同样的方式dubug。

  • 添加的程序是ecap1的配置模块和中断模块,代码如下:

    void InitECap1()
    {
       ECap1Regs.ECEINT.all = 0x0000;        // Disable all capture interrupts
       ECap1Regs.ECCLR.all = 0xFFFF;         // Clear all CAP interrupt flags
       ECap1Regs.ECCTL1.bit.CAPLDEN = 0;     // Disable CAP1-CAP4 register loads
       ECap1Regs.ECCTL2.bit.TSCTRSTOP = 0;   // Make sure the counter is stopped
    
       ECap1Regs.ECCTL2.bit.CONT_ONESHT = 1;  // One-shot
       ECap1Regs.ECCTL2.bit.STOP_WRAP = 3;    // Stop at 4 events
       ECap1Regs.ECCTL1.bit.CAP1POL = 1;      // Falling edge
       ECap1Regs.ECCTL1.bit.CAP2POL = 0;      // Rising edge
       ECap1Regs.ECCTL1.bit.CAP3POL = 1;      // Falling edge
       ECap1Regs.ECCTL1.bit.CAP4POL = 0;      // Rising edge
       ECap1Regs.ECCTL1.bit.CTRRST1 = 1;      // Difference operation
       ECap1Regs.ECCTL1.bit.CTRRST2 = 1;      // Difference operation
       ECap1Regs.ECCTL1.bit.CTRRST3 = 1;      // Difference operation
       ECap1Regs.ECCTL1.bit.CTRRST4 = 1;      // Difference operation
       ECap1Regs.ECCTL2.bit.SYNCI_EN = 1;     // Enable sync in
       ECap1Regs.ECCTL2.bit.SYNCO_SEL = 0;    // Pass through
       ECap1Regs.ECCTL1.bit.CAPLDEN = 1;      // Enable capture units
    
       ECap1Regs.ECCTL2.bit.TSCTRSTOP = 1;    // Start Counter
       ECap1Regs.ECCTL2.bit.REARM = 1;        // arm one-shot
       ECap1Regs.ECCTL1.bit.CAPLDEN = 1;      // Enable CAP1-CAP4 register loads
       ECap1Regs.ECEINT.bit.CEVT4 = 1;        // 4 events = interrupt
    }
    
    __interrupt void ecap1_isr(void)
    {
        nCAP1=(ECap1Regs.CAP1 + ECap1Regs.CAP2);
        nCAP2=(ECap1Regs.CAP3 + ECap1Regs.CAP4);
    
        Freq_Flag1=1;
    
        ECap1Regs.ECCLR.bit.CEVT4 = 1;
        ECap1Regs.ECCLR.bit.INT = 1;
        ECap1Regs.ECCTL2.bit.REARM = 1;
    
        PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
    }

    注释掉的程序是epwm1的配置模块,代码如下:

    void InitEPwm1(void)
    {
        EPwm1Regs.TBPRD = TB_PERIOD;
        EPwm1Regs.CMPA.half.CMPA = DUTY_VALUE;
        EPwm1Regs.TBPHS.half.TBPHS = 0; // Set Phase register to zero
        EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;       // Clock ratio to SYSCLKOUT
        EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
        EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; // Asymmetrical mode
        EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Master module
        EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
        EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
    
        EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
        EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
        EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO; // load on CTR=Zero
        EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO; // load on CTR=Zero
    
        EPwm1Regs.AQCTLA.bit.ZRO = AQ_SET; // set actions for EPwm3A
        EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
    //    EPwm1Regs.AQCTLA.bit.ZRO = AQ_CLEAR; // set actions for EPwm3A
    //    EPwm1Regs.AQCTLA.bit.CAU = AQ_SET;
    
        // Interrupt where we will change the Compare Values
        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 3rd event
    
        EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE; // enable Dead-band module
    
        EPwm1Regs.DBFED = DB_VALUE; // FED = 300 TBCLKs initially
        EPwm1Regs.DBRED = DB_VALUE; // RED = 300 TBCLKs initially
    
    }

    添加的ecap1配置和中断程序是跟着官方例程来的所以应该不会有问题,epwm1注释掉之后ecap1程序就正常了,所以我怀疑是epwm1程序的问题。

    您说的“边添加程序边通过添加断点及单步运行的方式debug一下”,我就是通过一步步添加程序来定位到是epwm1的问题的,另外单步运行是怎么操作的呢,这个没弄过。

    目前只知道应该是epwm1的问题,但是具体是什么问题什么原因,就不清楚,所以很卡进度 T T 

  • 您说的“边添加程序边通过添加断点及单步运行的方式debug一下”,我就是通过一步步添加程序来定位到是epwm1的问题的,另外单步运行是怎么操作的呢,这个没弄过。

    打了断点之后,debug按钮后面有单步运行的图标;

    我会看一下的。另外在几个硬件上发现了这个问题?有没有多换几个板子尝试一下?

    我在E2E上找到一个类似的问题:

    https://e2e.ti.com/support/microcontrollers/c2000-microcontrollers-group/c2000/f/c2000-microcontrollers-forum/1242794/launchxl-f28379d-influence-of-epwm-on-ecap-modules

    看起来问题似乎与那个客户的硬件有关系。因为我们的工程师试过之后是正常的,复现不了问题。

  • 链接里E2E上的问题跟我这个症状一致,只是芯片型号不同。

    我有一个板子,所以没有办法换板子验证问题。

    我完全是新手,我会在之后多试用断点单步运行的功能。

    目前的情况是我把epwm1换成epwm2,epwm2换成epwm3,这样调换的目的是避免使用epwm1,测试结果显示ecap功能正常,epwm在debug时占空比数值正常,但是还需要用示波器实测波形是否正确,涉及到硬件改线所以暂时无法完全验证代码。

    如果是问题原因来源于硬件,我会在有其它板子时尝试验证是否会发生同样问题。

  • 目前的情况是我把epwm1换成epwm2,epwm2换成epwm3,这样调换的目的是避免使用epwm1,测试结果显示ecap功能正常,

    看起来这个问题应该不是器件本身设计及原理上的问题。

    如果ePWM资源充足的话,就先不要使用ePWM1了。