目前想要用cpu1用epwm3,同时adca到dacd的channel0采集信号(由epwm3SOCA触发,ADCINT1发送中断),作比较后根据情况触发cpu2的采样(adca到adcb的1通道,由epwm2SOCA触发,ADCINT2发送中断)和epwm2。
目前运行,每个pwm都是给定50%定值输出,给定的采样值也是让cpu2恒定触发采样和epwm2。cpu1的epwm3没有输出,但是由它触发的adca到adcd的零通道是有采集数据的。cpu2的epwm2没有输出,相应的adc1也没有采集。求助
cpu1的初始化配置的代码:
////////////////////////////////////////////////////////////
ConfigureADC();
EALLOW;
DevCfgRegs.CPUSEL0.bit.EPWM3 = 0;
EDIS;
SetupADCEpwm(0); //Setup the ADC for ePWM triggered conversions on channel 0
ledkeyInit(); //初始化led,注意,若使用pwm不能配置为led
EALLOW;
PieVectTable.ADCA1_INT = &adc_isr;
EDIS;
EALLOW;
CpuSysRegs.PCLKCR2.bit.EPWM3 = 1; //外围时钟门控寄存器
CpuSysRegs.PCLKCR13.bit.ADC_A = 1;//外围时钟门控寄存器
CpuSysRegs.PCLKCR13.bit.ADC_B = 1;//外围时钟门控寄存器
CpuSysRegs.PCLKCR13.bit.ADC_C = 1;//外围时钟门控寄存器
CpuSysRegs.PCLKCR13.bit.ADC_D = 1;//外围时钟门控寄存器
EDIS;
EALLOW;
CpuSysRegs.PCLKCR0.bit.GTBCLKSYNC = 0;
EDIS;
ConfigureEPWM3(); //驱动cpu1的
ConfigureEPWM2(); //驱动cpu2的
EALLOW;
DevCfgRegs.CPUSEL0.bit.EPWM2 = 1;
EDIS;
IPCLtoRFlagSet(IPC_FLAG17);
while(IPCLtoRFlagBusy(IPC_FLAG17));
EALLOW;
CpuSysRegs.PCLKCR0.bit.GTBCLKSYNC = 1;//全核心pwm时钟同步
EDIS;
PieCtrlRegs.PIECTRL.bit.ENPIE = 1;
IER |= M_INT1;
PieCtrlRegs.PIEIER1.bit.INTx1 = 1;
////////////////////////////////////////////////////////////
cpu2的初始化代码:
////////////////////////////////////////////////////////////
PieVectTable.IPC0_INT = &CPU01toCPU02IPC0_ISR;
// PieVectTable.EPWM1_INT = &epwm1_isr;
PieVectTable.ADCA2_INT = &adc_isr;
EDIS; // ISR functions found within this file.
ConfigureADC();
EALLOW;
CpuSysRegs.PCLKCR0.bit.GTBCLKSYNC = 0;//外围时钟门控寄存器 EPWM1时基时钟同步
EDIS;
SetupADCEpwmSC(1); //没设置触发源,IPC来之后设置
while(!IPCRtoLFlagBusy(IPC_FLAG17));
CpuSysRegs.PCLKCR2.bit.EPWM2 = 1;
IPCRtoLFlagAcknowledge(IPC_FLAG17);
PieCtrlRegs.PIECTRL.bit.ENPIE = 1; // Enable the PIE block
//PieCtrlRegs.PIEIER1.bit.INTx1 = 1; //使能第一组中断中第一个小中断
PieCtrlRegs.PIEIER10.bit.INTx2 = 1; //使能第一组中断中第一个小中断
PieCtrlRegs.PIEIER1.bit.INTx13 = 1; // CPU1 to CPU2 INT0,两者都用INT0寄存器一样
IER |= M_INT1;
IER |=M_INT10;
EINT;
ERTM;
while(1)
{
//if(IPCRtoLFlagBusy(IPC_FLAG10) == 1)
if(dischargeflag == 1) //dischargeflag是通过cpu1通过shared ram发给cpu2(借助ipc0)的,确实是发过去的,也就是再测试时dischargeflag=0恒成立
{
//IPCRtoLFlagAcknowledge (IPC_FLAG10);
/*************************************启动adc******************************
AdcaRegs.ADCSOC1CTL.bit.TRIGSEL = 7; //trigger on ePWM2 SOCA
AdcbRegs.ADCSOC1CTL.bit.TRIGSEL = 7; //trigger on ePWM2 SOCA
/*********** 是否需要等待adc中断执行后再下一步?********************/
while(AdcbRegs.ADCINTFLG.bit.ADCINT2==0);//////////////////////////////////////////////////////此时cpu2一直停在这里,adc配置失败????
while(AdcbRegs.ADCINTFLG.bit.ADCINT2==1);
////////////////////////////////////////////////////////////
Green Deng:
一个是,你的问题关键似乎在于ePWM3没有发波但ADCxIN0的通道采样被触发了。这里不知道是你的PWM设置有误(看不到这部分代码)还是你的PWM引脚测错了?
二是你的程序中似乎没有配置将ADC的owner ship分配给CPU2的CPUSEL11寄存器?
,
user5100224:
第一个问题,引脚没有测错,因为用了另一个程序同一个引脚输出epwm,是可以输出的。cpu1的pwm和adc的设置如下,请问那些地方有错误?
////////////////////////////////////////////////////////////////
void ConfigureADC(void)
{EALLOW;AdcaRegs.ADCCTL2.bit.PRESCALE = 6;AdcSetMode(ADC_ADCA, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);AdcaRegs.ADCCTL1.bit.INTPULSEPOS = 1;AdcaRegs.ADCCTL1.bit.ADCPWDNZ = 1;DELAY_US(1000);EDIS;
EALLOW;AdcbRegs.ADCCTL2.bit.PRESCALE = 6; AdcSetMode(ADC_ADCB, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);AdcbRegs.ADCCTL1.bit.INTPULSEPOS = 1;AdcbRegs.ADCCTL1.bit.ADCPWDNZ = 1;DELAY_US(1000);EDIS;
EALLOW;AdccRegs.ADCCTL2.bit.PRESCALE = 6;AdcSetMode(ADC_ADCC, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);AdccRegs.ADCCTL1.bit.INTPULSEPOS = 1;AdccRegs.ADCCTL1.bit.ADCPWDNZ = 1;DELAY_US(1000);EDIS;
EALLOW;AdcdRegs.ADCCTL2.bit.PRESCALE = 6;AdcSetMode(ADC_ADCD, ADC_RESOLUTION_12BIT, ADC_SIGNALMODE_SINGLE);AdcdRegs.ADCCTL1.bit.INTPULSEPOS = 1;AdcdRegs.ADCCTL1.bit.ADCPWDNZ = 1;DELAY_US(1000);EDIS;
}////////////////////////////////////////////////////////////////
void SetupADCEpwm(Uint16 channel)
{Uint16 acqps;
if(ADC_RESOLUTION_12BIT == AdcaRegs.ADCCTL2.bit.RESOLUTION){acqps = 14; //75ns F=Fsys/(acqps+1)}else //resolution is 16-bit{acqps = 63; //320ns}
EALLOW;AdcaRegs.ADCSOC0CTL.bit.CHSEL = channel;//SOC0 will convert pin A0AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cyclesAdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 9; //trigger on ePWM3 SOCAAdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //0h EOC0 is trigger for ADCINT1AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1;//enable ADCINT1 flagAdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is clearedEDIS;
//ADCBEALLOW;AdcbRegs.ADCSOC0CTL.bit.CHSEL = channel;//SOC1 will convert pin B0AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cyclesAdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 9; //trigger on ePWM3 SOCAAdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flagAdcbRegs.ADCINTSEL1N2.bit.INT1E = 1;//enable INT1 flagAdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is clearedEDIS;//ADCCEALLOW;AdccRegs.ADCSOC0CTL.bit.CHSEL = channel+2;//28377D闫旭ADCC从2到4,没有0,1AdccRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cyclesAdccRegs.ADCSOC0CTL.bit.TRIGSEL = 9; //trigger on ePWM3 SOCAAdccRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flagAdccRegs.ADCINTSEL1N2.bit.INT1E = 1;//enable INT1 flagAdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is clearedEDIS;//ADCDEALLOW;AdcdRegs.ADCSOC0CTL.bit.CHSEL = channel;//SOC1 will convert pin B0AdcdRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cyclesAdcdRegs.ADCSOC0CTL.bit.TRIGSEL = 9; //trigger on ePWM3 SOCAAdcdRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flagAdcdRegs.ADCINTSEL1N2.bit.INT1E = 1;//enable INT1 flagAdcdRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is clearedEDIS;
}////////////////////////////////////////////////////////////////
void ConfigureEPWM3(void)
{
EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and downEPwm3Regs.TBPRD = EPWM1_TIMER_TBPRD;// Set timer periodEPwm3Regs.TBCTL.bit.PHSEN = TB_DISABLE;// Disable phase loadingEPwm3Regs.TBPHS.bit.TBPHS = 0x0000;// Phase is 0EPwm3Regs.TBCTR = 0x0000;// Clear counterEPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1;// Clock ratio to SYSCLKOUTEPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1;//TBCLK =EPWMCLK/((HSPCLKDIV*2) * (CLKDIV^2))
// Setup shadow register load on ZEROEPwm3Regs.CMPCTL.bit.SHDWAMODE = CC_SHADOW;EPwm3Regs.CMPCTL.bit.SHDWBMODE = CC_SHADOW;EPwm3Regs.CMPCTL.bit.LOADAMODE = CC_CTR_ZERO;EPwm3Regs.CMPCTL.bit.LOADBMODE = CC_CTR_ZERO;
// Set Compare valuesEPwm3Regs.CMPA.bit.CMPA = 5;// Set compare A valueEPwm3Regs.CMPB.bit.CMPB = 5;// Set Compare B value
// Set actionsEPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR;// Clear PWM1A on event A, up countEPwm3Regs.AQCTLA.bit.CAD = AQ_SET;// Set PWM1A on event A, down countEPwm3Regs.AQCTLB.bit.CBU = AQ_SET;// Set PWM1A on event B, up countEPwm3Regs.AQCTLB.bit.CBD = AQ_CLEAR;// Clear PWM1B on event B, down count
// Set DB TIMEEPwm3Regs.DBCTL.bit.OUT_MODE = DB_FULL_ENABLE;EPwm3Regs.DBCTL.bit.POLSEL = DB_ACTV_HIC;EPwm3Regs.DBRED.bit.DBRED = 0;EPwm3Regs.DBFED.bit.DBFED = 0;
EPwm3Regs.ETFLG.bit.SOCA=1;EPwm3Regs.ETSEL.bit.SOCAEN = 1;// Enable SOC on A groupEPwm3Regs.ETSEL.bit.SOCASEL =1;// Select SOC from CPMA on upcountEPwm3Regs.ETPS.bit.SOCAPRD = 1;// Generate pulse on 1st event
}第二个问题我不是很清楚,cpu1也要用到adca,adcb,adcc,adcd。如果把adca和adcb的ownership分给cpu2。那不是cpu1用不了adca和adcb了吗?28377d的每一个adc通道只能由一个cpu来控制采样?
,
user5100224:
第一个问题的代码补充,adc_isr 函数如下:
interrupt void adc_isr(void)
{//while(AdcaRegs.ADCINTFLG.bit.ADCINT1==0){};//ADC中断标志寄存器//while(AdcbRegs.ADCINTFLG.bit.ADCINT1==0){};//ADC中断标志寄存器//while(AdccRegs.ADCINTFLG.bit.ADCINT1==0){};while(AdcdRegs.ADCINTFLG.bit.ADCINT1==0);
vbat=AdcaResultRegs.ADCRESULT0-48.0;//AdcResult_A0ibat=AdcbResultRegs.ADCRESULT0+1.0;//AdcResult_B0vdc=AdccResultRegs.ADCRESULT0-48.0;//AdcResult_C2idc=AdcdResultRegs.ADCRESULT0-48.0;//AdcResult_D0//ubat=u_cal(vdc,ibat,vdcref);//EPwm3Regs.CMPA.bit.CMPA = EPWM1_TIMER_TBPRD*ubat;EPwm3Regs.CMPA.bit.CMPA = 250;EPwm3Regs.CMPB.bit.CMPB = 250;
AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear ADCINT1 flagAdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear ADCINT1 flagAdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear ADCINT1 flagAdcdRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear ADCINT1 flagPieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
}