DSP28379D_ePWM同步触发差分AD

ePWM同步触发差分AD

  • 为什么要使用同步触发
    • ePWM(ET)配置
    • 差分ADC配置
    • 实验验证
    • 结束语
    • 参考资料目录

为什么要使用同步触发

介绍使用ePWM周期触发16位的差分AD采样,保证每次采样在控制周期的起始位置。因与ePWM的内在联系,可以在谐波的固定位置采样,有利于采样的稳定性,使数字控制系统更标准,利于传函应用,避免影响到与时间密切相关的一些数字滤波器。

ePWM(ET)配置

重点放于ET上,基础的PWM发波不再赘述。事件触发子模块管理时基模块、计数比较模块和数字比较模块生成的事件,以在发生选定事件时向CPU生成中断,或向ADC生成转换脉冲的开始。计数比较模块共有四个:CMPA、CMPB、CMPC、CMPD。前两者通常用于控制PWM的占空比,TBPRD的数值控制PWM的周期,那么可以通过设置ETSEL、ETPS两个寄存器,使能并选择在何时产生触发事件。可以选择触发条件为TBCTR=0或者TBCTR=TBPRD,产生ADC的同步触发信号。当TBCTR为在增减计数模式时,即生成PWM为中心对称模式,则可以理解为,可以在每个PWM周期开始或者中间,可以进行AD同步转换。再进一步,可以选定在差分输入电压信号的波峰或者波谷进行采样,避免一会儿在纹波的波峰采样,一会儿在波谷,引起数值不稳。
建立在数据手册、技术参考手册和官方例程理解的基础上,阐明ePWM子模块ET的使用配置流程:
① 设置时基模块工作模式。配置时基周期,计数模式,分频系数等,时基周期为电机控制周期。
② 选择产生SOCx中断的条件。SOCxSEL共八种模式,不同的模式可以选择不同的触发条件。
③ 设置触发事件分频系数。ETPS可以设置三种方式,1.中断条件满足即触发(不分频);2.中断条件满足两次后触发(二分频);3.中断条件满足三次后触发(三分频)。
④使能SOCx中断。SOCxEN=1,当上周所讲ADC也配置好之后,开启中断。

void InitEPwm1(void)
{
    //A相驱动-EPWM1
    InitEPwm1Gpio();                                //初始化PWMx的GPIO
    //时基模块工作模式
    EPwm1Regs.TBPRD = EPWM_PRD;                      // 设置三角载波周期
    EPwm1Regs.TBPHS.bit.TBPHS = 0x0000;             // Phase is 0
    EPwm1Regs.TBCTR = 0x0000;                       // Clear counter
    EPwm1Regs.TBCTL.bit.CTRMODE = 0x2;              // 递增递减双向模式
    EPwm1Regs.TBCTL.bit.PHSEN = 0x0;                // Disable phase loading
    EPwm1Regs.TBCTL.bit.HSPCLKDIV = 0x0;            // Clock ratio to SYSCLKOUT
    EPwm1Regs.TBCTL.bit.CLKDIV = 0x0;               // Slow just to observe on the scope
    // 计数比较模块CMPA初始值(可删)
    EPwm1Regs.CMPA.bit.CMPA = EPWM_PRD;
    // 影子寄存器设置
    EPwm1Regs.CMPCTL.bit.SHDWAMODE = 0;
    EPwm1Regs.CMPCTL.bit.LOADAMODE = 0;             // 计数器为0时,载入比较值
    // 动作模块,高电平有效
    EPwm1Regs.AQCTLA.bit.CAU = 2;            // Set PWMxA on 1
    EPwm1Regs.AQCTLA.bit.CAD = 1;            // Set PWMxA on 0
    // 死区产生模块
    EPwm1Regs.DBCTL.bit.OUT_MODE = 0x3; //死区输出模式,RED和FED都使能
    EPwm1Regs.DBCTL.bit.POLSEL = 0x2;   //死区设置在B路PWM上
    EPwm1Regs.DBCTL.bit.IN_MODE = 0x0;  //死区输入模式控制
    EPwm1Regs.DBRED.bit.DBRED = DB_TIME;    //上升沿死区
    EPwm1Regs.DBFED.bit.DBFED = DB_TIME;    //下降沿死区
    // PWM中断设置
    //EPwm1Regs.ETSEL.bit.INTSEL = 0x1;   //设置EPWM产生中断的条件,当前设置为TB等于0时产生中断
    //EPwm1Regs.ETPS.bit.INTPRD = 0x1;    //Generate INT on 1st event
    EPwm1Regs.ETSEL.bit.SOCAEN  = 0;     // Disable SOC on A group
    EPwm1Regs.ETSEL.bit.SOCASEL = 1;     // Enable event time-base counter equal to 0 (TBCTR =0)
    EPwm1Regs.ETPS.bit.SOCAPRD  = 1;     // Generate pulse on 1st event
    //EPwm1Regs.ETSEL.bit.SOCAEN  = 1;    // enable SOC on A group
    //EPwm1Regs.ETSEL.bit.INTEN = 1;      //打开EPWM中断使能
}

差分ADC配置

片上的ADC支持12位和16位采样精度,12位仅为单端转换使用,16位仅为差分转换使用。ADC模块支持多重触发源,包括定时器0/1/2、ePWM等。
建立在数据手册、技术参考手册和官方例程理解的基础上,阐明ADC模块的使用配置流程:
①配置ADCCLK时钟。DSP28379D共有4个ADC模块,使用时需要分别配置4个模块的时钟。ADC的采样保持电路由系统时钟SYSCLK计时,而ADC的转换过程由ADCCLK计时。
②配置采样精度和模式。12位精度对应单端模式,16位精度对应差分模式。这其中存在一个重新注入trim值的过程,与TI出厂时ADC的标定有关,例程只给出12位精度时的线性修剪校正,16位精度尚未明确,可能不需要做线性修剪校正。
③配置中断脉冲发生位置(ADCINT flag)。存在两种位置:1.在采样保持结束时刻;2.在转换结束时刻。通常使用2位置,将ADCINT flag置位,此时转换结果已存入结果寄存器中。
④ADC加电。给一定的时间让ADC加电运行。
⑤配置ePWM模块。将ePWM的SOCx、CMPx、TBPRD、TBCTL等寄存器,按照需要赋值,产生ADC的SOCx单元的同步触发信号。需要理解事件触发子模块。
⑥配置ADC的SOC。 根据硬件设计的实际引脚情况,设置采样保持窗口时间,选择与步骤⑤对应的触发方式,使能相应的标志位功能,并复位。
⑦中断服务程序中读取ADC结果寄存器中的数据。控制程序可以放在ADC中断中。
ADC同步采样的关键在于:
①尽量保证每个ADC的SOC配置相同(设置相同的采样保持时间与触发源)。
②由于硬件设计不一定保证每个ADC下的SOC数量相同,故触发源触发时间间隔,应大于拥有SOC数量最多的ADC完成转换的总时长。
③若存在不同采样精度,应并行处理。同一时刻保证不同的ADC是相同的采样精度。

//  ADCA
    //write configurations
    AdcaRegs.ADCCTL2.bit.PRESCALE = 6; //set ADCCLK divider to /4
    AdcSetMode(ADC_ADCA, ADC_RESOLUTION_16BIT, ADC_SIGNALMODE_DIFFERENTIAL);
    //Set pulse positions to late
    AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;
    //power up the ADCs
    AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;
    //delay for 1ms to allow ADC time to power up
    DELAY_US(1000);
    ...
//  ADCA
    AdcaRegs.ADCSOC14CTL.bit.CHSEL = 2;     
    AdcaRegs.ADCSOC15CTL.bit.CHSEL = 4;    
    AdcaRegs.ADCSOC14CTL.bit.ACQPS = 139;    //sample window is 140 SYSCLK cycles
    AdcaRegs.ADCSOC15CTL.bit.ACQPS = 139;   //sample window is 140 SYSCLK cycles
    AdcaRegs.ADCSOC14CTL.bit.TRIGSEL = 5;    //trigger on ePWM1 SOCA
    AdcaRegs.ADCSOC15CTL.bit.TRIGSEL = 5;    //trigger on ePWM1 SOCA
    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 15; //End of SOC15 will set INT1 flag
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;    //Enable ADCINT1
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1;  //make sure INT1 flag is cleared
    ...
    interrupt void ADCA1_ISR(void)
    {
     	AdcaResults[0] = AdcaResultRegs.ADCRESULT14;
	AdcaResults[1] = AdcaResultRegs.ADCRESULT15;
	sample[0] = ( __divf32((int32)AdcaResults[0] * 2 , 65536 ) - 1 ) * 3;
	sample[1] = ( __divf32((int32)AdcaResults[1] * 2 , 65536 ) - 1 ) * 3;
	//
        // Check if overflow has occurred
        //
        if(1 == AdcaRegs.ADCINTOVF.bit.ADCINT1)
        {
		AdcaRegs.ADCINTOVFCLR.bit.ADCINT1 = 1; //clear INT1 overflow flag
        	AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear INT1 flag
        }
      	PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    }

实验验证

受限于条件,疫情期间家里蹲。使用12位的DAC输出(0~3V),16位的ADC进行采样,触发条件为ePWM的载波计数为0。如下图所示,简单地换算一下,我们可以看到,功能实现完毕。

在这里插入图片描述
DSP28379D_ePWM同步触发差分AD_第1张图片

结束语

TI的C2000Ware是非常值得参考的,虽然不能面面俱到,但是给出思路,有迹可循。再者,技术参考手册和数据手册需要配合使用,才能不遗漏一点,都是些比较细节的东西,配置难度不高,关键是看用户是否真正想要使用好数字控制。如有不缜密的地方,欢迎大佬指点。

参考资料目录

《TMS320F2837xD Dual-Core Microcontrollers Technical Reference Manual》ADC、ePWM、DAC章节
《TMS320F2837xD Dual-Core Microcontrollers Datasheet》模拟外设章节
《LAUNCHXL-F28379D Overview》
C2000Ware有关ADC的所有例程

你可能感兴趣的:(DSP2837xS/D)