OpenEdv-开源电子网

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

求助:关于ADC多通道数据采集的问题

[复制链接]

4

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-1-3
在线时间
0 小时
发表于 2014-4-17 15:28:19 | 显示全部楼层 |阅读模式
我想用STM32实现ADC双通道数据采集并把采集到的数据不断的打印到串口。
程序如下:
void ADC1_GPIO_config(void)
{
  GPIO_InitTypeDef GPIO_Initstructure;

  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOC,ENABLE);

  GPIO_Initstructure.GPIO_Pin=GPIO_Pin_1|GPIO_Pin_2;
  GPIO_Initstructure.GPIO_Mode=GPIO_Mode_AIN;
  GPIO_Init(GPIOC,&GPIO_Initstructure);
}
void ADC1_config(void)
{
  ADC_InitTypeDef ADC_InitStructure;
  DMA_InitTypeDef DMA_InitStructure;
//配置DMA
  DMA_InitStructure.DMA_PeripheralBaseAddr = ADC1_DR_Address; //外设寄存器地址
  DMA_InitStructure.DMA_MemoryBaseAddr = (u32) ADC_ConvertedValue; //内存地址
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; 
  DMA_InitStructure.DMA_BufferSize = 2;  
  DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable; 
  DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; 
  DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord; 
  DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; 
  DMA_InitStructure.DMA_Mode = DMA_Mode_Circular; 
  DMA_InitStructure.DMA_Priority = DMA_Priority_High; 
  DMA_InitStructure.DMA_M2M = DMA_M2M_Disable; 
  DMA_Init(DMA1_Channel1, &DMA_InitStructure);

  ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;  //配置ADC
  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_InitStructure.ADC_NbrOfChannel = 2; 
  ADC_Init(ADC1, &ADC_InitStructure);

  RCC_ADCCLKConfig(RCC_PCLK2_Div8); //配置ADC时钟
  ADC_RegularChannelConfig(ADC1, ADC_Channel_11, 1, ADC_SampleTime_55Cycles5); //配置ADC通道
  ADC_RegularChannelConfig(ADC1, ADC_Channel_12, 2, ADC_SampleTime_55Cycles5); //配置ADC通道
  ADC_DMACmd(ADC1, ENABLE); //使能DMA
  ADC_Cmd(ADC1,ENABLE); //使能ADC

  ADC_ResetCalibration(ADC1); //复位校准寄存器
  while(ADC_GetResetCalibrationStatus(ADC1)); //等待复位完成
  ADC_StartCalibration(ADC1); //开始校准
  while(ADC_GetCalibrationStatus(ADC1)); //等待校准完成

  ADC_SoftwareStartConvCmd(ADC1, ENABLE); //软件触发
  DMA_Cmd(DMA1_Channel1, ENABLE);
}
void ADC1_init()
{
  ADC1_GPIO_config();
ADC1_config();
}
int main(void)
{
   u16 i;
 delay_init();
 WM_init();
 usart_config(115200);
 ADC1_init();
 while(1)
 {
     ADC_ConvertedValueLocal=(float) ADC_ConvertedValue[0]/4096*3.3;
 printf("\r\n The current V1=%f V \r\n",ADC_ConvertedValueLocal);
     ADC_ConvertedValueLocal=(float) ADC_ConvertedValue[1]/4096*3.3;
 printf("\r\n The current V2=%f V \r\n",ADC_ConvertedValueLocal);
 delay_ms(1000);
 }

}
程序参考网上的,输出结果不正确:有一路通道没有加电压,却偶尔会显示有电压,是不是数据发生错位?另外想问一下,DMA是什么时候将数据从外设转至内存,我想让ADC_ConvertedValue[0]显示通道1的电压,ADC_ConvertedValue[1]显示通道2的电压,但是ADC1的通道都共用ADC_DR寄存器,如何保证让DMA传一次ADC1通道1的数据下次传ADC1通道2的数据,而不是连着传两次ADC1通道1的数据。
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

38

主题

2061

帖子

6

精华

论坛大神

Rank: 7Rank: 7Rank: 7

积分
3273
金钱
3273
注册时间
2012-1-16
在线时间
37 小时
发表于 2014-4-17 15:54:01 | 显示全部楼层
站在巨人的肩膀上不断的前进。。。
回复 支持 反对

使用道具 举报

29

主题

311

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1530
金钱
1530
注册时间
2012-9-4
在线时间
262 小时
发表于 2014-4-17 16:26:08 | 显示全部楼层
首先 你没有加压的那一路肯定会有值输出的,这没啥问题,你上啦或下啦电阻就能解决这个问题;;;

DMA在你软件开启的时候就已经开始转移数据了,而且你通过DMA采集到的AD值是连续转换的,就应该是你要的
"让ADC_ConvertedValue[0]显示通道1的电压,ADC_ConvertedValue[1]显示通道2的电压"这个结果.....
STM32---STM32---STM32---STM32---STM32---STM32---STM32---STM32---STM32
回复 支持 反对

使用道具 举报

4

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-1-3
在线时间
0 小时
 楼主| 发表于 2014-4-17 16:56:48 | 显示全部楼层
回复【3楼】aben:
---------------------------------
会不会发生ADC通道1采样期间,DMA转移两个数据导致ADC_ConvertedValue[0]和ADC_ConvertedValue[1]都显示通道1数据的情况。因为DMA只负责在外设寄存器和内存地址间转移数据,它不会管寄存器的数据是否发生变化。
回复 支持 反对

使用道具 举报

29

主题

311

帖子

0

精华

金牌会员

Rank: 6Rank: 6

积分
1530
金钱
1530
注册时间
2012-9-4
在线时间
262 小时
发表于 2014-4-17 17:07:43 | 显示全部楼层
你两个通道嘛,你开个1K的数组
DMA_InitStructure.DMA_MemoryBaseAddr = (u32) ADC_ConvertedValue; //内存地址
DMA_InitStructure.DMA_BufferSize = 1000;


unsigned short ADC_ConvertedValue[1000];

一个通道插3.3V,一个通道插0V,你试试把ADC_ConvertedValue全打印出来,看一下结果...........
printf("ADC_ConvertedValue[%d]:%d\r\n",j,ADC_ConvertedValue[j]);
STM32---STM32---STM32---STM32---STM32---STM32---STM32---STM32---STM32
回复 支持 反对

使用道具 举报

4

主题

10

帖子

0

精华

新手上路

积分
46
金钱
46
注册时间
2014-1-3
在线时间
0 小时
 楼主| 发表于 2014-4-17 17:35:50 | 显示全部楼层
回复【5楼】aben:
---------------------------------
可以了,谢谢。
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2013-11-24
在线时间
0 小时
发表于 2014-4-28 17:33:36 | 显示全部楼层
你好,我也出现这个问题了,怎么解决的?????
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2013-11-24
在线时间
0 小时
发表于 2014-4-28 17:36:51 | 显示全部楼层
我的单个通道能够显示正确,但两个一起就不能显示了,能有一个通道的数据,另一个为0
回复 支持 反对

使用道具 举报

0

主题

4

帖子

0

精华

新手上路

积分
25
金钱
25
注册时间
2013-11-24
在线时间
0 小时
发表于 2014-4-28 19:42:06 | 显示全部楼层
最后改变一下端口,问题解决了。可能是一些端口被复用了
回复 支持 反对

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-7 19:59

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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