DSP2837x ECAP调试(BLDC霍尔)


前言

DSP28377D 的ECAP调试。


提示:以下是本篇文章正文内容,下面案例可供参考

一、ECAP的作用

ECAP可以根据位置传感器脉冲来测量位置、计算脉冲周期等等。
在这里插入图片描述
此处我们使用ECAP来捕捉霍尔的信号,类似于STM32的定时器捕捉霍尔功能,本质上ECAP也是通过计数器计算周期。


二、ECAP初始化及配置

1.初始化

1)mian()

主函数代码部分如下(示例):

EALLOW;
PieVectTable. ECAP1_INT = &ECAP1_ISR;
PieVectTable. ECAP2_INT = &ECAP2_ISR;
PieVectTable. ECAP3_INT = &ECAP3_ISR;
EDIS;
//Enable eCAP1\2\3 interrupts
PieCtrlRegs.PIEIER4.bit.INTx1 = 1;
PieCtrlRegs.PIEIER4.bit.INTx2 = 1;
PieCtrlRegs.PIEIER4.bit.INTx3 = 1;
IER |= M_INT4;                 //CAP

InitECap1();
InitECap2();
InitECap3();

2)引脚配置

在这里插入图片描述
28377和28335的ECAP有不同,2837x里的ECAP属于x-bar范围,分别是INTPUT 7 、8、9,
简单来说就是将引脚配置成普通GPIO然后再用x-bar的input7映射到引脚即可 。

InputXbarRegs.INPUT7SELECT = 58;
//Set ECAP1 source to GPIO-pin58

代码如下(示例):

void InitECap1(void)
{
  EALLOW;
  InputXbarRegs.INPUT7SELECT = 58;       //Set ECAP1 source to GPIO-pin
  GpioCtrlRegs.GPBDIR.bit.GPIO58 = 0;    // input
  GpioCtrlRegs.GPBPUD.bit.GPIO58 = 0;    // Enable pull-up on GPIO58 (CAP1)
  GpioCtrlRegs.GPBGMUX2.bit.GPIO58 = 0;        // GPIO
  GpioCtrlRegs.GPBMUX2.bit.GPIO58 = 0;         // GPIO
  GpioCtrlRegs.GPBQSEL2.bit.GPIO58 = 0;        
  EDIS;
  SetCap1Mode();
}

3)ECAP配置

ECAP计数器有多种模式,不一一阐释,本次采用连续计数模式并捕获事件后清空计数

ECap1Regs.ECCTL1.bit.CTRRST1 = EC_DELTA_MODE;
//捕获到事件清空计数器
ECap1Regs.ECCTL2.bit.CONT_ONESHT = EC_CONTINUOUS;
//连续计数模式

在这里插入图片描述
这种方式的好处是每次事件发生都获得周期的计数时间,并再次复位计数器。

代码如下(示例):

void SetCap1Mode(void)
{
  ECap1Regs.ECCTL1.bit.CAP1POL = EC_RISING;         //事件1极性
  ECap1Regs.ECCTL1.bit.CAP2POL = EC_FALLING;        //事件2极性
  ECap1Regs.ECCTL1.bit.CAP3POL = EC_RISING;         //事件3极性
  ECap1Regs.ECCTL1.bit.CAP4POL = EC_FALLING;        //事件4极性
  ECap1Regs.ECCTL1.bit.CTRRST1 = EC_DELTA_MODE;     //捕获到事件清空计数器
  ECap1Regs.ECCTL1.bit.CTRRST2 = EC_DELTA_MODE;     //捕获到事件清空计数器
  ECap1Regs.ECCTL1.bit.CTRRST3 = EC_DELTA_MODE;     //捕获到事件清空计数器
  ECap1Regs.ECCTL1.bit.CTRRST4 = EC_DELTA_MODE;     //捕获到事件清空计数器
  ECap1Regs.ECCTL1.bit.CAPLDEN = EC_ENABLE;         //使能装载
  ECap1Regs.ECCTL1.bit.PRESCALE = EC_DIV1;          //输入信号不分频
  ECap1Regs.ECCTL2.bit.CAP_APWM = EC_CAP_MODE;      //配置为捕获模式
  ECap1Regs.ECCTL2.bit.CONT_ONESHT = EC_CONTINUOUS; //连续计数模式
  ECap1Regs.ECCTL2.bit.SYNCO_SEL = EC_SYNCO_DIS;    //
  ECap1Regs.ECCTL2.bit.SYNCI_EN = EC_DISABLE;
  ECap1Regs.ECEINT.all=0x0000;                      //stop all interrupt
  ECap1Regs.ECCLR.all=0xFFFF;                       //clare all flag
  ECap1Regs.ECCTL2.bit.TSCTRSTOP = EC_RUN;          //时间戳计数器自由运行
  ECap1Regs.ECEINT.bit.CEVT1=1;                     // Enable cevt1 interrupt
  ECap1Regs.ECEINT.bit.CEVT2=1;                     // Enable cevt2 interrupt
  ECap1Regs.ECEINT.bit.CEVT3=1;                     // Enable cevt3 interrupt
  ECap1Regs.ECEINT.bit.CEVT4=1;                     // Enable cevt4 interrupt
}

void SetCap2Mode(void)
{
//与上相同
}

2.中断

服务函数代码如下(示例):

interrupt void ECAP1_ISR(void)
{
 static Uint32  t1,t2,t3,t4;
 //此处可以读一次hall的引脚电平,并执行换向
 t1= ECap1Regs.CAP1;
 t2= ECap1Regs.CAP2;
 t3= ECap1Regs.CAP3;
 t4= ECap1Regs.CAP4;
}

ECap1Regs.ECCTL1.bit.CAP1POL = EC_RISING; //事件1极性
ECap1Regs.ECCTL1.bit.CAP2POL = EC_FALLING; //事件2极性
ECap1Regs.ECCTL1.bit.CAP3POL = EC_RISING; //事件3极性
ECap1Regs.ECCTL1.bit.CAP4POL = EC_FALLING; //事件4极性

因为 t1,t3是上升沿,t2,t4是下降沿,所以霍尔时间计算如下:
霍尔(GPIO58)为高的持续时间=t2 * ECAP频率=t4 * ECAP频率 ;
霍尔(GPIO58)为低的持续时间=t1 * ECAP频率=t3 * ECAP频率;
ECAP频率 = SYSCLK / ECap1Regs.ECCTL1.bit.PRESCALE = SYSCLK / 1 ;


总结

ECAP可以及时响应霍尔信号通过计数器计算周期,但实际项目中,我还是取消了该计算功能,因为电机刚启动时的ECAP计数是角缺失的,即t1需要第二次获取才是完整的角时间,速度计算严重滞后,最终方案改为:
1、ecap捕捉3个霍尔位置。
2、开启定时器,并计算每个hall之间的时间间隔。
3、启动时只需要丢弃第一个step的计时即可。