Drencin 发表于 2024-12-27 10:48

GD32的DMA+ADC应用之二维数组转不动

#每日话题#
用GD32F103RC做一个ADC(5 channels)+DMA应用,当数据目的地址为二维数组时,无论怎么搞都会无法达到目的,详情如下:
uint16_t AD_buff;//设置5个数组对应5个ADC通道,每个数组含10个值
ADC0_CH0--> AD_buff[]
ADC0_CH1--> AD_buff[]
ADC0_CH2--> AD_buff[]
ADC0_CH3--> AD_buff[]
ADC0_CH4--> AD_buff[]
每次只采一个通道只转换一次只传输一次,使用ADC0转换完成事件请求DMA0传输数据,做一个中断服务程序,在中断服务程序中检查到DMA0传输完成后切换下一个ADC通道和传输目的地址(可以设置两个变量例如sample_index和channel_num代替数组的x/y序号),这意味着当ADC0_CH4采集数据并转换完成后又从ADC0_CH0开始,同时二维数组进一级(举例AD_buff切换到AD_buff)。周而复始。

问题是:DMA0只会在AD_buff ~ AD_buff循环,无论怎么尝试(开/关ADC0循环或开/关DMA0循环各种操作)都无法存入AD_buff ~ AD_buff。

郁闷了。最后取消DMA传输,只在中断服务程序是直接从ADC0存入数组。任务方面虽然完成了,但ADC+DMA存二维数组这种问题到处都没找到应用实例,望高手们尝试一下,看看到底什么原因。


Amazingxixixi 发表于 2024-12-27 11:10

可以二维转换为一维数组

Amazingxixixi 发表于 2024-12-27 11:10

可以二维转换为一维数组

Drencin 发表于 2024-12-27 13:45

当5个通道对应不同的物理量时,一维数组在利用时仍然需要重新分组处理,增加代码量。如果仅着眼于数据获得,甚至都不必用到DMA(前面已提到最终应用时已经放弃了DMA改用ADC中断直接存数组)。我只是想知道为什么二维数组DMA处理不了。

b5z1giu 发表于 2025-1-8 15:59

你遇到的问题是由于DMA的配置和ADC的触发机制没有正确配合导致的。DMA在传输数据时,通常是一次性传输一组数据,而你的需求是每次只传输一个通道的一个采样值,并且需要动态切换目标地址。

lamanius 发表于 2025-1-8 17:05

DMA通常配置为循环模式或单次模式。循环模式下,DMA会在固定的内存区域(如 AD_buff 到 AD_buff)之间循环传输,无法自动切换到下一列

w2nme1ai7 发表于 2025-1-8 18:12

你希望每次只采集一个通道的一个采样值,然后通过中断切换通道和目标地址。但DMA的配置可能没有正确支持这种动态切换。是不是没配置对呢?

l1uyn9b 发表于 2025-1-8 19:11

二维数组 AD_buff 在内存中是连续存储的,DMA需要正确配置目标地址的增量模式

p0gon9y 发表于 2025-1-8 20:18

每次DMA只传输一个采样值。在DMA传输完成后,通过中断重新配置DMA的目标地址。

lix1yr 发表于 2025-1-8 21:22

在DMA传输完成中断中,更新目标地址为下一列的位置。使用变量 sample_index 和 channel_num 来跟踪当前的行和列。

d1ng2x 发表于 2025-1-8 22:32

每次只转换一个通道的一个采样值。在ADC转换完成后触发DMA传输。

ex7s4 发表于 2025-1-8 23:46

DMA目标地址动态更新,在DMA传输完成中断中,更新目标地址为下一列的位置。

cen9ce 发表于 2025-1-9 10:05

每次DMA传输完成后,切换到下一个ADC通道。DMA配置为单次传输模式,每次只传输一个采样值。

y1n9an 发表于 2025-1-9 13:02

估计是你的DMA没配置对吧,而且一定要确保ADC的触发和DMA的传输时序正确。
页: [1]
查看完整版本: GD32的DMA+ADC应用之二维数组转不动