[M3]

STM32F103的多ADC基于DMA方式传输数据的错位现象

[复制链接]
1809|4
手机看帖
扫描二维码
随时随地手机跟帖
sunwave|  楼主 | 2016-12-20 08:53 | 显示全部楼层 |阅读模式
看了很多帖子说关于DMA的数据错位问题,没想到今天自己遇到了,麻烦搞过这方面内容的大侠给看看,问题出在哪里,具体如下:
我想通过ADC1采集通道11/12/13的数据,然后通过DMA送到数组volatile u16 AD_Value[53][3]中,即每个数据采集53次,共3组数据,现在数据可以采集到,但问题是通道数据顺序不对,本来数据排列顺序是ch11-ch12-ch13分别对应AD_Value[i][0]/AD_Value[i][1]/AD_Value[i][2],现在数据排列顺序是ch11-ch12-ch13分别对应AD_Value[i][2]/AD_Value[i][0]/AD_Value[i][1],不知为啥呢?
volatile u16 AD_Value[53][3];
1. ADC初始化
void ADC1_Configuration(u8 mode)
{
   ADC_InitTypeDef ADC_InitStructure;
   ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;
  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 = 3;
  ADC_Init(ADC1,&ADC_InitStructure);
  ADC_RegularChannelConfig(ADC1,ADC_Channel_11,1,ADC_SampleTime_239Cycles5);
  ADC_RegularChannelConfig(ADC1,ADC_Channel_12,2,ADC_SampleTime_239Cycles5);
  ADC_RegularChannelConfig(ADC1,ADC_Channel_13,3,ADC_SampleTime_239Cycles5);
  ADC_DMACmd(ADC1, ENABLE); //¿ªÆôADCµÄDMAÖ§³Ö
  ADC_Cmd(ADC1, ENABLE);
ADC_ResetCalibration(ADC1);
while(ADC_GetResetCalibrationStatus(ADC1));
  ADC_StartCalibration(ADC1);
while(ADC_GetCalibrationStatus(ADC1));
}
2.DMA初始化
void DMA_Config(void)
{
DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA传输时钟

DMA_DeInit(DMA1_Channel1); //将DMA的通道1寄存器重设为缺省值
//DMA1_MEM_LEN=cndtr;
//DMA_InitStructure.DMA_PeripheralBaseAddr = cpar;//DMA外设ADC基地址
DMA_InitStructure.DMA_PeripheralBaseAddr = (u32)&ADC1->DR;
//DMA_InitStructure.DMA_MemoryBaseAddr = cmar; //DMA内存基地址  G_AD_Value
DMA_InitStructure.DMA_MemoryBaseAddr = (u32)&AD_Value;
DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//外设作为数据传输的源
DMA_InitStructure.DMA_BufferSize = 159; //DMA通道的DMA缓存的大小
DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设地址寄存器不变
DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//内存地址寄存器递增Enable,
DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//Word 一个字  外设ADC基地址数据宽度为8位
DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord; //半个字_HalfWord;一字节_Byte; 内存基地址数据宽度为8位
DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//循环模式开启,Buffer写满后,自动回到初始地址开始传输
DMA_InitStructure.DMA_Priority = DMA_Priority_High; //DMA通道x拥有高优先级
DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;
DMA_Init(DMA1_Channel1,&DMA_InitStructure);
//DMA_Cmd(DMA1_Channel1, ENABLE);//启动DMA通道
DMA_ITConfig(DMA1_Channel1, DMA_IT_TC, ENABLE); //使能DMA传输完成中断

}

3、在主程序中调用Start_DMA()开启DMA,软件触发方式。
void Start_DMA(void)
{

ADC_Cmd(ADC1, ENABLE);
ADC_DMACmd(ADC1, ENABLE);
DMA_Cmd(DMA1_Channel1, ENABLE);  
ADC_SoftwareStartConvCmd(ADC1, ENABLE);
}

相关帖子

巧克力娃娃| | 2016-12-20 09:45 | 显示全部楼层
帮顶

使用特权

评论回复
皈依| | 2016-12-21 17:21 | 显示全部楼层
出现错位是ADC启动后未能及时使能DMA造成的
所以楼主你要先使能DMA 再使能ADC~

使用特权

评论回复
sunwave|  楼主 | 2016-12-21 19:25 | 显示全部楼层
皈依 发表于 2016-12-21 17:21
出现错位是ADC启动后未能及时使能DMA造成的
所以楼主你要先使能DMA 再使能ADC~ ...

我好像刚看过一个帖子说,要先ADC后DMA,究竟是哪个呢?

使用特权

评论回复
皈依| | 2016-12-21 19:27 | 显示全部楼层
sunwave 发表于 2016-12-21 19:25
我好像刚看过一个帖子说,要先ADC后DMA,究竟是哪个呢?

最好的办法 试一下

使用特权

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

本版积分规则

43

主题

154

帖子

5

粉丝