OpenEdv-开源电子网

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

STM32 AD多通道不用DMA采集,查了很多都是独立单次采集,然后多次调用,希望大神分析下这样为什么不可以??

[复制链接]

5

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2014-3-1
在线时间
1 小时
发表于 2014-3-1 17:33:03 | 显示全部楼层 |阅读模式
         
问下STM32多通道AD采集不用DMA,用多通道单次采集怎么发现数据很乱,求解。
代码如下:void Adc_Init(void)
{
ADC_InitTypeDef ADC_InitStructure;
GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1 , ENABLE ); //使能ADC1通道时钟

RCC_ADCCLKConfig(RCC_PCLK2_Div6); //72M/6=12,ADC最大时间不能超过14M
//PA0/1/2/3 作为模拟通道输入引脚
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2|GPIO_Pin_3;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN; //模拟输入引脚
GPIO_Init(GPIOA, &GPIO_InitStructure);

ADC_DeInit(ADC1); //将外设 ADC1 的全部寄存器重设为缺省值

ADC_InitStructure.ADC_Mode = ADC_Mode_Independent; //ADC工作模式:ADC1和ADC2工作在独立模式
ADC_InitStructure.ADC_ScanConvMode = ENABLE; //模数转换工作在单通道模式
ADC_InitStructure.ADC_ContinuousConvMode = ENABLE; //模数转换工作在单次转换模式
ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None; //转换由软件而不是外部触发启动
ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right; //ADC数据右对齐
ADC_InitStructure.ADC_NbrOfChannel = 4; //顺序进行规则转换的ADC通道的数目
ADC_Init(ADC1, &ADC_InitStructure); //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器

ADC_RegularChannelConfig(ADC1, ADC_Channel_0, 1, ADC_SampleTime_239Cycles5 ); //ADC1,ADC通道3,规则采样顺序值为1,采样时间为239.5周期
ADC_RegularChannelConfig(ADC1, ADC_Channel_1, 2, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_2, 3, ADC_SampleTime_239Cycles5 );
ADC_RegularChannelConfig(ADC1, ADC_Channel_3, 4, ADC_SampleTime_239Cycles5 );

ADC_Cmd(ADC1, ENABLE); //使能指定的ADC1

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

while(ADC_GetResetCalibrationStatus(ADC1)); //获取ADC1重置校准寄存器的状态,设置状态则等待

ADC_StartCalibration(ADC1); //开始指定ADC1的校准状态

while(ADC_GetCalibrationStatus(ADC1)); //获取指定ADC1的校准程序,设置状态则等待

//ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能

}

u16 ADC_CONVER(void)
{

ADC_SoftwareStartConvCmd(ADC1, ENABLE); //使能指定的ADC1的软件转换启动功能

while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_EOC ));//等待转换结束

return ADC_GetConversionValue(ADC1); //返回最近一次ADC1规则组的转换结果
}




然后再main函数调用:
int main(void)
{
u16 adcx;
float temp;
SystemInit();
delay_init(72); //延时初始化
NVIC_Configuration();
uart_init(9600);
LED_Init();
KEY_Init();
LCD_Init();
Adc_Init();
POINT_COLOR=RED;//设置字体为红色
LCD_ShowString(60,50,"Mini STM32");
LCD_ShowString(60,70,"ADC TEST");
LCD_ShowString(60,90,"ATOM@ALIENTEK");
LCD_ShowString(60,110,"2010/12/30");
//显示提示信息
POINT_COLOR=BLUE;//设置字体为蓝色
LCD_ShowString(60,130,"ADC_CH0_VAL:");
LCD_ShowString(60,150,"ADC_CH0_VOL:0.000V");
while(1)
{
adcx=ADC_CONVER();
LCD_ShowNum(156,130,adcx,4,16);//显示ADC的值
temp=(float)adcx*(3.3/4096);
adcx=temp;
LCD_ShowNum(156,150,adcx,1,16);//显示电压值
temp-=adcx;
temp*=1000;
LCD_ShowNum(172,150,temp,3,16);
LED0=!LED0;
delay_ms(1000);

}

}

发现数据不是先PA0,PA1,PA2,PA3的AD值的顺序,第一个(复位后)屏幕显示是PA3采集的,其它的有点紊乱。
怎么回事,谢谢大哥与各位朋友。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
21
金钱
21
注册时间
2015-3-21
在线时间
0 小时
发表于 2015-7-24 10:25:31 | 显示全部楼层
回复【2楼】745021926:
---------------------------------
多路采集,不用DMA?
回复 支持 1 反对 0

使用道具 举报

39

主题

2026

帖子

1

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
2020
金钱
2020
注册时间
2013-5-1
在线时间
87 小时
发表于 2014-3-1 21:25:24 | 显示全部楼层
参考下这个代码...

2.多路ADC实验.zip

354.04 KB, 下载次数: 8552

博观而约取,厚积而薄发。
回复 支持 1 反对 0

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165536
金钱
165536
注册时间
2010-12-1
在线时间
2117 小时
发表于 2014-3-1 22:01:43 | 显示全部楼层
回复【楼主位】小小飞行器:
--------------------------------- 
没这么用过,你还不如用我们例程提供的方式,去做。要哪个通道,给哪个通道。
我是开源电子网www.openedv.com站长,有关站务问题请与我联系。
正点原子STM32开发板购买店铺http://openedv.taobao.com
正点原子官方微信公众平台,点击这里关注“正点原子”
回复 支持 反对

使用道具 举报

5

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2014-3-1
在线时间
1 小时
 楼主| 发表于 2014-3-1 22:10:14 | 显示全部楼层
回复【2楼】745021926:
---------------------------------
谢谢大哥,刚看完你的,是一路一路的采集,这样思维比较明显,谢谢你啊!    
有空的话,你试试我上面的那样看看,我没调试成功,不知道Why,谢谢···
回复 支持 反对

使用道具 举报

5

主题

22

帖子

0

精华

初级会员

Rank: 2

积分
67
金钱
67
注册时间
2014-3-1
在线时间
1 小时
 楼主| 发表于 2014-3-1 22:11:47 | 显示全部楼层
回复【3楼】正点原子:
--------------------------------
OK,原子哥,一楼的就是你的思路。 
你有空的话,按照我用的看看,我查了很多,不知道为什么不行才发帖的····
谢谢你
回复 支持 反对

使用道具 举报

2

主题

4

帖子

0

精华

新手上路

积分
40
金钱
40
注册时间
2014-6-19
在线时间
2 小时
发表于 2014-10-29 21:29:24 | 显示全部楼层
中文手册里说的:
当所有通道都转换完成之后,ADC_SR EOC位才置1,所以当转换完成后ADC_DR寄存器的数据都是最后一个通道的数据。我是这么理解的。最好用哪个开哪个,


还有我觉得 val = ((temp*3300)/4095);

4095 更合适,但也有缺陷,就是运算速度不如
val = ((temp*3300)>>12);快
回复 支持 反对

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2014-2-28
在线时间
2 小时
发表于 2015-7-13 15:07:53 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
 好像 1楼的 也不对    问一下原子哥  我这边采集使用的AD不能 依次去采集,比如说采集220V的电压  是 定是采集某一个通道的 这样切换怎么弄呢
没有解决不了的问题 只有不努力的笨蛋
回复 支持 反对

使用道具 举报

5

主题

27

帖子

0

精华

初级会员

Rank: 2

积分
73
金钱
73
注册时间
2014-2-28
在线时间
2 小时
发表于 2015-7-13 15:08:36 | 显示全部楼层
回复【2楼】745021926:
---------------------------------
你这个 貌似不行的   逐次
没有解决不了的问题 只有不努力的笨蛋
回复 支持 反对

使用道具 举报

14

主题

81

帖子

0

精华

初级会员

Rank: 2

积分
183
金钱
183
注册时间
2015-5-25
在线时间
39 小时
发表于 2015-10-23 11:25:44 | 显示全部楼层
回复【2楼】745021926:
---------------------------------
多谢 哈哈
回复 支持 反对

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2015-9-1
在线时间
1 小时
发表于 2015-11-24 14:37:28 | 显示全部楼层
回复【4楼】小小飞行器:
---------------------------------
他这个我的显示屏显示不出来,怎么回事
回复 支持 反对

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2015-9-1
在线时间
1 小时
发表于 2015-11-24 14:46:33 | 显示全部楼层
回复【3楼】正点原子:
---------------------------------
原子哥,例程就一个通道啊
回复 支持 反对

使用道具 举报

1

主题

8

帖子

0

精华

新手上路

积分
41
金钱
41
注册时间
2015-9-1
在线时间
1 小时
发表于 2015-11-24 14:47:51 | 显示全部楼层
回复【2楼】745021926:
---------------------------------
你这个顺序是对了,可是为什么呢,还有一个问题就是,有几个通道,没有给采样信号显示屏显示都是4095 3.299v
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手上路

积分
29
金钱
29
注册时间
2015-12-28
在线时间
7 小时
发表于 2016-1-28 17:02:43 | 显示全部楼层
同样想知道这个问题
回复 支持 反对

使用道具 举报

2

主题

5

帖子

0

精华

新手上路

积分
24
金钱
24
注册时间
2016-1-28
在线时间
6 小时
发表于 2016-1-28 17:22:40 | 显示全部楼层
ADC_InitStructure.ADC_ScanConvMode = ENABLE;扫描模式打开后,只有把规则通道里的4个转换都转换完才产生一个EOC,也就是说你采集的结果只能是PA3,其它的结果都是
中间过程
回复 支持 反对

使用道具 举报

0

主题

7

帖子

0

精华

初级会员

Rank: 2

积分
59
金钱
59
注册时间
2016-5-7
在线时间
7 小时
发表于 2016-5-13 22:47:57 | 显示全部楼层
745021926 发表于 2014-3-1 21:25
参考下这个代码...

我参考你的部分程序,因为我只需要2路ad ,用的ADC1 CH1 和CH11 ,请问 :为什么CH11的值受CH1的影响啊?
择一城终老,遇一人白首....
回复 支持 反对

使用道具 举报

0

主题

2

帖子

0

精华

新手入门

积分
20
金钱
20
注册时间
2016-4-30
在线时间
3 小时
发表于 2016-5-17 20:13:46 | 显示全部楼层
为啥开五路不行啊?????
回复 支持 反对

使用道具 举报

0

主题

52

帖子

0

精华

初级会员

Rank: 2

积分
83
金钱
83
注册时间
2013-5-30
在线时间
3 小时
发表于 2016-5-19 16:43:28 | 显示全部楼层
学习了!非常感谢楼主!
做自己喜欢做的的事,爱自己所爱的人!
回复 支持 反对

使用道具 举报

0

主题

1

帖子

0

精华

新手入门

积分
18
金钱
18
注册时间
2016-6-12
在线时间
4 小时
发表于 2016-7-7 11:40:48 | 显示全部楼层
正在学习它。也是遇到这个问题。多通道不用DMA,只有一个通道有结果,用DMA,TMD,全部往后错一位。采集的时候 打开 DMA,用完AD数据再关闭DMA一样,往后错一位。好难用的芯片啊,怎么出厂的。
回复 支持 反对

使用道具 举报

1

主题

10

帖子

0

精华

新手上路

积分
37
金钱
37
注册时间
2016-7-19
在线时间
9 小时
发表于 2016-9-20 17:46:49 | 显示全部楼层
跟楼主一样,遇到同样的问题。。。 为什么不能按照下面这个函数设置的采样顺序逐次采样呢。。。同问
ADC_RegularChannelConfig(ADC1,ADC_Channel_3, 1,ADC_SampleTime_1Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_2, 2,ADC_SampleTime_1Cycles5);
ADC_RegularChannelConfig(ADC1,ADC_Channel_5, 3,ADC_SampleTime_1Cycles5);

但是按照原子提供的例程的思路,就可以了。。
回复 支持 反对

使用道具 举报

3

主题

138

帖子

0

精华

初级会员

Rank: 2

积分
195
金钱
195
注册时间
2014-5-12
在线时间
4 小时
发表于 2016-11-20 15:33:12 | 显示全部楼层
小东海单号 发表于 2015-11-24 14:37
回复【4楼】小小飞行器:
---------------------------------
他这个我的显示屏显示不出来,怎么回事

板子的屏幕引脚不同,他的应该是战舰的
回复 支持 反对

使用道具 举报

二十一画生1570 该用户已被删除
发表于 2017-2-4 13:08:47 | 显示全部楼层
提示: 作者被禁止或删除 内容自动屏蔽
回复 支持 反对

使用道具 举报

5

主题

103

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
453
金钱
453
注册时间
2016-8-8
在线时间
101 小时
发表于 2017-9-6 13:05:13 | 显示全部楼层
不知你的问题解决了没,我最近也在弄这个没有DMA的程序。
比你的还差,没数据。

如果你方便的话是否可以提供一个代码供我参考一下,非常感谢!!
如何拿下蒙住眼的树叶。
回复 支持 反对

使用道具 举报

9

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
189
金钱
189
注册时间
2017-12-12
在线时间
19 小时
发表于 2017-12-12 14:22:59 | 显示全部楼层
你这最多只能输出一个ADC的值,其他ADC通道的值main函数也没给循环输出?
回复 支持 反对

使用道具 举报

9

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
189
金钱
189
注册时间
2017-12-12
在线时间
19 小时
发表于 2017-12-12 17:14:46 | 显示全部楼层
老罗 发表于 2016-7-7 11:40
**** 作者被禁止或删除 内容自动屏蔽 ****

假如你没使用DMA位,你的ADC配置通道选单次模式好,如果你用了DMA位你可以用连续模式。
回复 支持 反对

使用道具 举报

9

主题

56

帖子

0

精华

初级会员

Rank: 2

积分
189
金钱
189
注册时间
2017-12-12
在线时间
19 小时
发表于 2018-1-22 10:05:39 | 显示全部楼层
ADC_InitStructure.ADC_ScanConvMode = ENABLE;        //模数转换工作在单通道模式
这一句的注释有问题



ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;        //模数转换工作在单次转换模式
这一句配置错了
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-6-9 04:15

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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