请教STC8H8K64U的DMA-ADC数据传输
第一次接触DMA,想用DMA-ADC功能实现对多路模拟量的采集,看手册没看懂,论坛里看到有个例程
(https://www.stcaimcu.com/forum.p ... 1494&extra=page%3D1),例程更没看懂。
主要问题是:ADC_DMA 接收地址寄存器(DMA_ADC_RXAx)的作用是什么?
从例程看,定义了外部存储器所需数据的存放地址,u8 xdata DmaBuffer _at_ DMA_ADDR;
但是,主程序中用了
DMA_ADC_RXAH = (u8)(DMA_ADDR >> 8); //ADC转换数据存储地址
DMA_ADC_RXAL = (u8)DMA_ADDR;
这明显是将外部数据往DMA_ADC_RXAx传送,这么传送的目的是什么?
那么DmaBuffer中的数据时怎么获得的?
将ADC设置好,将DMA设置好,启动一次DMA,硬件会自动帮你完成多通道ADC转换+平均值计算,DMA完成后你去读取结果即可,转换过程中不需要你的CPU去过问。下面的程序给你参考。
用户请先别修改程序, 直接下载"16-15路12位ADC转换-DMA-串口1(P3.1)返回结果-C语言"里的"ADC.hex"测试.
下载时选择主频11.0592MHZ. 测试时, 电脑的串口助手设置115200,8,n,1.
本程序演示15路ADC和bandgap DMA采样,通过串口1(P3.1)发送给上位机,波特率115200,8,n,1.
0~7通道对应P1.0 P1.1 P5.4 P1.3~P1.7, 8~14通道对应P0.0~P0.6, 15通道为内部1.19V基准电压做输入的ADC值.
梁工 发表于 2023-9-7 11:20
将ADC设置好,将DMA设置好,启动一次DMA,硬件会自动帮你完成多通道ADC转换+平均值计算,DMA完成后你去读取 ...
谢谢梁工{:4_196:},我详细看看哈。
不过这个程序和我给链接的程序完全是两个风格
本帖最后由 清风迎明月 于 2023-9-7 21:11 编辑
梁工 发表于 2023-9-7 11:20
将ADC设置好,将DMA设置好,启动一次DMA,硬件会自动帮你完成多通道ADC转换+平均值计算,DMA完成后你去读取 ...
梁工,你给这个程序继续请教一下,还是有地方看的不是很明白,但感觉理解应该八九不离十。
DMA_ADC_RXA= adc_tmp;
这句程序其实就是将ADC每次转换结果的相关数据的存放外部存储器首地址交代清楚了。
DMA—ADC的工作原理其实就是将每次获取的ADC的数据送入寄存器DMA_ADC_RXA,而DMA_ADC_RXA按指向首地址,结合转换次数等等按顺序去存放ADC各通道的相关数据。
我上面理解没有错吧?
不管是看手册,还是我给除链接的程序,还是你这个程序,一直纠结的是DMA_ADC_RXA寄存器的作用。
我给你那句程序加的注释如下:
DMA_ADC_RXA= adc_tmp; //将外部存放数据首地址赋给DMA_ADC_RXA
清风迎明月 发表于 2023-9-7 21:04
梁工,你给这个程序继续请教一下,还是有地方看的不是很明白,但感觉理解应该八九不离十。
DMA_ADC_RXA= ...
ADC DMA自动存放结果,则要给DMA指定存放的首地址。DMA_ADC_RXA= adc_tmp;就是给首地址。 梁工 发表于 2023-9-7 11:20
将ADC设置好,将DMA设置好,启动一次DMA,硬件会自动帮你完成多通道ADC转换+平均值计算,DMA完成后你去读取 ...
梁工,这个有视频教程的吗? link123 发表于 2024-7-11 13:49
梁工,这个有视频教程的吗?
简单应用,我没有视频。 本帖最后由 link123 于 2024-7-12 15:51 编辑
梁工 发表于 2024-7-11 17:07
简单应用,我没有视频。
梁工,里面代码有个不太懂的地方,
for(i=0; i<CHANNELS; i++)
{
Tx_ADC((u8)(adc_tmp>>8), adc_tmp);
}
这个代码为什么能输出平均值,假设我只开了通道0,16次转换,根据手册平均值的高位不是2n+2,低位不是2n+3吗?换成程序应该是adc_tmp和adc_tmp,image link123 发表于 2024-7-12 15:49
梁工,里面代码有个不太懂的地方,
for(i=0; i>8), adc_tmp);
}
请看我的变量定义,定义的注释已经说得很清楚:
#define CHANNELS 16 //定义DMA要扫描的ADC通道数
#define COUNTS 16 //定义每个ADC通道转换的次数
u16 xdata adc_tmp; //adc存放的数组, 为每次转换的值, 高字节为ADC通道号,低字节为取平均值后的余数,为平均值
我的DMA扫描CHANNELS=16通道,每个通道COUNTS=16次,则完成后,每个通道前面16个数据(数组下标0~15)就是ADC结果,下标16是通道号+平均值余数,下目标17就是平均值,这下明白了吧?
如果你只做一个通道,则只需要定义一个一维数组即可:
#define CHANNELS 16 //定义DMA要扫描的ADC通道数
u16 xdata adc_tmp;
数据的安排同上述。 这明显是将外部数据往DMA_ADC_RXAx传送,这么传送的目的是什么?
答:这是告诉DMA我要存放数据的首地址。
那么DmaBuffer中的数据时怎么获得的?
答:数据是DMA获取的。
页:
[1]
2