一文搞定STM32F103双通道ADC_DMA采集,可拓展多通道

嵌入式ARM 2021-02-25 00:00


对于STM32F103来说,它的ADC是12位,一共18个通道,其中16个外部通道,2个内部通道。支持单次,连续以及间断模式扫描。


12位ADC

指的是STM32F103的ADC分辨率具有12位,位数越高采集到的ADC越精准。12位是相对于二进制数来说,也就是“111111111111”,转换为十进制就是4095,其实是0-4095,实际上是4096个数,STM32F103的引脚电压是0-3.3V,12位的ADC就会把0-3.3V切割成4096份。这样转换器得到的ADC值便可以转换为相应电压,设转换器采集到的ADC值为x,实际所求电压为y。那么公式为:y=x/4096*3.3V。

16个外部通道:

f103的芯片上有16个引脚是接到模拟电压上可以进行电压检测的,这16个通道会分给3个转换器,这三个转换器是独立的,也就是我们常见的ADC1,ADC2,ADC3。引脚和通道的对应关系可通过手册或者芯片引脚定义查询。

 

因为手册的引脚定义表太大,我这里就给出一个开发板原理图上的芯片引脚图。在图中可以看到哪个引脚有ADC通道。


这里挑一个典型进行说明:

比如PC0 标注的是ADC123_IN10,说明该引脚可以作为ADC引脚,而123说明该引脚可以被ADC1.ADC2,ADC3三个转化器共用。10对应上面所说的18个通道中的10通道。

ADC的使用:

我在使用该应用的时候是因为项目需要有一个有线遥控器连接控制板,遥控器上按键很多,如果采用外部中断或者按键扫描这种模式,那么每一个按键都需要连接控制板,造成IO口资源的浪费,同时连接线也会更粗,更贵。于是我们采用双排按键,每一排按键对应一个ADC的IO口,根据每个按键按下的电压不同来判断哪个按键被按下。

废话到此结束,让我们开始吧:

我们采用固件库的方式编写代码,那么就先初始化ADC的端口:

GPIO_InitTypeDef GPIO_InitStructure;RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA ,ENABLE);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_4;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;GPIO_Init(GPIOA, &GPIO_InitStructure);

首先还是走老路,初始化所用的GPIO,此次所用的是PA4和PA5。通过手册可以看到这两个口对应的是ADC1和ADC2,对应通道是通道4和通道5。


于是选择ADC1的通道4和通道5对ADC进行初始化:

ADC_InitTypeDef ADC_InitStructure; RCC_APB2PeriphClockCmd( RCC_APB2Periph_ADC1 ,ENABLE);RCC_ADCCLKConfig(RCC_PCLK2_Div6);//12M 最大14M

ADC_DeInit(ADC1); //将外设 ADC1 的全部寄存器重设为缺省值 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 = 2;//扫描通道数 ADC_Init(ADC1, &ADC_InitStructure);/* ADC1 regular channel10 configuration */ ADC_RegularChannelConfig(ADC1, ADC_Channel_4,1, ADC_SampleTime_71Cycles5); ADC_RegularChannelConfig(ADC1, ADC_Channel_5,2, ADC_SampleTime_71Cycles5); /* Enable ADC1 */ ADC_Cmd(ADC1, ENABLE); ADC_DMACmd(ADC1, ENABLE);/* Enable ADC1 reset calibaration register */  ADC_ResetCalibration(ADC1); //复位指定的ADC1的校准寄存器 /* Check the end of ADC1 reset calibration register */ while(ADC_GetResetCalibrationStatus(ADC1));//获取ADC1复位校准寄存器的状态,设置状态则等待/* Start ADC1 calibaration */  ADC_StartCalibration(ADC1); //开始指定ADC1的校准状态 /* Check the end of ADC1 calibration */ while(ADC_GetCalibrationStatus(ADC1)); //获取指定ADC1的校准程序,设置状态则等待/* Start ADC1 Software Conversion */ ADC_SoftwareStartConvCmd(ADC1, ENABLE); ADC_SoftwareStartConvCmd(ADC1, ENABLE); DMA_Cmd(DMA1_Channel1, ENABLE); //启动DMA通道

参数 ADC_Mode :是用来设置 ADC 的模式  ,ADC的模式很多(如下图),这里选择独立模式:ADC_Mode_Independent


参数ADC_ScanConvMode :规定了模数转换工作在扫描模式(多通道)还是单次(单通道)模式。可以设置这个参数为 ENABLE 或者 DISABLE。

参数ADC_ContinuousConvMode :规定了模数转换工作在连续还是单次模式。可以设置这个参数为 ENABLE 或者 DISABLE。

参数ADC_ExternalTrigConv :定义了使用外部触发来启动规则通道的模数转换 ,可取值如下图


参数ADC_DataAlign :规定了 ADC 数据向左边对齐还是向右边对齐。


参数ADC_NbreOfChannel :规定了顺序进行规则转换的 ADC 通道的数目 。我这里只用了双通道,所以为2.

函数ADC_RegularChannelConfig():这一步比较重要,上面我们初始化了ADC,但是并未指定引脚,也就是规则组通道,这里设置有规则组通道和转化顺序以及采样时间。根据上面所说,我们选择ADC1,通道4和5,顺序是通道4第一个采样,通道5第二个采样。ADC_SampleTime 设定了通道的 ADC 采样时间,可选参数如下:


DMA设置:

DMA_InitTypeDef DMA_InitStructure;
RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟 DMA_DeInit(DMA1_Channel1); DMA_InitStructure.DMA_PeripheralBaseAddr =(u32)&ADC1->DR; //DMA外设ADC基地 DMA_InitStructure.DMA_MemoryBaseAddr =(u32)&ADCConvertedValue;//内存地址 DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC;//dma传输方向单向 DMA_InitStructure.DMA_BufferSize = 100*2;//设置DMA在传输时缓冲区的长度 word DMA_InitStructure.DMA_PeripheralInc = DMA_PeripheralInc_Disable;//设置DMA的外设递增模式,一个外设 DMA_InitStructure.DMA_MemoryInc = DMA_MemoryInc_Enable;//设置DMA的内存递增模式, DMA_InitStructure.DMA_PeripheralDataSize = DMA_PeripheralDataSize_HalfWord;//外设数据字长 DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//内存数据字长 DMA_InitStructure.DMA_Mode = DMA_Mode_Circular;//设置DMA的传输模式:连续不断的循环模式 DMA_InitStructure.DMA_Priority = DMA_Priority_High;//设置DMA的优先级别 DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//设置DMA的2个memory中的变量互相访问 DMA_Init(DMA1_Channel1, &DMA_InitStructure); DMA_Cmd(DMA1_Channel1, ENABLE);

因为我在代码中做了备注,这里踢几个人比较重要的点:

参数DMA_BufferSize :设置DMA在传输时缓冲区的长度 ,这里要提一下我的数据储存数组u16 ADCConvertedValue[100][2];因为采用两个通道,所以需要两个缓冲保存数据,100*2=200,DMA在运行是就会采集200个ADC值保存在数组中,100个通道4的值,100个通道5的值。取值处理会在后面介绍。

此项设置完之后DMA就回不停地采集这两个ADC通道中的ADC值并保存在数组中。我们只需要在需要的时候读取数组中的值便可。

读取ADC值并做处理

 int sum; int sum1=0; int sum2=0;  int value1[10]; int value2[10]; int isSorted,temp1,temp2,k,p; float a; int i,j,c; float ADC_Value[2];//用来保存经过转换得到的电压值  for(c=0;c<10;c++){ for(i=0;i<2;i++) { sum=0; for(j=0;j<100;j++) { sum+=ADCConvertedValue[j][i]; } ADC_Value[i]=(float)sum*3.3/4096/100;//求平均值并转换成电压值
} value1[c]=(int)(ADC_Value[0]*100);//4通道电压值扩大100 value2[c]=(int)(ADC_Value[1]*100);//5通道电压值扩大100 }

END

本文系21ic论坛蓝v作者呐咯密密编纂



推荐阅读
呵,你会51单片机的精确延时吗?
关于画电路图的10大分歧,你站哪边?
早期MCU芯片是怎么加密的?


→点关注,不迷路←
嵌入式ARM 关注这个时代最火的嵌入式ARM,你想知道的都在这里。
评论
  • 铁氧体芯片是一种基于铁氧体磁性材料制成的芯片,在通信、传感器、储能等领域有着广泛的应用。铁氧体磁性材料能够通过外加磁场调控其导电性质和反射性质,因此在信号处理和传感器技术方面有着独特的优势。以下是对半导体划片机在铁氧体划切领域应用的详细阐述: 一、半导体划片机的工作原理与特点半导体划片机是一种使用刀片或通过激光等方式高精度切割被加工物的装置,是半导体后道封测中晶圆切割和WLP切割环节的关键设备。它结合了水气电、空气静压高速主轴、精密机械传动、传感器及自动化控制等先进技术,具有高精度、高
    博捷芯划片机 2024-12-12 09:16 87浏览
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-12 10:13 46浏览
  • 时源芯微——RE超标整机定位与解决详细流程一、 初步测量与问题确认使用专业的电磁辐射测量设备,对整机的辐射发射进行精确测量。确认是否存在RE超标问题,并记录超标频段和幅度。二、电缆检查与处理若存在信号电缆:步骤一:拔掉所有信号电缆,仅保留电源线,再次测量整机的辐射发射。若测量合格:判定问题出在信号电缆上,可能是电缆的共模电流导致。逐一连接信号电缆,每次连接后测量,定位具体哪根电缆或接口导致超标。对问题电缆进行处理,如加共模扼流圈、滤波器,或优化电缆布局和屏蔽。重新连接所有电缆,再次测量
    时源芯微 2024-12-11 17:11 115浏览
  • RK3506 是瑞芯微推出的MPU产品,芯片制程为22nm,定位于轻量级、低成本解决方案。该MPU具有低功耗、外设接口丰富、实时性高的特点,适合用多种工商业场景。本文将基于RK3506的设计特点,为大家分析其应用场景。RK3506核心板主要分为三个型号,各型号间的区别如下图:​图 1  RK3506核心板处理器型号场景1:显示HMIRK3506核心板显示接口支持RGB、MIPI、QSPI输出,且支持2D图形加速,轻松运行QT、LVGL等GUI,最快3S内开
    万象奥科 2024-12-11 15:42 88浏览
  • 应用环境与极具挑战性的测试需求在服务器制造领域里,系统整合测试(System Integration Test;SIT)是确保产品质量和性能的关键步骤。随着服务器系统的复杂性不断提升,包括:多种硬件组件、操作系统、虚拟化平台以及各种应用程序和服务的整合,服务器制造商面临着更有挑战性的测试需求。这些挑战主要体现在以下五个方面:1. 硬件和软件的高度整合:现代服务器通常包括多个处理器、内存模块、储存设备和网络接口。这些硬件组件必须与操作系统及应用软件无缝整合。SIT测试可以帮助制造商确保这些不同组件
    百佳泰测试实验室 2024-12-12 17:45 74浏览
  • 习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习笔记&记录学习习笔记&记学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记录学习学习笔记&记
    youyeye 2024-12-11 17:58 88浏览
  • 首先在gitee上打个广告:ad5d2f3b647444a88b6f7f9555fd681f.mp4 · 丙丁先生/香河英茂工作室中国 - Gitee.com丙丁先生 (mr-bingding) - Gitee.com2024年对我来说是充满挑战和机遇的一年。在这一年里,我不仅进行了多个开发板的测评,还尝试了多种不同的项目和技术。今天,我想分享一下这一年的故事,希望能给大家带来一些启发和乐趣。 年初的时候,我开始对各种开发板进行测评。从STM32WBA55CG到瑞萨、平头哥和平海的开发板,我都
    丙丁先生 2024-12-11 20:14 78浏览
  • 一、SAE J1939协议概述SAE J1939协议是由美国汽车工程师协会(SAE,Society of Automotive Engineers)定义的一种用于重型车辆和工业设备中的通信协议,主要应用于车辆和设备之间的实时数据交换。J1939基于CAN(Controller Area Network)总线技术,使用29bit的扩展标识符和扩展数据帧,CAN通信速率为250Kbps,用于车载电子控制单元(ECU)之间的通信和控制。小北同学在之前也对J1939协议做过扫盲科普【科普系列】SAE J
    北汇信息 2024-12-11 15:45 114浏览
  • 本文介绍瑞芯微RK3588主板/开发板Android12系统下,APK签名文件生成方法。触觉智能EVB3588开发板演示,搭载了瑞芯微RK3588芯片,该开发板是核心板加底板设计,音视频接口、通信接口等各类接口一应俱全,可帮助企业提高产品开发效率,缩短上市时间,降低成本和设计风险。工具准备下载Keytool-ImportKeyPair工具在源码:build/target/product/security/系统初始签名文件目录中,将以下三个文件拷贝出来:platform.pem;platform.
    Industio_触觉智能 2024-12-12 10:27 79浏览
  • 在智能化技术快速发展当下,图像数据的采集与处理逐渐成为自动驾驶、工业等领域的一项关键技术。高质量的图像数据采集与算法集成测试都是确保系统性能和可靠性的关键。随着技术的不断进步,对于图像数据的采集、处理和分析的需求日益增长,这不仅要求我们拥有高性能的相机硬件,还要求我们能够高效地集成和测试各种算法。我们探索了一种多源相机数据采集与算法集成测试方案,能够满足不同应用场景下对图像采集和算法测试的多样化需求,确保数据的准确性和算法的有效性。一、相机组成相机一般由镜头(Lens),图像传感器(Image
    康谋 2024-12-12 09:45 81浏览
  • 全球智能电视时代来临这年头若是消费者想随意地从各个通路中选购电视时,不难发现目前市场上的产品都已是具有智能联网功能的智能电视了,可以宣告智能电视的普及时代已到临!Google从2021年开始大力推广Google TV(即原Android TV的升级版),其他各大品牌商也都跟进推出搭载Google TV操作系统的机种,除了Google TV外,LG、Samsung、Panasonic等大厂牌也开发出自家的智能电视平台,可以看出各家业者都一致地看好这块大饼。智能电视的Wi-Fi连线怎么消失了?智能电
    百佳泰测试实验室 2024-12-12 17:33 66浏览
我要评论
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦