OpenEdv-开源电子网

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

STM32F051 3路ADC DMA 传输,数据错位,一个通道采不到值

[复制链接]

9

主题

20

帖子

0

精华

初级会员

Rank: 2

积分
97
金钱
97
注册时间
2011-11-12
在线时间
24 小时
发表于 2015-1-23 11:52:18 | 显示全部楼层 |阅读模式
5金钱

stm32f051 做AD采集, A0 接电位器  A1 接3.3V  A2  接GND
通过DMA中断的方式 取值,现在发现 取值结果
ADC_DMA_DAT[0]正常  
ADC_DMA_DAT[1] 为通道2的结果(0x0000)  通道2的跑到这里来了
ADC_DMA_DAT[2]无结果,搞了半天也没整出来,请大家帮我看看。

u16 ADC_DMA_DAT[3];
u16 AdcIa = 0;
u16 AdcIb = 0;
u16 AdcRt = 0;
u16 GetAdcState = 0;
u16 sss[3];

//http://blog.csdn.net/xuezhimeng2010/article/details/15157911
static void Adc_Gpio_Init()
{
 GPIO_InitTypeDef GPIO_InitStructure;
 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_GPIOA,ENABLE);
 
 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
 GPIO_InitStructure.GPIO_OType = GPIO_OType_PP;
 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 ;
 GPIO_InitStructure.GPIO_PuPd = GPIO_PuPd_NOPULL;
 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 GPIO_Init(GPIOA,&GPIO_InitStructure);
}

static void Adc_Dma_Init()
{
 DMA_InitTypeDef  DMA_InitStructure;
 NVIC_InitTypeDef NVIC_InitStructure;
 
 RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1,ENABLE);
 
 NVIC_InitStructure.NVIC_IRQChannel = DMA1_Channel1_IRQn;
 NVIC_InitStructure.NVIC_IRQChannelPriority = 0;
 NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
 NVIC_Init(&NVIC_InitStructure);
 
 DMA_InitStructure.DMA_BufferSize = 3;
 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//???è×÷????????
 DMA_InitStructure.DMA_M2M = DISABLE; //??????????????
 DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&ADC_DMA_DAT[0]; //?????????×???·
 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//?????ó???è????halfword
 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable; //???????·????
 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//DMA?­?·?????????ê???ó????????
 DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&(ADC1->DR);
 DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;// ???è?????ó???è????Halfword
 DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//???è???·????????
 DMA_InitStructure.DMA_Priority = DMA_Priority_High;//DMA???????è??????
 DMA_Init(DMA1_Channel1,&DMA_InitStructure);
 
 DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE);                 
 DMA_ClearITPendingBit(DMA_IT_TC);    //????????DMA????±ê??
  DMA_Cmd(DMA1_Channel1, ENABLE);  //????DMA1
}

void Adc_Init()
{
 ADC_InitTypeDef   ADC_InitStructure;
 
 Adc_Gpio_Init(); //GPIO Init
 Adc_Dma_Init();
 
 RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
 ADC_DeInit(ADC1);
 ADC_StructInit(&ADC_InitStructure);


 ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;
 ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;
 ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_T1_TRGO;
 ADC_InitStructure.ADC_Resolution = ADC_Resolution_12b;
 ADC_InitStructure.ADC_ExternalTrigConvEdge = ADC_ExternalTrigConvEdge_Rising;
 ADC_InitStructure.ADC_ScanDirection = ADC_ScanDirection_Upward;
 ADC_Init(ADC1,&ADC_InitStructure);
 
 ADC_OverrunModeCmd(ADC1,ENABLE); //????????·???????±???×?????????
 ADC_ChannelConfig(ADC1,ADC_Channel_0 | ADC_Channel_1 | ADC_Channel_2 ,
          ADC_SampleTime_28_5Cycles);  //?????¨???? ×????±??
 ADC_GetCalibrationFactor(ADC1);  // ?????°??×?ADC1
 
 ADC_Cmd(ADC1,ENABLE);
 while(ADC_GetFlagStatus(ADC1,ADC_FLAG_ADEN) == RESET); //wait for adc1 enable
 
 ADC_DMARequestModeConfig(ADC1,ADC_DMAMode_Circular); //????DMA???ó???????­?·??????
 
 ADC_StartOfConversion(ADC1); //?????????¨±????©
 ADC_DMACmd(ADC1,ENABLE); //????ADC_DMA
 
}

 

void DMA1_Channel1_IRQHandler() 
{    
 if(DMA_GetITStatus(DMA_IT_TC))                      //????DMA????????
  {        
  if(GetAdcState == 0) 
  { 
    AdcIa = ADC_DMA_DAT[0]; 
    AdcIb = ADC_DMA_DAT[1]; 
    AdcRt = ADC_DMA_DAT[2];
  //  GetAdcState = 1;   
  }  
    
    DMA_ClearITPendingBit(DMA_IT_TC);   //??DMA????±ê??
 }
}

最佳答案

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

看看ADC的初始化有没有放在DMA初始化后面,如果ADC先初始化的话,会出现数据错位的情况
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

6

主题

18

帖子

0

精华

初级会员

Rank: 2

积分
165
金钱
165
注册时间
2013-6-3
在线时间
24 小时
发表于 2015-1-23 11:52:19 | 显示全部楼层
看看ADC的初始化有没有放在DMA初始化后面,如果ADC先初始化的话,会出现数据错位的情况
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165540
金钱
165540
注册时间
2010-12-1
在线时间
2117 小时
发表于 2015-1-23 23:41:28 | 显示全部楼层
帮顶....
回复

使用道具 举报

1

主题

13

帖子

0

精华

初级会员

Rank: 2

积分
95
金钱
95
注册时间
2016-7-5
在线时间
22 小时
发表于 2016-7-12 13:06:38 | 显示全部楼层
http://blog.sina.com.cn/s/blog_542bad910101h5jy.html
这个帖子里重点讲解了为什么会数据错位,并且怎么处理。亲测有效!

要注意在初始化时将DMA_Cmd(DMA1_Channel1, ENABLE);放置到ADC_SoftwareStartConvCmd(ADC1, ENABLE);前面。

原因是:如果在初始化AD的时候DMA被触发了一次,但是此时并没有采样,但是DMA目的地址已经发生了自加,
当你采样第一路的时候,数据却填充到了第二路。

校准AD的时候会触发DMA导致通道错位,因此校准AD基准前不要启用DMA
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-7-5 20:18

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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