OpenEdv-开源电子网

 找回密码
 立即注册
正点原子全套STM32/Linux/FPGA开发资料,上千讲STM32视频教程免费下载...
查看: 8035|回复: 13

关于ADC多通道采样的问题

[复制链接]

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2014-4-18
在线时间
0 小时
发表于 2014-5-8 18:49:39 | 显示全部楼层 |阅读模式
5金钱
在进行ADC多通道采样的程序中,我设置两个通道并采用扫描模式和单次转换模式,并根据EOC来读取采样的数据
初始化代码如下:


读取数据代码如下:


程序总是卡死在第二个while循环,查看资料发现,规则多通道ADC采样的时候,只有最后一个通道转换完成以后才置位EOC,后来看了下资料和视频发现,可以设置EOCS位,置位该位以后,对规则多通道进行采样时候,每个通道转换完毕都会置位EOC,但是我在手册上没有找到该位。请问各位这个存在吗?

另外附上EOCS位的信息:

最佳答案

查看完整内容[请看2#楼]

回复【5楼】bug_ken: --------------------------------- 这个我没试过,我百度了一下还是搜不回之前那篇文章。我大概记得是这样子:把AD转换的周期降低,你要两路的话,就先只开一路,转完后关掉,再开另外一路,这样循环下去,所以每次只有一个通道。               思路好像是这样子。。。。。不过不确定
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

47

主题

360

帖子

0

精华

高级会员

Rank: 4

积分
726
金钱
726
注册时间
2014-3-6
在线时间
19 小时
发表于 2014-5-8 18:49:40 | 显示全部楼层
回复【5楼】bug_ken:
---------------------------------
这个我没试过,我百度了一下还是搜不回之前那篇文章。我大概记得是这样子:把AD转换的周期降低,你要两路的话,就先只开一路,转完后关掉,再开另外一路,这样循环下去,所以每次只有一个通道。               思路好像是这样子。。。。。不过不确定
成长不是衣服越来越小,裤子越来越短,而是心和梦想一起越来越大!
回复

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2014-4-18
在线时间
0 小时
 楼主| 发表于 2014-5-8 18:49:40 | 显示全部楼层
回复【6楼】ljjdglg520:
---------------------------------
对,是你说的那样,在进行通道转换之前都要配置规则通道然后再使能ADC启动转换。网上也基本都是这么做的,但是回过头来想想,这种实现方法实质上还是单通道实现ADC采样。难道规则多通道ADC采样的实现方法必须使用DMA。我把实现代码贴在下面,供大家批评指正:

ADC多通道采样非DAM方式实现方法:
1.ADC初始化部分(注意只是一部分,GPIO、时钟都没有贴出来)
  /*初始化ADC1*/
ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; 
ADC_InitStructure.ADC_ScanConvMode = DISABLE; 
ADC_InitStructure.ADC_ContinuousConvMode = DISABLE; 
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; 
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; 
ADC_InitStructure.ADC_NbrOfChannel = 1; 
ADC_Init(ADC1, &ADC_InitStructure);

    /*使能ADC1*/
ADC_Cmd(ADC1, ENABLE);

    /*重置指定的ADC的校准寄存器*/
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));

    /*开始指定ADC的校准程序*/
ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));

2.转换函数:
u16 ADC1_GetValue(u8 channel)
{
u32 value;

ADC_RegularChannelConfig(ADC1, channel, 1, ADC_SampleTime_55Cycles5);
ADC_Cmd(ADC1, ENABLE);

ADC_SoftwareStartConvCmd(ADC1, ENABLE);
while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC));
value = ADC_GetConversionValue(ADC1);
ADC_SoftwareStartConvCmd(ADC1, DISABLE);

return (u16)value;
}
在本函数中只需要传入通道号就可以实现该通道数据的采集。如果不想传入通道号,还可以,在本函数中写个循环,对所有通道进行读取。
回复

使用道具 举报

120

主题

7878

帖子

13

精华

资深版主

Rank: 8Rank: 8

积分
12012
金钱
12012
注册时间
2013-9-10
在线时间
427 小时
发表于 2014-5-8 19:33:06 | 显示全部楼层
不是推荐你用DMA么,整个资料搜索也找不到EOCS?
现在,程序把烂铜烂铁变得智能化了,人呢,一旦离开了这烂铜烂铁就不知道干啥了
回复

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2014-4-18
在线时间
0 小时
 楼主| 发表于 2014-5-8 20:36:43 | 显示全部楼层
回复【2楼】Badu_Space:
---------------------------------
还没有考虑使用DMA,中文手册和应为手册都没有EOCS位。
回复

使用道具 举报

47

主题

360

帖子

0

精华

高级会员

Rank: 4

积分
726
金钱
726
注册时间
2014-3-6
在线时间
19 小时
发表于 2014-5-8 21:21:22 | 显示全部楼层
之前我写过一个用DMA的15路AD转换,你参考一下
 http://www.openedv.com/posts/list/31811.htm
成长不是衣服越来越小,裤子越来越短,而是心和梦想一起越来越大!
回复

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2014-4-18
在线时间
0 小时
 楼主| 发表于 2014-5-9 07:55:18 | 显示全部楼层
回复【4楼】ljjdglg520:
---------------------------------
谢谢,必须使用DMA吗,我就用两路AD转化,没有必要使用DMA吧。有没有非DMA的实现方式。
回复

使用道具 举报

47

主题

360

帖子

0

精华

高级会员

Rank: 4

积分
726
金钱
726
注册时间
2014-3-6
在线时间
19 小时
发表于 2014-5-9 15:14:29 | 显示全部楼层
回复【7楼】bug_ken:
---------------------------------
因为stm32里面只有一个地方存放AD转换的数据,如果不用DMA还能进行多路的话,除非你能做到,你要知道每个通道什么时候转换完,一转换完后要马上把数据取走。每个通道转换完成应该有标志位吧,我觉得应该有库函数能够判断这个。不过这些我没深入研究- -
成长不是衣服越来越小,裤子越来越短,而是心和梦想一起越来越大!
回复

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2014-4-18
在线时间
0 小时
 楼主| 发表于 2014-5-9 19:24:19 | 显示全部楼层
回复【8楼】ljjdglg520:
---------------------------------
有些STM32寄存器中有个EOCS位,当置位的时候,规则多通道转换,每次转换完成一个通道就会置位EOC,当EOCS为0时,规则通道全部转换完成后置位EOC。
但是我在我的寄存器手册的中没有找到该位(STM32F103RBT6),英文原版手册中也没有,所以现在我考虑使用DMA实现多通道ADC转换功能。

起初没有使用DMA是因为我只对两个通道进行转换,使用DMA就感觉暴殄天物一样,太浪费了。

另外你的15路ADC转换DMA实现方式代码我已经下载了,不错的,感谢!
回复

使用道具 举报

47

主题

360

帖子

0

精华

高级会员

Rank: 4

积分
726
金钱
726
注册时间
2014-3-6
在线时间
19 小时
发表于 2014-5-10 07:51:41 | 显示全部楼层
回复【9楼】bug_ken:
---------------------------------
可能只是没有EOCS位,但是我觉得应该有这样功能的位的,只是名字不同,虽然我也没查到。。。      另外,如果允许的话,干嘛不试一下用模拟开关来实现多路AD,那就不用DMA了
成长不是衣服越来越小,裤子越来越短,而是心和梦想一起越来越大!
回复

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2014-4-18
在线时间
0 小时
 楼主| 发表于 2014-5-10 08:22:06 | 显示全部楼层
回复【10楼】ljjdglg520:
---------------------------------
这也是一种方法,但是刚接触STM32不久,对模拟开关实现多路AD转换比较陌生,google下,网上对这方面的介绍还是比较少的。能不能提供下编程的思路,我试下。谢谢!
回复

使用道具 举报

47

主题

360

帖子

0

精华

高级会员

Rank: 4

积分
726
金钱
726
注册时间
2014-3-6
在线时间
19 小时
发表于 2014-5-10 09:28:34 | 显示全部楼层
回复【11楼】bug_ken:
---------------------------------
只用开一个AD通道,同时接2路模拟开关,比方说现在你要测A,B两个电压,对应模拟A开关,模拟B开关。因为模拟开关断开的时候可以视为非常大的阻值嘛,当你测A电压的时候,打开A模拟开关,断开B模拟开关,这时测的是A电压,与B相当于断开了;当你测B电压的时候,断开A模拟开关,打开B模拟开关,这时测的是B电压,与A相当于断开了。  在while(1)里面不停的扫描,就相当于同时测2路了,当然可能要适当延时一下。当然这个是我自己猜的,我没试过,不过我觉得可行性还挺大的,你有兴趣可以试下,再告诉我
成长不是衣服越来越小,裤子越来越短,而是心和梦想一起越来越大!
回复

使用道具 举报

4

主题

21

帖子

0

精华

初级会员

Rank: 2

积分
57
金钱
57
注册时间
2014-4-18
在线时间
0 小时
 楼主| 发表于 2014-5-10 10:54:56 | 显示全部楼层
回复【12楼】ljjdglg520:
---------------------------------
好的,大致意思我已经明白了,谢谢,如果试成功的话转告你一声;
另外昨晚把ADC多通道转换的DMA方式实现了,觉得还是不错的,多谢你的参考代码;
回复

使用道具 举报

1

主题

7

帖子

0

精华

新手上路

积分
31
金钱
31
注册时间
2015-1-16
在线时间
0 小时
发表于 2015-1-26 14:01:48 | 显示全部楼层
在STM32F4的资料中才有ECOS
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则



关闭

原子哥极力推荐上一条 /2 下一条

正点原子公众号

QQ|手机版|OpenEdv-开源电子网 ( 粤ICP备12000418号-1 )

GMT+8, 2025-6-26 08:58

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

快速回复 返回顶部 返回列表