从官方对DSC28034芯片的定位可以看出,该芯片是比较适合应用于电力电子电源设备的主控芯片的,下面就针对电力电子应用的主要外设EPWM和ADC的配置进行简单的说明,首先介绍PWM的配置,配置EPWM1模块的两路互补带死区PWM输出EPWM1A和EPWM1B作为单相H4桥的L桥臂两管驱动,配置EPWM2模块的两路互补带死区PWM输出EPWM2A和EPWM2B作为单相H4桥的N桥臂两管驱动,同时在EPWM1计数器为0时触发AD采样触发信号EPWM1_SOCA,以实现电感电流上升沿中心点采样,设置在计数器在AD采样触发后5us触发EPWM1中断,然后在中断中读取AD采样值,然后就可以执行闭环算法了。
具体PWM初始化代码如下:
void InitEPWM(void)
{
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 0; /每个启用的ePWM模块中的TBCLK(时基时钟)均已停止。/
EDIS;
//=============EPwm1 Init For INV-L===============//
EALLOW;
EPwm1Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
EPwm1Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
EPwm1Regs.TZFRC.bit.OST = 1;
EDIS;
EPwm1Regs.TBPRD = EPWM1_TIMER_TBPRD;
EPwm1Regs.CMPA.half.CMPA = EPWM1_TIMER_HALFPRD;
EPwm1Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm1Regs.TBCTL.bit.PHSEN = TB_DISABLE;
EPwm1Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm1Regs.TBCTL.bit.PHSDIR = TB_UP;
EPwm1Regs.TBCTL.bit.SYNCOSEL = TB_CTR_ZERO;
EPwm1Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm1Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm1Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm1Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm1Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm1Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm1Regs.AQCTLA.bit.CAD = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBU = AQ_SET;
EPwm1Regs.AQCTLB.bit.CBD = AQ_CLEAR;
EPwm1Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO;
EPwm1Regs.ETPS.bit.SOCAPRD = ET_1ST;
EPwm1Regs.ETSEL.bit.SOCAEN = 1;
EPwm1Regs.CMPB = EPWM1_CMPB_INT_CNT;
EPwm1Regs.ETSEL.bit.INTSEL = ET_CTRU_CMPB;
EPwm1Regs.ETPS.bit.INTPRD = ET_1ST;
EPwm1Regs.ETSEL.bit.INTEN = 0;
EPwm1Regs.AQSFRC.bit.RLDCSF = 0;
EPwm1Regs.AQCSFRC.bit.CSFA = AQ_NO_ACTION;
EPwm1Regs.AQCSFRC.bit.CSFB = AQ_NO_ACTION;
EPwm1Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm1Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm1Regs.DBCTL.bit.IN_MODE = DBA_ALL;
EPwm1Regs.DBRED = EPWM1_TIMER_DB;
EPwm1Regs.DBFED = EPWM1_TIMER_DB;
//=============EPwm2 Init For INV-N===============//
EALLOW;
EPwm2Regs.TZCTL.bit.TZA = TZ_FORCE_LO;
EPwm2Regs.TZCTL.bit.TZB = TZ_FORCE_LO;
EPwm2Regs.TZFRC.bit.OST = 1;
EDIS;
EPwm2Regs.TBPRD = EPWM1_TIMER_TBPRD;
EPwm2Regs.CMPA.half.CMPA = EPWM1_TIMER_HALFPRD;
EPwm2Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN;
EPwm2Regs.TBCTL.bit.PHSEN = TB_ENABLE;
EPwm2Regs.TBCTL.bit.PRDLD = TB_SHADOW;
EPwm2Regs.TBCTL.bit.PHSDIR = TB_UP;
EPwm2Regs.TBCTL.bit.SYNCOSEL = TB_SYNC_IN;
EPwm2Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;
EPwm2Regs.TBCTL.bit.CLKDIV = TB_DIV1;
EPwm2Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;
EPwm2Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;
EPwm2Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
EPwm2Regs.AQCTLA.bit.CAU = AQ_CLEAR;
EPwm2Regs.AQCTLA.bit.CAD = AQ_SET;
EPwm2Regs.AQCTLB.bit.CBU = AQ_SET;
EPwm2Regs.AQCTLB.bit.CBD = AQ_CLEAR;
EPwm2Regs.AQSFRC.bit.RLDCSF = 0;
EPwm2Regs.AQCSFRC.bit.CSFA = AQ_NO_ACTION;
EPwm2Regs.AQCSFRC.bit.CSFB = AQ_NO_ACTION;
EPwm2Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;
EPwm2Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;
EPwm2Regs.DBCTL.bit.IN_MODE = DBA_ALL;
EPwm2Regs.DBRED = EPWM1_TIMER_DB;
EPwm2Regs.DBFED = EPWM1_TIMER_DB;
// 设置EPWM同步相位值
EPwm1Regs.TBPHS.half.TBPHS = 0;
EPwm2Regs.TBPHS.half.TBPHS = 0;
// 设置EPWM计数寄存器初值
EPwm1Regs.TBCTR = 0x0000;
EPwm2Regs.TBCTR = 0x0000;
EALLOW;
SysCtrlRegs.PCLKCR0.bit.TBCLKSYNC = 1;
EDIS;
}
以下是ADC采样初始化:设置16路AD采样通道,所有通道采样触发为EPWM1_SOCA
void InitAdcSample(void)
{
EALLOW;
AdcRegs.ADCCTL1.bit.ADCENABLE = 1; / 使能ADC,并给ADC上电,写0无效,写1使能ADC /
AdcRegs.ADCCTL2.bit.CLKDIV2EN = 1; / 当系统时钟是120M的时候,配置为1,为SYSCLK/4,
当系统时钟是60M的时候,保持默认值0,为SYSCLK/2 /
while(AdcRegs.ADCCTL1.bit.ADCRDY != 1) / ADC 复位完成,当ADCRDY = 1表示复位完成,0表示复位未完成 */
{
}
AdcRegs.INTSEL1N2.bit.INT1SEL = 15;
AdcRegs.INTSEL1N2.bit.INT1E = 0;
AdcRegs.INTSEL1N2.bit.INT1CONT = 0;
AdcRegs.ADCSOC0CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC0CTL.bit.CHSEL = 0;
AdcRegs.ADCSOC0CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC1CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC1CTL.bit.CHSEL = 1;
AdcRegs.ADCSOC1CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC2CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC2CTL.bit.CHSEL = 2;
AdcRegs.ADCSOC2CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC3CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC3CTL.bit.CHSEL = 3;
AdcRegs.ADCSOC3CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC4CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC4CTL.bit.CHSEL = 4;
AdcRegs.ADCSOC4CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC5CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC5CTL.bit.CHSEL = 5;
AdcRegs.ADCSOC5CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC6CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC6CTL.bit.CHSEL = 6;
AdcRegs.ADCSOC6CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC7CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC7CTL.bit.CHSEL = 7;
AdcRegs.ADCSOC7CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC8CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC8CTL.bit.CHSEL = 8;
AdcRegs.ADCSOC8CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC9CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC9CTL.bit.CHSEL =9;
AdcRegs.ADCSOC9CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC10CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC10CTL.bit.CHSEL = 10;
AdcRegs.ADCSOC10CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC11CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC11CTL.bit.CHSEL = 11;
AdcRegs.ADCSOC11CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC12CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC12CTL.bit.CHSEL = 12;
AdcRegs.ADCSOC12CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC13CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC13CTL.bit.CHSEL = 13;
AdcRegs.ADCSOC13CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC14CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC14CTL.bit.CHSEL = 14;
AdcRegs.ADCSOC14CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCSOC15CTL.bit.ACQPS = 6;
AdcRegs.ADCSOC15CTL.bit.CHSEL = 15;
AdcRegs.ADCSOC15CTL.bit.TRIGSEL = 0x5;
AdcRegs.ADCINTSOCSEL1.all = 0x0000;
AdcRegs.ADCINTSOCSEL2.all = 0x0000;
AdcRegs.SOCPRICTL.bit.SOCPRIORITY = 0x00;
AdcRegs.SOCPRICTL.bit.RRPOINTER = 0x0F;
AdcRegs.SOCPRICTL.bit.ONESHOT = 0;
EDIS;
}
然后配置PWM输出的GPIO:
``
/******************************************************************
*函数名:void InitGPIO(void)
*参 数 :无
*返回值:无
*作 用 :初始化GPIO
******************************************************************/
void InitGPIO(void)
{
EALLOW;
GpioCtrlRegs.GPAPUD.bit.GPIO0 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO0 = 1; // GPIO0 = PWM1A-->OPWM1A/GPIO0
GpioCtrlRegs.GPAPUD.bit.GPIO1 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO1 = 1; // GPIO1 = PWM1B
GpioCtrlRegs.GPAPUD.bit.GPIO2 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO2 = 1; // GPIO2 = PWM2A
GpioCtrlRegs.GPAPUD.bit.GPIO3 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO3 = 1; // GPIO3 = PWM2B
GpioCtrlRegs.GPAPUD.bit.GPIO4 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO4 = 1; // GPIO4 = PWM3A
GpioCtrlRegs.GPAPUD.bit.GPIO5 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO5 = 1; // GPIO5 = PWM3B
GpioCtrlRegs.GPAPUD.bit.GPIO6 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO6 = 1; // GPIO6 = PWM4A
GpioCtrlRegs.GPAPUD.bit.GPIO7 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO7 = 1; // GPIO7 = PWM4B
GpioCtrlRegs.GPAPUD.bit.GPIO8 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO8 = 1; // GPIO8 = PWM5A
GpioCtrlRegs.GPAPUD.bit.GPIO9 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO9 = 1; // GPIO9 = PWM5B
GpioCtrlRegs.GPAPUD.bit.GPIO10 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO10 = 1; // GPIO10 = PWM6A
GpioCtrlRegs.GPAPUD.bit.GPIO11 = 0;
GpioCtrlRegs.GPAMUX1.bit.GPIO11 = 1; // GPIO11 = PWM6B-->OPWM6B/GPIO11
EDIS;
}
配置好PWM中断使能
/******************************************************************
*函数名:void EnableInt(void)
*参 数 :无
*返回值:无
*作 用 :使能外设中断
******************************************************************/
void EnableInt(void)
{
EALLOW; / 允许访问受保护的空间 /
PieVectTable.EPWM1_INT = &Epwm1_ISR; / 将Epwm1_ISR入口地址赋给EPWM1_INT /
EDIS; / 禁止访问受保护的空间 /
IER |= M_INT3; /*使能CPU中断组3*/
PieCtrlRegs.PIEIER3.bit.INTx1 = 1; /使能PIE3.1的中断/
// EINT;
}
中断服务函数:在中断服务函数中取得AD采样值
/******************************************************************
*函数名:void INTERRUPT Epwm1_ISR(void)
*参 数:无
*返回值:无
*作 用:中断服务函数改变pwm死区
******************************************************************/
void INTERRUPT Epwm1_ISR(void)
{
EPwm1Regs.ETCLR.bit.INT = 1;
PieCtrlRegs.PIEACK.all = PIEACK_GROUP3;
IntADResultGet();
}
/************************************************************************************
// IntADResultGet
// 功能描述:AD采样结果获取
************************************************************************************/
Uint16 AdcSample[16];
void CODE_SECTION("ramfuncs") IntADResultGet(void)
{
Uint16 iAdRltA0_0, iAdRltA1_0, iAdRltA2_0, iAdRltA3_0, iAdRltA4_0, iAdRltA5_0, iAdRltA6_0, iAdRltA7_0;
Uint16 iAdRltB0_0, iAdRltB1_0, iAdRltB2_0, iAdRltB3_0, iAdRltB4_0, iAdRltB5_0, iAdRltB6_0, iAdRltB7_0;
while(AdcRegs.ADCCTL1.bit.ADCBSY == 1)
{
continue; // 等待AD采样结束
}
iAdRltA0_0 = AdcResult.ADCRESULT0;
iAdRltA1_0 = AdcResult.ADCRESULT1;
iAdRltA2_0 = AdcResult.ADCRESULT2;
iAdRltA3_0 = AdcResult.ADCRESULT3;
iAdRltA4_0 = AdcResult.ADCRESULT4;
iAdRltA5_0 = AdcResult.ADCRESULT5;
iAdRltA6_0 = AdcResult.ADCRESULT6;
iAdRltA7_0 = AdcResult.ADCRESULT7;
iAdRltB0_0 = AdcResult.ADCRESULT8;
iAdRltB1_0 = AdcResult.ADCRESULT9;
iAdRltB2_0 = AdcResult.ADCRESULT10;
iAdRltB3_0 = AdcResult.ADCRESULT11;
iAdRltB4_0 = AdcResult.ADCRESULT12;
iAdRltB5_0 = AdcResult.ADCRESULT13;
iAdRltB6_0 = AdcResult.ADCRESULT14;
iAdRltB7_0 = AdcResult.ADCRESULT15;
AdcSample[0] = iAdRltA0_0;
AdcSample[1] = iAdRltA1_0;
AdcSample[2] = iAdRltA2_0;
AdcSample[3] = iAdRltA3_0;
AdcSample[4] = iAdRltA4_0;
AdcSample[5] = iAdRltA5_0;
AdcSample[6] = iAdRltA6_0;
AdcSample[7] = iAdRltA7_0;
AdcSample[8] = iAdRltB0_0;
AdcSample[9] = iAdRltB1_0;
AdcSample[10] = iAdRltB2_0;
AdcSample[11] = iAdRltB3_0;
AdcSample[12] = iAdRltB4_0;
AdcSample[13] = iAdRltB5_0;
AdcSample[14] = iAdRltB6_0;
AdcSample[15] = iAdRltB7_0;
}
主函数中打开总中断和看门狗喂狗等
int main(void)
{
SystemInit();
EnableDog();
EPwm1Regs.ETCLR.bit.INT = 1;
EPwm1Regs.ETSEL.bit.INTEN = 1;
EINT;
while(1)
{
ServiceDog();
SysTimeBase();
StateLEDCtrl();
}
return 0;
}
仿真读取的AD采样值:
只有第ADC_A4通道接着3.3V,所以它的采样值为4096,其他都为0
另外说明一个小问题,在仿真时是没办法实时看变量的,IDE不支持,这个很影响调试
同时,手册上说的参考2.5.8,实际是没有这个章节的