This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

28377D 怎么设置双核分别驱动各自的pwm以及采集各自的采样值?



目前想要用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);

////////////////////////////////////////////////////////////

  • 一个是,你的问题关键似乎在于ePWM3没有发波但ADCxIN0的通道采样被触发了。这里不知道是你的PWM设置有误(看不到这部分代码)还是你的PWM引脚测错了?
    二是你的程序中似乎没有配置将ADC的owner ship分配给CPU2的CPUSEL11寄存器?
  • 第一个问题,引脚没有测错,因为用了另一个程序同一个引脚输出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 A0
    AdcaRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
    AdcaRegs.ADCSOC0CTL.bit.TRIGSEL = 9; //trigger on ePWM3 SOCA
    AdcaRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //0h EOC0 is trigger for ADCINT1
    AdcaRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable ADCINT1 flag
    AdcaRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
    EDIS;

    //ADCB
    EALLOW;
    AdcbRegs.ADCSOC0CTL.bit.CHSEL = channel; //SOC1 will convert pin B0
    AdcbRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
    AdcbRegs.ADCSOC0CTL.bit.TRIGSEL = 9; //trigger on ePWM3 SOCA
    AdcbRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
    AdcbRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag
    AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
    EDIS;
    //ADCC
    EALLOW;
    AdccRegs.ADCSOC0CTL.bit.CHSEL = channel+2; //28377D闫旭ADCC从2到4,没有0,1
    AdccRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
    AdccRegs.ADCSOC0CTL.bit.TRIGSEL = 9; //trigger on ePWM3 SOCA
    AdccRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
    AdccRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag
    AdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
    EDIS;
    //ADCD
    EALLOW;
    AdcdRegs.ADCSOC0CTL.bit.CHSEL = channel; //SOC1 will convert pin B0
    AdcdRegs.ADCSOC0CTL.bit.ACQPS = acqps; //sample window is 100 SYSCLK cycles
    AdcdRegs.ADCSOC0CTL.bit.TRIGSEL = 9; //trigger on ePWM3 SOCA
    AdcdRegs.ADCINTSEL1N2.bit.INT1SEL = 0; //end of SOC0 will set INT1 flag
    AdcdRegs.ADCINTSEL1N2.bit.INT1E = 1; //enable INT1 flag
    AdcdRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //make sure INT1 flag is cleared
    EDIS;
    }

    ////////////////////////////////////////////////////////////////
    void ConfigureEPWM3(void)
    {

    EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; // Count up and down
    EPwm3Regs.TBPRD = EPWM1_TIMER_TBPRD; // Set timer period
    EPwm3Regs.TBCTL.bit.PHSEN = TB_DISABLE; // Disable phase loading
    EPwm3Regs.TBPHS.bit.TBPHS = 0x0000; // Phase is 0
    EPwm3Regs.TBCTR = 0x0000; // Clear counter
    EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; // Clock ratio to SYSCLKOUT
    EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1; //TBCLK =EPWMCLK/((HSPCLKDIV*2) * (CLKDIV^2))

    // Setup shadow register load on ZERO
    EPwm3Regs.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 values
    EPwm3Regs.CMPA.bit.CMPA = 5; // Set compare A value
    EPwm3Regs.CMPB.bit.CMPB = 5; // Set Compare B value

    // Set actions
    EPwm3Regs.AQCTLA.bit.CAU = AQ_CLEAR; // Clear PWM1A on event A, up count
    EPwm3Regs.AQCTLA.bit.CAD = AQ_SET; // Set PWM1A on event A, down count
    EPwm3Regs.AQCTLB.bit.CBU = AQ_SET; // Set PWM1A on event B, up count
    EPwm3Regs.AQCTLB.bit.CBD = AQ_CLEAR; // Clear PWM1B on event B, down count

    // Set DB TIME
    EPwm3Regs.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 group
    EPwm3Regs.ETSEL.bit.SOCASEL =1; // Select SOC from CPMA on upcount
    EPwm3Regs.ETPS.bit.SOCAPRD = 1; // Generate pulse on 1st event
    }

    第二个问题我不是很清楚,cpu1也要用到adca,adcb,adcc,adcd。如果把adca和adcb的ownership分给cpu2。那不是cpu1用不了adca和adcb了吗?28377d的每一个adc通道只能由一个cpu来控制采样?
  • 第一个问题的代码补充,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_A0
    ibat=AdcbResultRegs.ADCRESULT0+1.0;//AdcResult_B0
    vdc=AdccResultRegs.ADCRESULT0-48.0;//AdcResult_C2
    idc=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 flag
    AdcbRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear ADCINT1 flag
    AdccRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear ADCINT1 flag
    AdcdRegs.ADCINTFLGCLR.bit.ADCINT1 = 1; //clear ADCINT1 flag
    PieCtrlRegs.PIEACK.all = PIEACK_GROUP1;
    }