STM32的ADC多通道采集的实现

发布者:自由思考最新更新时间:2018-05-20 来源: eefocus关键字:STM32  ADC  多通道采集 手机看文章 扫描二维码
随时随地手机看文章

在经过半个月的不懈努力下,终于将32的ADC多通道的信号采集完成,在网上能找到一些对于多通道信号采集的范例,要么就是用多个ADC,要么就是指贴出部分关键代码,也不对其中的配置及实现做一些细致的说明,这让人会走很多弯路,但也正是这样才能不断提升,才能认识自己的不足。好了,下面就先对STM的ADC做个简单的介绍;

         ADC又称'模拟/数字转换器',在STM32单片机中模拟/数字转换器(ADC)是一种提供可选择多通道输入,逐次逼近型的模数转换器。分辨率为12位,在一般的信号采集应用中已经算是很高的分辨率了。

        它有18个通道,可测量16个外部和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。

        下面就是对ADC多通道采集是如何实现做详细说明:
        第一:先讲讲大家在调试这功能可能遇到的一些困惑,我也是这样过来的,不知道你们是不是这样.
        1、范例是用DMA的方式对所采集到的数据进行的读取,这是我首先困惑的,存储到哪个地方去了,为此我还专门看了DMA(直接记忆存取/直接内存存取)到底是什么东西;
        2、我们就认为采集的数据已经被DMA提取并存储了,怎么把这么多通道的数据分离!!! 真滴是伤神~~~
        把上面这两个主要的大问题解决了,那么就能将这个模块调通,并能在实际中得到应用。16路信号的采集还不是小小的应用哟~~~

        下面上代码
//多通道转换函数
vu32 ADC_MultiChannelConvertedValue;
void ADC1_MultiChannel_Configuration(void)
{
        GPIO_InitTypeDef GPIO_InitStructure;
        DMA_InitTypeDef DMA_InitStruct;
        ADC_InitTypeDef ADC_InitStruct;


        //ADC input init PA0-7 AD0-7
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
        GPIO_InitStructure.GPIO_Pin = GPIO_PinSource0|GPIO_PinSource1|GPIO_PinSource2|GPIO_PinSource3|GPIO_PinSource4|GPIO_PinSource5|GPIO_PinSource6|GPIO_PinSource7;
        GPIO_Init(GPIOA,&GPIO_InitStructure);


        //ADC input init PB0-1 AD8-9
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
        GPIO_InitStructure.GPIO_Pin = GPIO_PinSource0|GPIO_PinSource1;
        GPIO_Init(GPIOB,&GPIO_InitStructure);


        //ADC input init Pc0-5 AD10-15
        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;
        GPIO_InitStructure.GPIO_Pin = GPIO_PinSource0|GPIO_PinSource1|GPIO_PinSource2|GPIO_PinSource3|GPIO_PinSource4|GPIO_PinSource5;
        GPIO_Init(GPIOC,&GPIO_InitStructure);
    
                
        DMA_DeInit(DMA1_Channel1);//开启DMA1的第一通道
        DMA_InitStruct.DMA_PeripheralBaseAddr = ADC1_DR_Address; //DMA对应的外设基地址
        DMA_InitStruct.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;
        DMA_InitStruct.DMA_MemoryBaseAddr = (unsigned long)&ADC_MultiChannelConvertedValue;        这就是单片机采集后存储的值的地址
        DMA_InitStruct.DMA_DIR = DMA_DIR_PeripheralSRC;
        DMA_InitStruct.DMA_M2M = DMA_M2M_Disable;
        DMA_InitStruct.DMA_MemoryDataSize = DMA_MemoryDataSize_Word;//DMA_MemoryDataSize_HalfWord  DMA搬运的数据尺寸,注意ADC是12位的,HalfWord就是16位。这个地方只有用word方式才能对位转换搬移,具体原因不详wxm
        DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Disable;
        DMA_InitStruct.DMA_MemoryInc = DMA_MemoryInc_Enable; //接收一次数据后,目标内存地址是否后移--重要概念,用来采集多个数据的,多通道的时候需要使能它
        DMA_InitStruct.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//接收一次数据后,设备地址是否后移
        DMA_InitStruct.DMA_Mode  = DMA_Mode_Circular;//转换模式,循环缓存模式,常用
        DMA_InitStruct.DMA_Priority = DMA_Priority_High;//DMA优先级,高
        DMA_InitStruct.DMA_BufferSize = 16;//DMA缓存大小,1*16个
        DMA_Init(DMA1_Channel1,&DMA_InitStruct);


        
        ADC_InitStruct.ADC_Mode = ADC_Mode_Independent; //转换模式,为独立转换
        ADC_InitStruct.ADC_ScanConvMode = ENABLE; 
        ADC_InitStruct.ADC_ContinuousConvMode = ENABLE; //连续转换模式开启
        ADC_InitStruct.ADC_ExternalTrigConv = ADC_ExternalTrigConv_None;//ADC外部触发开关,关闭 
        ADC_InitStruct.ADC_DataAlign = ADC_DataAlign_Right; //对齐方式,ADC结果是12位的,显然有个对齐左边还是右边的问题。一般是右对齐
        ADC_InitStruct.ADC_NbrOfChannel = 16; //开启通道数,16个
        ADC_Init(ADC1, &ADC_InitStruct); 

        /* Enable ADC1 */ 
        ADC_Cmd(ADC1, ENABLE); 
        /* Enable ADC1 reset calibaration register */    
        ADC_ResetCalibration(ADC1); 
        /* Check the end of ADC1 reset calibration register */ 
        while(ADC_GetResetCalibrationStatus(ADC1)); 
        /* Start ADC1 calibaration */ 
        ADC_StartCalibration(ADC1); 
        /* Check the end of ADC1 calibration */ 
        while(ADC_GetCalibrationStatus(ADC1));  
}
//多通道转换函数
u8 MultiChannel_AsciiBuff[5];
void Read_ADC1_MultiChannel(unsigned char u8_channNo)
{  
          unsigned short  ADC_data = 0;
        unsigned char i,id;
        ADC_SoftwareStartConvCmd(ADC1, DISABLE);
                
        for(i=16;i>0;i--)
        {        
                //ADC1,ADC 通道 x,规则采样顺序值为 1,采样时间为 7.5 周期,大于此周期除了通道 0 能识别外,其他不能识别
                ADC_RegularChannelConfig(ADC1, u8_channNo, 1, ADC_SampleTime_7Cycles5 );
                ADC_SoftwareStartConvCmd(ADC1, ENABLE);                         /* 软件启动 ADC1 */                
                do
                {
                        id = ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC);                         /* 读取转换标志 */
                }        while(!id);                                                                                 /* 等待,直到转换完成 */
                
                ADC_data += ADC_GetConversionValue(ADC1);                                这里将值读出,后面就是解析的过程咯
                ADC_SoftwareStartConvCmd(ADC1, DISABLE);                                 /* 软件停止 ADC1 */                                                                          
        }
                                 
        ADC_data = ADC_data >> 4;                                                                         /* 取 16 次采样平均值 */        
        ADC_data = (unsigned int)(((unsigned int)ADC_data)*3300>>12);/* 把采集到的数值转换成电压数据 */


        MultiChannel_AsciiBuff[0] = ADC_data/1000%10 + 0x30;
        MultiChannel_AsciiBuff[1] = ADC_data/100%10 + 0x30;
        MultiChannel_AsciiBuff[2] = ADC_data/10%10 + 0x30;                                                 /* 数据分离送 USART1 显示 */
        MultiChannel_AsciiBuff[3] = ADC_data%10 + 0x30;
        MultiChannel_AsciiBuff[4] = 0;


        USART1Write((u8*)MultiChannel_AsciiBuff,4);
        USART1Write((u8*)"\r\n",sizeof("\r\n"));


        //return (unsigned int)(((unsigned long)(ADC_data>>4))*3300>>12);
}       
        对于那两个问题的答案也在这里面。首先是DMA的存储地址,用横着的红线做了标记;对于采集数据的分离在最后一个红色竖线部分。呵呵,看着是不是就很简单咯~   

关键字:STM32  ADC  多通道采集 引用地址:STM32的ADC多通道采集的实现

上一篇:STM32下Keil IDE中Printf函数的使用
下一篇:使用Keil MDK运行第一个STM32程序

推荐阅读最新更新时间:2024-03-16 16:03

STM32使用内部振荡器及其和外部晶体振荡器的区别
在STM32上如果不使用外部晶振,OSC_IN和OSC_OUT的接法 如果使用内部RC振荡器而不使用外部晶振,请按照下面方法处理: 1)对于100脚或144脚的产品,OSC_IN应接地,OSC_OUT应悬空。 2)对于少于100脚的产品,有2种接法: 2.1)OSC_IN和OSC_OUT分别通过10K电阻接地。此方法可提高EMC性能。 2.2)分别重映射OSC_IN和OSC_OUT至PD0和PD1,再配置PD0和PD1为推挽输出并输出'0'。此方法可以减小功耗并(相对上面 首先要明确的是STM32没有内部晶振,HSI是内部RC振荡器。 HSI内部8MHz的RC振荡器的误差在1%左右 内部RC振荡器的精度通常比用HS
[单片机]
STM32之JTAG口作为普通IO使用
STM32F10x系列的MCU复位后,PA13/14/15 以及PB3/4默认配置为JTAG功能。有时我们为了充分利用MCU I/O口的资源,会把这些端口设置为普通I/O口。 JTAG对应IO JTMS -- PA13 JTCK -- PA14 JTDI -- PA15 JTDO -- PB3 JNRST -- PB4 SWD对应IO SWDIO -- PA13 SWCLK -- PA14 由对应IO关系可以看出,SWD只需用到PA13/JTMS、PA14/JTCK两根线,NREST可以接可不接,而剩下的PB4/JNTRST、PB3/JTDO和PA15/JTDI就可以当做普通IO使用,但是这三个口当做普通IO使
[单片机]
解析高速ADC和DAC与FPGA的配合使用
  许多数字处理系统都会使用FPGA,原因是FPGA有大量的专用DSP以及block RAM资源,可以用于实现并行和流水线算法。因此,通常情况下,FPGA都要和高性能的ADC和DAC进行接口,比如e2v EV10AQ190低功耗四通道10-bit 1.25 Gsps ADC和EV12DS130A内建4/2:1 MUX的低功耗12-bit 3 Gsps DAC。 通常情况下,这些转换器的采样率都达到了GHz的级别。对工程师团队来说,除了混合信号电路板布局之外,理解和使用这些高性能的设备也是一个挑战。   这些e2v数据转换器具有带宽宽、性能好的特点—数据手册上通常称为模拟全功率带宽—即使是在高奈奎斯特区。(这种能力是不多见的。)正是
[电源管理]
解析高速<font color='red'>ADC</font>和DAC与FPGA的配合使用
STM32FSMC机制FlaSh存储器扩展
  STM32是ST(意法半导体)公司推出的基于ARM内核Cortex-M3的32位微控制器系列。Cortex-M3内核是为低功耗和价格敏感的应用而专门设计的,具有突出的能效比和处理速度。通过采用Thumb-2高密度指令集,Cortex-M3内核降低了系统存储要求,同时快速的中断处理能够满足控制领域的高实时性要求,使基于该内核设计的STM32系列微控制器能够以更优越的性价比,面向更广泛的应用领域。   STM32系列微控制器为用户提供了丰富的选择,可适用于工业控制、智能家电、建筑安防、医疗设备以及消费类电子产品等多方位嵌入式系统设计。STM32系列采用一种新型的存储器扩展技术——FSMC,在外部存储器扩展方面具有独特的优势,可根据
[单片机]
STM32FSMC机制FlaSh存储器扩展
基于ADC采集和数据处理系统实现二氧化碳检测仪的设计
引言 在石油勘探过程中,二氧化碳检测是一项重要的录井工作,为后续的地质解释评价提供参考依据。从钻井液脱出的气体包括多种烃类气体、氢气、二氧化碳等,在采用红外光谱吸收法之前一般采用热导法检测二氧化碳,这种方法的缺点是易受其他气体的干扰。随着工艺的发展,红外发光源和红外传感器变得更加小巧,红外光谱吸收法逐渐取代了热导法。为了实现准确稳定的检测,除了采用性能优良的红外发光源和红外传感器外,信号采集处理部分也至关重要。其中,稳定可靠的ADC采集和高效的数据处理是二氧化碳检测系统的关键。 1 红外光谱吸收法原理 红外光谱吸收法是利用被测气体对红外光的特征吸收来实现气体成分的浓度分析。当对应某一气体具有特征吸收的光波通过这一被测气体时,其
[测试测量]
基于<font color='red'>ADC</font><font color='red'>采集</font>和数据处理系统实现二氧化碳检测仪的设计
非常见问题:从传感器到ADC的危途:工程师应如何做?
有没有一个模块能让我直接将微小的传感器输出信号转换为ADC输入电压? 有的,ADI公司最新仪表放大器系列可以一举完成如下任务:抑制共模信号,放大差模信号,将电压转换为符合要求的ADC输入电压,并且保护ADC免受过压影响! 在无数的工业、汽车、仪器仪表和众多其他应用中,普遍存在一项挑战,就是如何将微小的传感器信号正确连接到ADC,以实现数字化和数据采集。传感器信号通常很微弱,可能有很高噪声,看上去像是一个非常高的阻抗源,位于大共模(CM)电压之上。这些都是ADC输入所不乐见的。本文将介绍最新集成解决方案,可以彻底解决工程师提出的超出当前能力范围的问题。本文还会详细介绍设计步骤,以便配置一个完整的传感器接口仪表放大器来驱动AD
[汽车电子]
非常见问题:从传感器到<font color='red'>ADC</font>的危途:工程师应如何做?
关于STM32中断向量表的位置 、重定向问题
首先我们需要跳到main函数,这个就不多说了。那么,中断发生后,又是怎么跑到中断入口地址的呢? 从stm32f10x.s可以看到,已经定义好了一大堆的中断响应函数,这就是中断向量表,标号__Vectors,表示中断向量表入口地址,例如: AREA RESET, DATA, READONLY ; 定义只读数据段,实际上是在CODE区(假设STM32从FLASH启动,则此中断向量表起始地址即为0x8000000) EXPORT __Vectors IMPORT OS_CPU_SysTickHandler IMPORT OS_CPU_PendSVHandler __Vectors DC
[单片机]
关于<font color='red'>STM32</font>中断向量表的位置 、重定向问题
ST提升STM32开发速度,推出快捷应用开发平台
全球领先的微控制器厂商意法半导体(纽约证券交易所代码:STM)发布一款U盘版的开发平台STM32-comStick。这个低价的全功能开发平台有助于提高基于STM32互联系列微控制器的应用开发速度。STM32互联系列微控制器包括STM32F105和STM32F107两个子系列,于2009年6月投产,以先进的ARM® Cortex™-M3为内核,内置以太网、USB Device/Host/OTG、CAN和音频级I2S外设接口,为需要网络和通信功能的嵌入式应用提供低功耗的32位处理性能和实时特性。 STM32-comStick包括代码量无限制的Hitex HiTOP5 IDE/调试器和TASKING C编译器,可
[手机便携]
ST提升<font color='red'>STM32</font>开发速度,推出快捷应用开发平台
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
热门活动
换一批
更多
设计资源 培训 开发板 精华推荐

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

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

更多精选电路图
换一换 更多 相关热搜器件
更多每日新闻
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved