打印

stm32f051 adc 多通道DMA,仅第一个通道转换结果正确???

[复制链接]
6177|14
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
busdriver|  楼主 | 2013-5-12 22:16 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 busdriver 于 2013-5-12 22:17 编辑

发现只有第一个ADC通道比较准,后面的转换结果不准。请帮忙。
比如ADC_Channel_0对应DMA的RegularConvData_Tab[0],结果准确,后面从RegularConvData_Tab[1]就不准确。注释掉ADC_Channel_0,让ADC_Channel_1对应DMA的RegularConvData_Tab[0],结果神奇准确,后面从RegularConvData_Tab[1]依然不准确。
不知道说清楚没有,下面是程序代码。

#define ADC1_DR_Address                0x40012440
__IO uint16_t RegularConvData_Tab[5];
//__IO uint16_t RegularConvData_Tab[6];
uint32_t vdd_12v, vdd_5v5,vdd_3v3;



void ADC1_DMA_Config(void)
{
  ADC_InitTypeDef     ADC_InitStructure;
  GPIO_InitTypeDef    GPIO_InitStructure;
  DMA_InitTypeDef   DMA_InitStructure;
  /* ADC1 DeInit */  
  ADC_DeInit(ADC1);
  
  /* GPIOC Periph clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOC, ENABLE);
  
   /* ADC1 Periph clock enable */
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1, ENABLE);
  
  /* DMA1 clock enable */
  RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1 , ENABLE);
  
  /* Configure ADC Channel11 as analog input */
  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1 |GPIO_Pin_1 ;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);
  
  /* DMA1 Channel1 Config */
  DMA_DeInit(DMA1_Channel1);
  DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t)ADC1_DR_Address;
  DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)RegularConvData_Tab;
  DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;
  DMA_InitStructure.DMA_BufferSize = 5;
  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);
  /* DMA1 Channel1 enable */
  DMA_Cmd(DMA1_Channel1, ENABLE);
  
  /* ADC DMA request in circular mode */
  ADC_DMARequestModeConfig(ADC1, ADC_DMAMode_Circular);
  
  /* Enable ADC_DMA */
  ADC_DMACmd(ADC1, ENABLE);  
  
  /* Initialize ADC structure */
  ADC_StructInit(&ADC_InitStructure);
  
  /* Configure the ADC1 in continous mode withe a resolutuion equal to 12 bits  */
  ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
  ADC_InitStructure.ADC_ContinuousConvMode = ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
  ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Backward;
  ADC_Init(ADC1, &ADC_InitStructure);

  /* Convert the ADC1 Channel 1 with 55.5 Cycles as sampling time */
  //ADC_ChannelConfig(ADC1, ADC_Channel_0 , ADC_SampleTime_55_5Cycles);   
  ADC_ChannelConfig (ADC1, ADC_Channel_1  , ADC_SampleTime_55_5Cycles);
  ADC_ChannelConfig (ADC1, ADC_Channel_2, ADC_SampleTime_55_5Cycles);
  
  /* Convert the ADC1 temperature sensor  with 55.5 Cycles as sampling time */
  ADC_ChannelConfig(ADC1, ADC_Channel_TempSensor , ADC_SampleTime_55_5Cycles);  
  ADC_TempSensorCmd(ENABLE);
  
  /* Convert the ADC1 Vref  with 55.5 Cycles as sampling time */
  ADC_ChannelConfig(ADC1, ADC_Channel_Vrefint , ADC_SampleTime_55_5Cycles);
  ADC_VrefintCmd(ENABLE);
  
  /* Convert the ADC1 Vbat with 55.5 Cycles as sampling time */
  ADC_ChannelConfig(ADC1, ADC_Channel_Vbat , ADC_SampleTime_55_5Cycles);  
  //ADC_VbatCmd(ENABLE);
  
  /* ADC Calibration */
  ADC_GetCalibrationFactor(ADC1);
  
  /* Enable ADC1 */
  ADC_Cmd(ADC1, ENABLE);     
  
  /* Wait the ADCEN falg */
  while(!ADC_GetFlagStatus(ADC1, ADC_FLAG_ADEN));

  //ADC_DMACmd(ADC1, ENABLE);  

  /* ADC1 regular Software Start Conv */
  ADC_StartOfConversion(ADC1);

  //ADC_DMACmd(ADC1, ENABLE);  
}
沙发
busdriver|  楼主 | 2013-5-13 09:22 | 只看该作者
等解答。。谢谢

使用特权

评论回复
板凳
liushuwei12| | 2013-5-13 10:34 | 只看该作者
你的GPIO口设置错了,最后一位是GPIO_Pin_2;不是  GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0| GPIO_Pin_1 |GPIO_Pin_1 ;

使用特权

评论回复
地板
busdriver|  楼主 | 2013-5-13 11:06 | 只看该作者
多谢3楼兄弟花时间看代码并指出问题。非常感谢!

使用特权

评论回复
5
busdriver|  楼主 | 2013-5-13 12:11 | 只看该作者
为啥第二个通道不正确呢?应该正确的啊?晚上试试再说。。。谢谢

使用特权

评论回复
6
airwill| | 2013-5-13 14:15 | 只看该作者
另外, 还跟信号源的阻抗有关, 先降低采样速度试试吧

使用特权

评论回复
7
busdriver|  楼主 | 2013-5-13 20:03 | 只看该作者
本帖最后由 busdriver 于 2013-5-13 22:40 编辑

感谢大家。
仔细看过rm手册。
改了两个地方后,转换结果正常了。
1.    ADC_InitStructure.ADC_ScanDirection 改为upward,原来是backward
2.将    ADC_DMACmd(ADC1, ENABLE);放在  ADC_GetCalibrationFactor (ADC1);的后面。否则会错位,得益于6楼airwill的经验,谢谢!
另外问一下vrefint的电压值在哪里能读到,如果知道vrefint的电压值,根据adc读数,可以反推参考电压的值。因为参考电压接的是vcc,不是精确电压源,板子间存在差异。



使用特权

评论回复
8
busdriver|  楼主 | 2013-5-13 22:46 | 只看该作者
查了data sheet,vrefint号称1.2v

使用特权

评论回复
9
菜鸟宅男| | 2013-8-31 15:24 | 只看该作者
路过学习一下

使用特权

评论回复
10
A款硬币| | 2015-6-3 14:05 | 只看该作者
刚遇到这个问题,完美解决

使用特权

评论回复
11
A款硬币| | 2015-6-3 16:02 | 只看该作者
纠正一下,upward和backward只会影响ADC通道的转换顺序,对结果不会有影响

使用特权

评论回复
12
LSLDAY| | 2016-6-11 12:15 | 只看该作者
busdriver 发表于 2013-5-13 20:03
感谢大家。
仔细看过rm手册。
改了两个地方后,转换结果正常了。

楼主,你的解决了?我的问题和你差不多,但我是采集6通道,ADC0~ADC5只有前四个通道正确,不管从后往前扫描还是,从前往后扫描,都是前四个通道正确   但我看你这一楼指出的问题我都没犯啊已经折腾好几天了,求帮助

使用特权

评论回复
13
LSLDAY| | 2016-6-11 12:16 | 只看该作者
A款硬币 发表于 2015-6-3 14:05
刚遇到这个问题,完美解决

求教  求怎么解决的  我也是这个问题

使用特权

评论回复
14
busdriver|  楼主 | 2016-6-12 15:33 | 只看该作者
LSLDAY 发表于 2016-6-11 12:15
楼主,你的解决了?我的问题和你差不多,但我是采集6通道,ADC0~ADC5只有前四个通道正确,不管从后往前扫 ...

看7楼有答案

使用特权

评论回复
15
lin494| | 2016-11-25 10:26 | 只看该作者
学习了,感谢上面几位

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

44

主题

416

帖子

0

粉丝