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.
需求:
1. 使用timer1高频触发多路ADC SOC,但是timer1不用产生中断,自动重载触发采样,以节约CPU开销
2. ADC EOC时通过DMA传输到指定RAM区,4轮EOC DMA传输完毕后再触发DMA传输完成中断。同样的,期间不要触发ADC EOC完成中断,以节约CPU开销
实际撰写上述需求的代码时,发现第一点就无法实现,必须使能timer1中断才能有效触发ADC SOC。
请问上述需求是否可以在280039中实现?
timer1可以不在PIE中使能中断,这样应该可以触发ADC SOC,但是不触发CPU中断。不过还是建议用ePWM来做这个功能,它的ET模块可以配置成每四次ADC SOC触发一次CPU中断。
ePWM触发速度太慢,我需要采集在一个PWM周期内采集3次电流以得到更准确的平均电流。
1. 使用timer1高频触发多路ADC SOC,但是timer1不用产生中断,自动重载触发采样,以节约CPU开销
这个问题已经解决。
目前出现了第二个问题,只有首次EOC触发了一次DMA搬运,后面EOC无法触发。
官方提供的例程没有涉及到这类情况,我的DMA代码配置如下,帮忙看看是否有问题
void configureDMAChannels(void)
{
DMA_clearTriggerFlag(DMA_CH1_BASE); // DMA channel 1
DMA_clearTriggerFlag(DMA_CH2_BASE); // DMA channel 2
// DMA channel 1 set up for ADCA
DMA_configAddresses(DMA_CH1_BASE, (uint16_t *)&s_AdcaResult,
(uint16_t *)ADCARESULT_BASE);
//该通道单次搬运的DMA_CH1_ADC_NO个ADC结果,以及按多大步长的地址进行搬运,单位为16bit (ADC 结果寄存器为16bit,所以配置为1)
DMA_configBurst(DMA_CH1_BASE, DMA_CH1_ADC_NO, 1, 1);
//配置传输N(2 * ADC_OVER_SAMPLE_FACTOR)次,且每次搬运后如何对源地址和目标地址操作,源地址需要回退到ADCA-Result0,目的地址继续累加1
DMA_configTransfer(DMA_CH1_BASE, 2 * ADC_OVER_SAMPLE_FACTOR, -DMA_CH1_ADC_NO + 1, 1);
//DMA1的触发源为ADCA1中断标志位
DMA_configMode(DMA_CH1_BASE, DMA_TRIGGER_ADCA1,
(DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE |
DMA_CFG_SIZE_16BIT));
DMA_enableTrigger(DMA_CH1_BASE);
DMA_disableOverrunInterrupt(DMA_CH1_BASE);
DMA_setInterruptMode(DMA_CH1_BASE, DMA_INT_AT_END);
DMA_enableInterrupt(DMA_CH1_BASE);
// DMA channel 2 set up for ADCB
DMA_configAddresses(DMA_CH2_BASE, (uint16_t *)&s_AdcbResult,
(uint16_t *)ADCBRESULT_BASE);
// Perform enough DMA_CH2_ADC_NO-word bursts to fill the results buffer. Data will be
// transferred 16 bits at a time hence the address steps below.
DMA_configBurst(DMA_CH2_BASE, DMA_CH2_ADC_NO, 1, 1);
DMA_configTransfer(DMA_CH2_BASE, 2 * ADC_OVER_SAMPLE_FACTOR, -DMA_CH2_ADC_NO + 1, 1);
DMA_configMode(DMA_CH2_BASE, DMA_TRIGGER_ADCB1,
(DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE |
DMA_CFG_SIZE_16BIT));
DMA_enableTrigger(DMA_CH2_BASE);
DMA_disableOverrunInterrupt(DMA_CH2_BASE);
DMA_setInterruptMode(DMA_CH2_BASE, DMA_INT_AT_END);
DMA_enableInterrupt(DMA_CH2_BASE);
}
1、没有调用DMA_startChannel();,可能你在其他地方配置了,如果没配置的话这儿需要配置。
2、没看到DMA_configWrap代码,目前看来这个配置没法实现一轮Transfer后回退到最初始地址。
另外我是用ePWM做的DMA触发,额外配置一路ePWM,将频率配置为你主PWM频率的倍数,这样就可以以固定倍数进行DMA触发了。你的主PWM可以设置触发中断,这样可以实现一个PWM周期内采样多次,并且只触发一次中断。下面是我之前的配置:
EPwm3Regs.TBPRD = EPWMPeriod_DC; EPwm3Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm3Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; EPwm3Regs.TBCTL.bit.PHSDIR = TB_UP; EPwm3Regs.TBCTL.bit.PRDLD = TB_SHADOW; EPwm3Regs.TBCTL.bit.PHSEN = TB_ENABLE; EPwm3Regs.TBPHS.bit.TBPHS = 0; EPwm3Regs.TBCTL.bit.CTRMODE = TB_COUNT_UPDOWN; EPwm3Regs.EPWMSYNCINSEL.bit.SEL = SYNC_IN_SRC_DISABLE_ALL; EPwm3Regs.EPWMSYNCOUTEN.bit.ZEROEN = SYNC_OUT_SRC_ENABLE; EPwm8Regs.TBPRD = EPWMPeriod_DC / 8; EPwm8Regs.TBCTL.bit.CLKDIV = TB_DIV1; EPwm8Regs.TBCTL.bit.HSPCLKDIV = TB_DIV1; EPwm8Regs.TBCTL.bit.PHSDIR = TB_UP; EPwm8Regs.TBCTL.bit.PRDLD = TB_SHADOW; EPwm8Regs.TBCTL.bit.PHSEN = TB_ENABLE; EPwm8Regs.TBPHS.bit.TBPHS = 0; EPwm8Regs.TBCTL.bit.CTRMODE = TB_COUNT_UP; EPwm8Regs.EPWMSYNCINSEL.bit.SEL = SYNC_IN_SRC_SYNCOUT_EPWM3; EPwm3Regs.ETSEL.bit.INTEN = 1; EPwm3Regs.ETSEL.bit.INTSEL = ET_CTR_PRD; EPwm3Regs.ETPS.bit.INTPRD = ET_1ST; EPwm8Regs.ETSEL.bit.SOCAEN = 1; EPwm8Regs.ETSEL.bit.SOCASEL = ET_CTR_ZERO; EPwm8Regs.ETPS.bit.SOCAPRD = ET_1ST; //// ADC_setInterruptSource(myADCB_BASE, ADC_INT_NUMBER1, ADC_SOC_NUMBER2); //// DMA_setEmulationMode(DMA_EMULATION_STOP); DMA_configAddresses(myDMA0_BASE, 5888, 2848); DMA_configBurst(myDMA0_BASE, 3U, 1, 16); DMA_configTransfer(myDMA0_BASE, 16U, -2, -31); DMA_configWrap(myDMA0_BASE, 16U, 0, 16U, 0); DMA_configMode(myDMA0_BASE, DMA_TRIGGER_ADCB1, DMA_CFG_ONESHOT_DISABLE | DMA_CFG_CONTINUOUS_ENABLE | DMA_CFG_SIZE_16BIT); DMA_enableTrigger(myDMA0_BASE); DMA_startChannel(myDMA0_BASE);
ePWM3作为主PWM,每个PWM周期内通过ePWM8触发采样,采样16次,每次采样3个信号:ADCB0,ADCB1,ADCB2。将ADCB0,ADCB1,ADCB2分别存于DMA_Data1,DMA_Data2,DMA_Data3中:
DMA_Data1 : origin = 0x001700, length = 0x000010
DMA_Data2 : origin = 0x001710, length = 0x000010
DMA_Data3 : origin = 0x001720, length = 0x000010
感谢。
上周末刚发完,加班琢磨了很久后,使用timer触发的方案已经可以了,是因为我没有将