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.

TMS320F28377D 的ECAP 模块 测试方波的频率和占空比

Other Parts Discussed in Thread: C2000WARE

在程序中试过两种方式,连续的和 one-short ,连续的得不到正确的结果,one-short可以,但是只能进入中断 函数一次,后续Ecap reg 就不在捕获寄存器了,代码如下

void ECaptureConfig(volatile struct ECAP_REGS *reg)
{
    reg-> ECEINT.all = 0x0000;             // Disable all capture __interrupts
    reg-> ECCLR.all = 0xFFFF;              // Clear all CAP __interrupt flags
    reg-> ECCTL1.bit.CAPLDEN = 0;          // Disable CAP1-CAP4 register loads
    reg-> ECCTL2.bit.TSCTRSTOP = 0;        // Make sure the counter is stopped

   // Configure peripheral registers
//    reg-> ECCTL1.bit.FREE_SOFT =2;//free run
    reg-> ECCTL2.bit.CONT_ONESHT = 1;      // One-shot
    reg-> ECCTL2.bit.STOP_WRAP = 3;        // Stop at 4 events
    reg-> ECCTL1.bit.CAP1POL = EC_RISING;    // Falling edge
    reg-> ECCTL1.bit.CAP2POL = EC_FALLING;    //1= Rising edge
    reg-> ECCTL1.bit.CAP3POL = EC_RISING;    //0= Falling edge
    reg-> ECCTL1.bit.CAP4POL = EC_FALLING;    // Rising edge
    reg-> ECCTL1.bit.CTRRST1 = 0;   // Difference operation
    reg-> ECCTL1.bit.CTRRST2 = 0;   // Difference operation
    reg-> ECCTL1.bit.CTRRST3 = 0;   // Difference operation
    reg-> ECCTL1.bit.CTRRST4 = 0;   // Difference operation
    reg-> ECCTL2.bit.SYNCI_EN = 0;   // DisEnable sync in
    reg-> ECCTL2.bit.SYNCO_SEL = 0;        // Pass through

    reg-> ECCTL1.bit.CAPLDEN = 1;          // Enable capture units

    //need change for different cap
    reg->ECCTL2.bit.REARM=1;
    reg-> ECEINT.bit.CEVT4 = 1;            // 1 events = __interrupt
    reg-> ECEINT.bit.CTROVF =1;
    reg-> ECCTL2.bit.TSCTRSTOP = 1;        // Start Counter
}

void EcapInit(void)

    ECaptureConfig(&ECap1Regs);
}

__interrupt void ecap1_isr(void)
{

    uint32_t prdio =0,duty=0;
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;

    if(ECap1Regs.ECFLG.bit.CTROVF == 1)
    {
        ECap1Regs.ECCLR.bit.CTROVF = 1;
        ECap1Regs.ECCLR.bit.INT = 1;
    }
    if(ECap1Regs.ECFLG.bit.CEVT4 == 1)
    {
        ECap1Regs.ECCLR.bit.CEVT1 = 1;
        ECap1Regs.ECCLR.bit.CEVT2 = 1;
        ECap1Regs.ECCLR.bit.CEVT3 = 1;
        ECap1Regs.ECCLR.bit.CEVT4 = 1;
        ECap1Regs.ECCLR.bit.INT = 1;

          prdio= ECap1Regs.CAP3 - ECap1Regs.CAP1;
          duty = ECap1Regs.CAP2 - ECap1Regs.CAP1;
          if(prdio >0)
          {
              FreData[0].frequen = 150000000/prdio;
              FreData[0].duty = duty*100/prdio;
          }else
          {
              FreData[0].frequen = 0;
              FreData[0].duty = 0;
          }

    }
//              // arm one-shot

    ECap1Regs.ECCTL2.bit.TSCTRSTOP =0;
//    ECap1Regs.ECCTL2.bit.REARM = 1;

}
#endi

上电后第一次进中断函数的频率值和占空比都是正常的,但捕获不会再次发生, 如果把中断的这句 ECap1Regs.ECCTL2.bit.REARM = 1; 加上,CEVT1~4 会立刻置位,ECAp1~4 的值和TSCTR的值相等,而且在中断函数 中无法清零。 我想持续读取方波的频率应该怎么办?

  • 您可以参考下C2000WARE内例程的设置

    C2000Ware_2_00_00_02\device_support\f2837xd\examples\cpu1\ecap_capture_pwm

    该例程是one-shot的

    //
    // InitECapture - Initialize ECAP1 configurations
    //
    void InitECapture()
    {
       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
    
       //
       // Configure peripheral registers
       //
       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
    }
    
    //
    // ecap1_isr - ECAP1 ISR
    //              Cap input is syc'ed to SYSCLKOUT so there may be
    //              a +/- 1 cycle variation
    //
    __interrupt void ecap1_isr(void)
    {
       if(ECap1Regs.CAP2 > EPwm3Regs.TBPRD*4+4 ||
          ECap1Regs.CAP2 < EPwm3Regs.TBPRD*4-4)
       {
           Fail();
       }
    
       if(ECap1Regs.CAP3 > EPwm3Regs.TBPRD*4+4 ||
          ECap1Regs.CAP3 < EPwm3Regs.TBPRD*4-4)
       {
           Fail();
       }
    
       if(ECap1Regs.CAP4 > EPwm3Regs.TBPRD*4+4 ||
          ECap1Regs.CAP4 < EPwm3Regs.TBPRD*4-4)
       {
           Fail();
       }
    
       ECap1IntCount++;
    
       if(EPwm3TimerDirection == EPWM_TIMER_UP)
       {
            if(EPwm3Regs.TBPRD < PWM3_TIMER_MAX)
            {
               EPwm3Regs.TBPRD++;
            }
            else
            {
               EPwm3TimerDirection = EPWM_TIMER_DOWN;
               EPwm3Regs.TBPRD--;
            }
       }
       else
       {
            if(EPwm3Regs.TBPRD > PWM3_TIMER_MIN)
            {
               EPwm3Regs.TBPRD--;
            }
            else
            {
               EPwm3TimerDirection = EPWM_TIMER_UP;
               EPwm3Regs.TBPRD++;
            }
       }
    
       ECap1PassCount++;
    
       ECap1Regs.ECCLR.bit.CEVT4 = 1;
       ECap1Regs.ECCLR.bit.INT = 1;
       ECap1Regs.ECCTL2.bit.REARM = 1;
    
       //
       // Acknowledge this __interrupt to receive more __interrupts from group 4
       //
       PieCtrlRegs.PIEACK.all = PIEACK_GROUP4;
    }

  • 配置除了没有 EPWM 部分 ,配置是一样的,但结果却是不对的。 REARM 这个bit 的作用具体是什么 ,只用在one-short模式吗?我不是特别清楚。