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的计时即可。