OpenEdv-开源电子网

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

3ADC的DMA传输实现失败

[复制链接]

48

主题

180

帖子

0

精华

初级会员

Rank: 2

积分
116
金钱
116
注册时间
2016-3-18
在线时间
88 小时
发表于 2016-4-7 14:10:23 | 显示全部楼层 |阅读模式
10金钱
如题,我选用的是ADC的规则同步传输模式ADC_TripleMode_RegSimult,ADC的DMA模式选用的是2型(根据资料,1型是ADC1,2,3一个个采然后一个个DMA传输,而三型是只能传输8位或者6位的数据,因此只能选择二型),根据手册,ADC1,2,3的数据应该是轮流出现在ADC->CDR寄存器的高低16位,也就是说第一次采集时,应该是低16位是ADC1的数据,高16位应该是ADC2的数据;在测试过程中低16位读取的数据是对的,但是高16位一直不对,请问是为啥?还是我有关ADC和DMA的模式选择不对吗?
代码如下:
void  Adc_Init(void)
{   
  GPIO_InitTypeDef  GPIO_InitStructure;
      ADC_CommonInitTypeDefADC_CommonInitStructure;
      ADC_InitTypeDef       ADC_InitStructure;



      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOA,ENABLE);
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOC,ENABLE);
      RCC_AHB1PeriphClockCmd(RCC_AHB1Periph_GPIOF,ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
      RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC2,ENABLE);
  RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC3,ENABLE);

  GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_4;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOA, &GPIO_InitStructure);

      GPIO_InitStructure.GPIO_Pin =GPIO_Pin_0|GPIO_Pin_1|GPIO_Pin_2;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOC, &GPIO_InitStructure);

     GPIO_InitStructure.GPIO_Pin= GPIO_Pin_6|GPIO_Pin_7|GPIO_Pin_8;
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AN;
  GPIO_InitStructure.GPIO_PuPd =GPIO_PuPd_NOPULL ;
  GPIO_Init(GPIOF, &GPIO_InitStructure);

      RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,ENABLE);     
      RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC1,DISABLE);
      RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,ENABLE);     
      RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC2,DISABLE);
      RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,ENABLE);     
      RCC_APB2PeriphResetCmd(RCC_APB2Periph_ADC3,DISABLE);  


  ADC_CommonInitStructure.ADC_Mode=ADC_TripleMode_RegSimult;
  ADC_CommonInitStructure.ADC_TwoSamplingDelay= ADC_TwoSamplingDelay_5Cycles;
  ADC_CommonInitStructure.ADC_DMAAccessMode=  ADC_DMAAccessMode_2;
  ADC_CommonInitStructure.ADC_Prescaler =ADC_Prescaler_Div4; ADC_CommonInit(&ADC_CommonInitStructure);

  ADC_InitStructure.ADC_Resolution =ADC_Resolution_12b;
  ADC_InitStructure.ADC_ScanConvMode = ENABLE;
  ADC_InitStructure.ADC_ContinuousConvMode =ENABLE;
  ADC_InitStructure.ADC_ExternalTrigConvEdge =ADC_ExternalTrigConvEdge_None;
  ADC_InitStructure.ADC_DataAlign =ADC_DataAlign_Right;
  ADC_InitStructure.ADC_NbrOfConversion = 3;
  ADC_Init(ADC1, &ADC_InitStructure);
      ADC_Init(ADC2, &ADC_InitStructure);

  ADC_DMACmd(ADC1, ENABLE);
      ADC_Cmd(ADC1, ENABLE);
  ADC_DMACmd(ADC2, ENABLE);
      ADC_Cmd(ADC2, ENABLE);
  ADC_DMACmd(ADC3, ENABLE);
      ADC_Cmd(ADC3, ENABLE);   

      ADC_RegularChannelConfig(ADC1,ADC_Channel_0, 1, ADC_SampleTime_3Cycles);
      ADC_RegularChannelConfig(ADC1,ADC_Channel_1, 2, ADC_SampleTime_3Cycles);
      ADC_RegularChannelConfig(ADC1,ADC_Channel_4, 3, ADC_SampleTime_3Cycles);
      ADC_RegularChannelConfig(ADC2,ADC_Channel_10, 1, ADC_SampleTime_3Cycles);
      ADC_RegularChannelConfig(ADC2,ADC_Channel_11, 2, ADC_SampleTime_3Cycles);
      ADC_RegularChannelConfig(ADC2,ADC_Channel_12, 3, ADC_SampleTime_3Cycles);
      ADC_RegularChannelConfig(ADC3,ADC_Channel_4, 1, ADC_SampleTime_3Cycles);
      ADC_RegularChannelConfig(ADC3,ADC_Channel_5, 2, ADC_SampleTime_3Cycles);
      ADC_RegularChannelConfig(ADC3,ADC_Channel_6, 3, ADC_SampleTime_3Cycles);



  ADC_SoftwareStartConv(ADC1);     
  ADC_SoftwareStartConv(ADC2);     
  ADC_SoftwareStartConv(ADC3);           
}         

MYDMA_Config(DMA2_Stream0,DMA_Channel_0,(u32)&ADC->CDR,(u32)&adcx,144);
MYDMA_Enable(DMA2_Stream0,144);




USB2.rar

11.37 MB, 下载次数: 372

最佳答案

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

...问题已解决,是这样的,我adc的采样是半字,但是他每次DMA传输的时候是两个数据合成一个传输,也就是字,所以在设定DMA传输模式的时候,要选择从外设:字 到内存:字,之前我一直选择的是半字,所以一直传输失败
正点原子逻辑分析仪DL16劲爆上市
回复

使用道具 举报

48

主题

180

帖子

0

精华

初级会员

Rank: 2

积分
116
金钱
116
注册时间
2016-3-18
在线时间
88 小时
 楼主| 发表于 2016-4-7 14:10:24 | 显示全部楼层
...问题已解决,是这样的,我adc的采样是半字,但是他每次DMA传输的时候是两个数据合成一个传输,也就是字,所以在设定DMA传输模式的时候,要选择从外设:字  到内存:字,之前我一直选择的是半字,所以一直传输失败
回复

使用道具 举报

48

主题

180

帖子

0

精华

初级会员

Rank: 2

积分
116
金钱
116
注册时间
2016-3-18
在线时间
88 小时
 楼主| 发表于 2016-4-7 14:14:28 | 显示全部楼层
关于ADC多重采样的两种模式规则同步模式和交替模式的运作我也不太明白,看手册上的时序图,规则同步模式是:三个ADC同时采样,然后转换完成后发送DMA请求。交替模式则是:ADC1先开启,采样,ADC2落后一段时间,开启,采样,ADC3再落后一段时间,开启采样。是这样吗?
ADC的DMA模式2中有一句话说是模式2只能用于规则同步和交替的双重采样,不能用于三重,如果是这样的话,那想要12位精度的采样岂不是只能用模式1?@正点原子
回复

使用道具 举报

66

主题

364

帖子

0

精华

初级会员

Rank: 2

积分
132
金钱
132
注册时间
2015-6-18
在线时间
129 小时
发表于 2016-4-7 15:07:39 | 显示全部楼层
帮顶      
回复

使用道具 举报

48

主题

180

帖子

0

精华

初级会员

Rank: 2

积分
116
金钱
116
注册时间
2016-3-18
在线时间
88 小时
 楼主| 发表于 2016-4-8 16:40:30 | 显示全部楼层
顶啊,求大神解读
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2016-4-9 21:34:40 | 显示全部楼层
帮顶
回复

使用道具 举报

530

主题

11万

帖子

34

精华

管理员

Rank: 12Rank: 12Rank: 12

积分
165371
金钱
165371
注册时间
2010-12-1
在线时间
2110 小时
发表于 2016-4-9 21:34:41 | 显示全部楼层
帮顶
回复

使用道具 举报

48

主题

180

帖子

0

精华

初级会员

Rank: 2

积分
116
金钱
116
注册时间
2016-3-18
在线时间
88 小时
 楼主| 发表于 2016-4-10 10:53:10 | 显示全部楼层
这个有一个错误是我的ADC3没使能,但是即使使能了还是不行,一旦使用了多重ADC模式,就无论怎么样数据都不对,按照说明书,应该是adcx的高位是adc2,低位是adc1,但是并不是这样,如果我adc1,接3.3V,adc2接地,那无论高位低位全都是3.3V
回复

使用道具 举报

5

主题

21

帖子

0

精华

中级会员

Rank: 3Rank: 3

积分
424
金钱
424
注册时间
2015-12-25
在线时间
39 小时
发表于 2016-4-10 21:31:48 | 显示全部楼层
mengheli 发表于 2016-4-7 14:10
...问题已解决,是这样的,我adc的采样是半字,但是他每次DMA传输的时候是两个数据合成一个传输,也就是字 ...

楼主啊,采集多路,只用一个ADC也行吧,我现在就是ADC1,轮流采集两路,没问题啊。
再有就是,你的DMA传输到那里去了?我想先传到SRAM,再传到SD卡(用FATFS文件系统),你会做吗?我最近在写AD,咱们交流一下吧
回复

使用道具 举报

48

主题

180

帖子

0

精华

初级会员

Rank: 2

积分
116
金钱
116
注册时间
2016-3-18
在线时间
88 小时
 楼主| 发表于 2016-4-11 14:48:20 | 显示全部楼层
marble 发表于 2016-4-10 21:31
楼主啊,采集多路,只用一个ADC也行吧,我现在就是ADC1,轮流采集两路,没问题啊。
再有就是,你的DMA传 ...

我也是DMA传输到文件系统,不够我那个精度要求高,所以必须用3AD
回复

使用道具 举报

11

主题

70

帖子

0

精华

高级会员

Rank: 4

积分
844
金钱
844
注册时间
2016-1-5
在线时间
208 小时
发表于 2016-4-11 16:32:19 | 显示全部楼层
楼主 我也是用的3个adc,可是为什么采集出来的数只有两个adc的呢
回复

使用道具 举报

48

主题

180

帖子

0

精华

初级会员

Rank: 2

积分
116
金钱
116
注册时间
2016-3-18
在线时间
88 小时
 楼主| 发表于 2016-4-11 16:42:08 | 显示全部楼层
明天起飞吧 发表于 2016-4-11 16:32
楼主 我也是用的3个adc,可是为什么采集出来的数只有两个adc的呢

....我也是啊!!!!交流一下啊!!我是第一次是12,第二次是13,然后就一直是13了,到不了23
回复

使用道具 举报

11

主题

70

帖子

0

精华

高级会员

Rank: 4

积分
844
金钱
844
注册时间
2016-1-5
在线时间
208 小时
发表于 2016-4-11 16:59:41 | 显示全部楼层
ADC_Init(ADC2, &ADC_InitStructure);  你没有对adc3初始化,adc3也能采集出数据?
回复

使用道具 举报

48

主题

180

帖子

0

精华

初级会员

Rank: 2

积分
116
金钱
116
注册时间
2016-3-18
在线时间
88 小时
 楼主| 发表于 2016-4-11 17:44:15 | 显示全部楼层
明天起飞吧 发表于 2016-4-11 16:59
ADC_Init(ADC2, &ADC_InitStructure);  你没有对adc3初始化,adc3也能采集出数据?

我前面已经纠正这个问题了,但是并没有用,还是不行
回复

使用道具 举报

48

主题

180

帖子

0

精华

初级会员

Rank: 2

积分
116
金钱
116
注册时间
2016-3-18
在线时间
88 小时
 楼主| 发表于 2016-4-11 17:51:15 | 显示全部楼层
明天起飞吧 发表于 2016-4-11 16:59
ADC_Init(ADC2, &ADC_InitStructure);  你没有对adc3初始化,adc3也能采集出数据?

直接加我QQ吧1747771947
回复

使用道具 举报

5

主题

19

帖子

0

精华

初级会员

Rank: 2

积分
94
金钱
94
注册时间
2015-7-21
在线时间
27 小时
发表于 2016-4-11 21:44:16 | 显示全部楼层
楼主楼主 ,这里菜鸟一只。想问问 采集单通道AD的电压用DMA传输 用串口看波形 怎么弄
回复

使用道具 举报

48

主题

180

帖子

0

精华

初级会员

Rank: 2

积分
116
金钱
116
注册时间
2016-3-18
在线时间
88 小时
 楼主| 发表于 2016-4-11 21:55:11 | 显示全部楼层
布衣江南 发表于 2016-4-11 21:44
楼主楼主 ,这里菜鸟一只。想问问 采集单通道AD的电压用DMA传输 用串口看波形 怎么弄

....我也没用过串口看波形啊,我只会采数据
回复

使用道具 举报

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

本版积分规则



关闭

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

正点原子公众号

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

GMT+8, 2025-2-26 20:09

Powered by OpenEdv-开源电子网

© 2001-2030 OpenEdv-开源电子网

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