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.
您好,
目前我计划通过DMA将ADC结果数据传输到SDRAM。
ePWM是我的ADC触发源。
ADC中断是DMA传输的触发源。
当我对ADC使用低采样率配置时,DMA工作正常,DMA中断即将出现。
但我通过提高ePWM频率提高了采样率(~1MSPS ),DMA中断不工作,但数据从ADC结果寄存器复制到SDRAM。
我无法找到任何解决此问题的方法,也无法找到为什么高速触发源出现此问题。
请告诉我,当我处理DMA的高速触发源时,如果我在这里遗漏了一些东西。
此外:是否确定未收到DMA溢出错误? SDRAM刷新过程有时可能需要很长时间(取决于SDRAM速度和刷新时钟),并且DMA (或更确切地说是SDRAM)可能无法跟上如此高的数据速率。
此致,
Andy
库拉库拉
您正在使用多少个DMA通道? 您在DMA ISR例程中做了什么? 正如AndyP所指出的,您是否遇到DMA超时错误?
此外,请分享您的DMA配置详细信息。
此致,
Manoj
您好,Manoj,
我只使用一个DMA通道。
在我的DMA ISR中,我正在更新我的DMA目标寄存器和目标卷影寄存器内容。 但DMA中断仅不会发生。但数据正通过DMA从源复制到目标。
到目前为止,我已经禁用了溢出中断。
这是我的DMA配置。
//
//远端内存中的缓冲区。
//
__attribute___(far) volatile uint16_t extSDRAMBuf[104.8576万];
void configDMAChannel1()
{
//
//配置DMA通道1 (16位数据大小)。
//
destDMA = extSDRAMBuf;
//srcDMA =(volatile uint16_t *) localSrcRAMBuf;
srcDMA =(volatile uint16_t *)(ADCBRESULT_base+2);
dma_configAddresses(DMA_CH1_base,(const void*)destdma,(const void*)srcdma);
DMA_configBurst (DMA_CH1_BASE,1U,1U);//机架式
//!@注释,要降低const src,请将trsnfer srcstep保持为零
dma_configTransfer (dma_ch1_base,1024,0U,1);
DMA_configWrap (DMA_CH1_BASE,0x1万U,0,0x1万U,0);
//
//将DMA触发源配置为软件,启用OneShot,禁用
//连续模式,DMA传输的数据大小为16位。
//
DMA_configMode (DMA_CH1_BASE,DMA_TRIGG_ADCB1,(DMA_CFG_OneShot_DISABLE
| DMA_CFG_CONTINUIENT_DISABLE | DMA_CFG_Size_16BIT);
//
//启用选定的外设触发器以在DMA上启动DMA传输
//通道1。
//
dma_enableTrigger (dma_ch1_base);
//dma_enableOverrunInterrupt (dma_ch1_base);
dma_disableOverrunInterrupt (dma_ch1_base);
DMA_setInterruptMode (DMA_CH1_BASE,DMA_INT_AT_END);
dma_enableInterrupt (dma_ch1_base);
//
//清除所有虚假外设中断标志。
//
dma_clearTriggerFlag (dma_ch1_base);
//
//清除所有虚假同步错误标志。
//
DMA_clearErrorFlag (DMA_CH1_BASE);
}
//DMA_ISR
__interrupt void dmach1ISR(void)
{
DMA_configDestAddress(DMA_CH1_BASE,(const void*)(extSDRAMBuf+(1024*USN_DMA_ISR_Counter));
dma_disableTrigger (dma_ch1_base);
dma_enableTrigger (dma_ch1_base);
dma_startChannel(DMA_CH1_base);
USN_DMA_ISR_Counter++;
在传输104.8576万(1M)样本后,//停止DMA
IF (USN_DMA_ISR_Counter >1024)
dma_stopChannel(DMA_CH1_base);
//
//通过删除SOC0的触发器来停止ADC
//
//ADC_setInterruptSOCTrigger (myADC0_BASE,ADC_SOC_NUMBER0,
// ADC_INT_SOC_TRIGG_NONE);
// ADC_setInterruptSOCTrigger (myADC1_BASE,ADC_SOC_NUMBER0,
// ADC_INT_SOC_TRIGG_NONE);
//
//确认中断
//
interrupT_clearACKGroup(interrupT_ACK_group7);
}
我已启用 溢出中断 ,但我不确定如何检查溢出是否发生 。请告诉我如何检查溢出是否发生
请检查CONTOL.OVRFLG标志位以了解是否发生过载情况。 另外,希望您认识到DMA中断不会发生在每个突发中,而是发生在每个传输中。
因此,在您的情况下,只有在每1024个字传输后才会得到DMA中断。
您好,Manoj,
我检查 了CONTROL.OVRFLG标志位,但它没有设置,并且始终为零。
我也有check control.ERRCLR标志,但它也始终为零。
但我观察到一种奇怪的行为,DMA中断正在发生,但不是在预期的时间间隔。
正如我 在前面的回答中所提到的,ADC中断是DMA通道的触发源,我在ADC_ISR例程中使用了UINT32_t计数器并递增,这样我就可以知道 发生了多少ADC转换以及 发生了多少次DMA触发。
然后我发现,对于ADC中断计数,DMA中断将出现12.2042万 (未修复,如果重置MCU并再次运行,则会有所变化),但由于我的DMA传输配置为1024,因此我预期在1024个ADC中断计数中会出现DMA中断。
第1个DMA中断发生在ADC中断的12.2042万个计数处(即遇到12.2042万 ADC中断)
第2个DMA中断发生 在 ADC中断的22.5192万个计数处
第3 个DMA中断发生 在 ADC中断的50.6195万次计数处。
这种模式 没有任何意义。 如果您重置MCU并重新开始测试,您将获得一些其他随机 数(ADC中断计数后的DMA中断)。
如果我降低ADC的采样率(100KSPS),则相同的配置工作正常, 在1024 个事务(1024个ADC中断计数)后DMA中断正常。
请告诉我,在处理 DMA (1MSPS ADC)的高速触发源时,如果我在这里漏掉了一些东西。
注:到目前为止,MCU上没有太多负载,仅 配置了1个ADC,1个ePWM,SDRAM和1个DMA通道。
也只配置和启用ADC中断和DMA中断。
如何与SDRAM (SPI (或) EMIF)连接? 是否有其它高优先级中断源会导致计数延迟? 您是否可以尝试写入F2.8388万D RAM位置,而不是写入SDRAM,并查看此问题是否消失? 我想知道此问题是否由SDRAM接口引起
我只与SDRAM和EMIF连接。
我的整个代码中只有两个中断,一个是ADC中断,另一个是DMA中断。 ADC中断(PIE组1矢量) 的优先级高于DMA中断(PIE组7矢量),并且也是必需的。
按照建议,我尝试 了F2.8388万D RAM作为DMA的目标,并对所有EMIF配置部分进行了注释,但行为 仍然相同。
我还将ADC采样速度降低到100ksps, DMA的工作方式与 F2.8388万D RAM相同 。
我觉得在DMA中,当它处理高速触发源时,只有一些问题。
但我没有找到哪个配置会导致 问题的确切原因。
库拉库拉
在您之前的帖子中,您曾报告您没有获得DMA中断。 我希望我们已经解决了这个问题。对吗?
现在,您的主要问题是我的DMA中断不应该是定期的(具有相同的周期计数)? 正确吗? 您可以私下向我发送电子邮件地址吗? 我希望通过WebEx通话来更好地了解问题?
此致,
Manoj
更改ADC配置后,DMA中断按预期工作。
在ADC配置中,我启用 了ADC中断的连续模式。
因此,无论是否设置了中断标志位,都将生成ADC中断。 因此,DMA可以完美地获得其事件触发器,DMA ISR也可以正常工作。
经过TRM后,我找到了这种模式。
特别感谢 Manoj Santha Mohan 的快速支持。
继续我之前的回答,我将在此处添加我的ADC配置代码详细信息。
//ADC初始化
void AdcA_init()
{
//myADC0初始化
// ADC初始化:写入ADC配置并为ADC通电
//配置模块到数字转换器模块预校准器。
ADC_setPrescaler (ADCA_BASE,ADC_CLK_DIV_1_0/*ADC_CLK_DIV_4_0*/);
//配置模数转换器分辨率和信号模式。
ADC_setMode (ADCA_BASE,ADC_Resolution _16BIT /*ADC_Resolution _12位*/,ADC_MODE_DIFFERC/*ADC_MODE_SINGLE_END_END_*/);
//设置转换脉冲结束的时间
ADC_setInterruptPulseMode (ADCA_BASE,ADC_PULSE_END_of_CONV);
//启动模数转换器内核。
ADC_enableConverter (ADCA_BASE);
//延迟1毫秒,以允许ADC有时间开机
DEVICE_DELAY _US (500);
// SOC配置:设置ADC ePWM通道和触发器设置
//禁用SOC突发模式。
//ADC_disableBurstMode (ADCA_BASE);2022年7月4日
//设置SOC的优先级模式。
ADC_setSOCPriPriority (ADCA_BASE,ADC_PRI_ALL ROL_ROUND);
//开始转换2配置
//在ADC中配置转换起点(SOC)及其中断SOC触发器。
// SOC编号:1.
//触发器:ADC_TRIGG_EPWM1_SOCA
//通道:ADC_CH_ADCIN0_ADCIN1.
//样例窗口:15个SYSCLK周期
//中断触发器:ADC_INT_SOC_TRIGG_NONE
ADC_setupSOC (ADCA_BASE,ADC_SOC_NUMBER0,ADC_TRIGATE_EPWM7_SOCA,ADC_CH_ADCIN0_ADCIN1,15U);
//由SOM-07-04-2022添加
ADC_ENableContinuousMode (ADCA_BASE,ADC_INT_NUMBER1);
ADC_setInterruptSOCTrigger (ADCA_BASE,ADC_SOC_NUMBER0,ADC_INT_SOC_TRIGTER_NONE);
// ADC中断1配置
// SOC/EOC号码:1.
//中断源:已启用
ADC_setInterruptSource (ADCA_BASE,ADC_INT_NUMBER1,ADC_SOC_NUMBER0);
ADC_enableInterrupt (ADCA_BASE,ADC_INT_NUMBER1);
ADC_clearInterruptStatus (ADCA_BASE,ADC_INT_NUMBER1);
中断注册(INT_ADCA1,&adcA1ISR);
INTERRUL_ENABLE (INT_ADCA1);
//ADCA_BASE
}
__interrupt void adcA1ISR(void)
{
}
注:DMA配置已添加到相同线程的先前响应中。
此致,
Someshwar K
L&T技术服务。