用DMA实现多路ADC通道数据采集

发布者:中华古风最新更新时间:2021-05-21 来源: eefocus关键字:DMA  多路ADC通道  数据采集 手机看文章 扫描二维码
随时随地手机看文章

找了不少例子参考,ADC和DMA的设置了解了个大概,并直接利用开发板来做一些实验来验证相关的操作,保证自己对各部分设置的理解。


我这里用了3路的ADC通道,1路外部变阻器输入,另外两路是内部的温度采样和Vrefint,这样就能组成连续的采样,来测试多通道ADC自动扫描了,ADC分规则转换和注入转换,其实规则转换就是按照既定的设定来顺序转换,而注入转换就是可以在这顺序队列中插队一样,能够提前转换了。


初始化设置:


 1 //PC0 FOR ANAGLE SAMPLE

 2 static void Protect_ClkInit(void)

 3 {

 4     RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1|RCC_APB2Periph_GPIOC,ENABLE);

 5     RCC_ADCCLKConfig(RCC_PCLK2_Div6);

 6     RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);

 7 }

 8 

 9 static void Protect_GPIOInit(void)

10 {

11     GPIO_InitTypeDef GPIO_InitStructure;

12 

13     /*GPIO PhaseA_H 初始化*/

14     GPIO_InitStructure.GPIO_Pin = ADC_PIN;

15     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;

16     GPIO_Init(TIMER_GPIO_AH_PORT, &GPIO_InitStructure);

17 }

18 

19 static void Protect_AdcInit(void)

20 {

21     ADC_InitTypeDef ADC_InitStructure;

22     

23     ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;

24     ADC_InitStructure.ADC_ScanConvMode = ENABLE;

25     ADC_InitStructure.ADC_ContinuousConvMode = DISABLE;

26     ADC_InitStructure.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;

27     ADC_InitStructure.ADC_DataAlign = ADC_DataAlign_Right;

28     ADC_InitStructure.ADC_NbrOfChannel = 3;

29     ADC_Init(ADC1, &ADC_InitStructure);

30     

31     ADC_TempSensorVrefintCmd(ENABLE);

32     ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_7Cycles5);

33     ADC_RegularChannelConfig(ADC1,ADC_Channel_TempSensor,2,ADC_SampleTime_7Cycles5);

34     ADC_RegularChannelConfig(ADC1,ADC_Channel_Vrefint,3,ADC_SampleTime_7Cycles5);

35     

36     ADC_DMACmd(ADC1, ENABLE);

37     /* Enable ADC1 external trigger */

38     ADC_ExternalTrigConvCmd(ADC1, DISABLE);

39 

40     ADC_Cmd(ADC1, ENABLE);

41 

42     ADC_ResetCalibration(ADC1);

43 

44     while(ADC_GetResetCalibrationStatus(ADC1));

45 

46     ADC_StartCalibration(ADC1);

47 

48     while(ADC_GetCalibrationStatus(ADC1));

49 

50 }

51 

52 static void Protect_DMAInit(void)

53 {

54 

55     DMA_InitTypeDef DMA_InitStructure;

56 

57     /* DMA1 channel1 configuration ----------------------------------------------*/

58     DMA_DeInit(DMA1_Channel1);

59     DMA_InitStructure.DMA_PeripheralBaseAddr = (uint32_t) & (ADC1->DR);

60     DMA_InitStructure.DMA_MemoryBaseAddr = (uint32_t)&ADCConvertedValue;

61     DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;

62     DMA_InitStructure.DMA_BufferSize = 3;

63     DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;

64     DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;

65     DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;

66     DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;

67     DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;

68     DMA_InitStructure.DMA_Priority = DMA_Priority_High;

69     DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;

70     DMA_Init(DMA1_Channel1, &DMA_InitStructure);

71 

72     /* Enable DMA1 channel1 */

73     DMA_Cmd(DMA1_Channel1, ENABLE);

74 }


设置好后测试,发现一个比较严重的问题,我在调变阻器的时候,发现会影响其他2路采样的数据,且数据变化比较大,我就先测试ADC的参考电压即Vref+和Vref-,没发现变化,那采样的初始化是否会有问题,在网上找了不少的资料,都没表明我的设置有问题,不过还是发现了一个不同,就是ADC_sampling_time的时间不同。那么我就把它设置成:


1ADC_RegularChannelConfig(ADC1,ADC_Channel_10,1,ADC_SampleTime_239Cycles5);


2ADC_RegularChannelConfig(ADC1,ADC_Channel_TempSensor,2,ADC_SampleTime_239Cycles5);


3ADC_RegularChannelConfig(ADC1,ADC_Channel_Vrefint,3,ADC_SampleTime_239Cycles5);


即最大的采样时间,结果发现确实是这个问题,后来又试了下其他几个采样时间,最短也要ADC_SampleTime_71Cycles5,不然数据都会被影响,大概采样周期不能太短, 不然DMA数据传输可能会被影响。


关键字:DMA  多路ADC通道  数据采集 引用地址:用DMA实现多路ADC通道数据采集

上一篇:STM32 CAN 控制器
下一篇:基于STM32单片机利用ST库函数设置Systick

推荐阅读最新更新时间:2024-11-12 19:00

SPI外设与USART外设之间通过DMA直接传输初步
选取DMA1 选取通道2 SPI1 USART3 根据上面这些配置初始化,参考32例程。 下面是我配置的SPI中断,我把它直接放在SPI初始化函数后面 先中断初始化 然后建立外设之间的连接 void SPI1_IRQHandler(void) USART3- DR=SPI1- DR; 再直接进行地址映射,把SPI1外设直接映射到USART3。 使能SPI的DMA发送请求PI_I2S_DMACmd(SPI1, SPI_I2S_DMAReq_Tx|SPI_I2S_DMAReq_Rx, ENABLE); 就会启动DMA 主函数
[单片机]
SPI外设与USART外设之间通过<font color='red'>DMA</font>直接传输初步
stm32之DMA彻底研究
在做实验之前,首先必须明白什么是DMA,DMA的作用又体现在哪里。 DMA,即直接内存存储,在一些数据的传输中,采用DMA方式,从而将CPU解放出来。让CPU有足够的时间处理其他的事情。 stm32使用DMA的相关操作: 1、DMA的配置 要配置的有DMA传输通道选择,传输的成员和方向、普通模式还是循环模式等等。 void DMA_Configuration(void) { DMA_InitTypeDef DMA_InitStructure; //DMA设置: //设置DMA源:内存地址&串口数据寄存器地址 //方向:内存-- 外设 //每次传输位:8bit //传输大小DMA_BufferSize=SENDBUFF_SI
[单片机]
基于USB的数据采集系统的设计与研究
  1引 言   数据采集作为获取信息的手段,越来越多的应用在各种工业系统中。目前数据采集系统多以PCI,ISA或。   EPP/ECP等完成数据的传输,这些方式开发调试比较困难,安装不便,通用性和可移植性差;而且PC上的插槽数量、地址、中断资源的有限导致这些方式的可扩展性差[1]。目前广泛应用的USB总线接口具有安装方便、高带宽、易于扩展等优点,USB 2.O的传输速率可达到480 Mb/s,已逐渐成为现代数据传输的发展趋势之一[2]。   2 EZ-USB FX2以及CY7C68013的特点   本文选择C2ypress公司LISB接口芯片CY7C268013(56一pin),该芯片属于EZ-IJSB FX2系列。
[嵌入式]
STM32 | 串口空闲中断接收不定长数据(DMA方式)
在使用STM32的串口接收数据的时候,我们常常会使用接收中断的方式来接收数据,常用的是RXNE。这里分享另一种接收数据的方式——IDLE中断(PS:本文的例子运行在STM32F103ZET6上)。 一、IDLE中断什么时候发生? IDLE就是串口收到一帧数据后,发生的中断。什么是一帧数据呢?比如说给单片机一次发来1个字节,或者一次发来8个字节,这些一次发来的数据,就称为一帧数据,也可以叫做一包数据。 二、RXNE中断和IDLE中断的区别? 当接收到1个字节,就会产生RXNE中断,当接收到一帧数据,就会产生IDLE中断。比如给单片机一次性发送了8个字节,就会产生8次RXNE中断,1次IDLE中断。 三、IDLE中断如何配
[单片机]
STM32 | 串口空闲中断接收不定长数据(<font color='red'>DMA</font>方式)
一文知道STM32 GUI的应用
整体上讲,很多STM32芯片内置了功能强大的用于加速图形处理的硬件加速器,借助它们一方面可以大大减轻CPU负荷,以节省CPU处理带宽去应对其它任务,另一方面,在节省内存同时还能保障动画或视频播放更为流畅。这些硬件图形加速器分别是STM32 Chrom-ART 加速器,或称DMA2D,是个专门用于二维图形操作处理的DMA;硬件JPEG 编解码器,用于对JPEG图像的编解码;STM32 Chrom-GRC,它是个内存管理单元,用于优化非方形图形显示的存储开销。 到目前为止,由于支持图形显示的STM32系列或料号很多,有时想基于STM32 的GUI应用做选型,可能要费一番功夫。这里有个表格,汇总了目前直接支持各类显示接口的STM32
[单片机]
一文知道STM32 GUI的应用
浅谈stm32f1两路adc采集(非DMA
由于项目的需要写2路ADC采集,发现采集的电压出现很大的误差。(后来换成ADC1和ADC2模式后解决了)仔细看了一下,不会是板子对应的引脚共用,那到底是怎么回事呢?想到了电路上的上拉电阻,测量出现的电压数值跳变不就是高阻态吗?在程序当中要是利用到上拉电阻不就搞定了吗!翻开某库函数关于ADC的介绍如下: STM32 拥有 1~3 个 ADC(STM32F101/102 系列只有 1 个 ADC),这些 ADC 可以独立使用,也可以使用双重模式(提高采样率)。STM32 的 ADC 是 12 位逐次逼近型的模拟数字转换器。 它有 18 个通道,可测量 16 个外部和 2 个内部信号源。各通道的 A/D 转换可以单次、连续、扫描
[单片机]
STM8L在USART中使用DMA来发送与接收数据
以USART为例子来使用DMA 分两部分,第一为,DMA这个外设自身的配置;第二为,USART的DMA部分配置, DMA与USART的DMA配置 void SYS_DMA_Init(void) { CLK_PeripheralClockConfig(CLK_Peripheral_DMA1, ENABLE); /span //打开时钟,很重要 /* Deinitialize DMA channels */ DMA_GlobalDeInit(); DMA_DeInit(DMA1_Channel1); DMA_DeInit(DMA1_Channel2); /* DMA channel Rx of USART Co
[单片机]
STM8L在USART中使用<font color='red'>DMA</font>来发送与接收数据
STM32笔记(三)ADCDMA、USART的综合练习
  我们在这里设置ADC为连续转换模式,常规转换序列中有两路转换通道,分别是ADC_CH10(PC0)和ADC_CH16(片内温度传感器)。因为使用了自动多通道转换,数据的取出工作最适合使用DMA方式取出,so,我们在内存里开辟了一个u16 AD_Value 数组,并设置了相应的DMA模块,使ADC在每个通道转换结束后启动DMA传输,其缓冲区数据量为2个HalfWord,使两路通道的转换结果自动的分别落到AD_Value 和AD_Value 中。   然后,在主函数里,就无需手动启动AD转换,等待转换结束,再取结果了。我们可以在主函数里随时取AD_Value中的数值,那里永远都是最新的AD转换结果。   如果我们定义一个更大的AD_
[单片机]
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved