STM32的ADC详解

        ADC即模拟数字转换器,通常用于将外部的模拟量信号转换为数字信号。STM32的ADC是12位逐次逼近型的模拟数字转换器,最大可以计数到4095,有18个通道,16个外部通道和2个内部通道。

ADC框图

ADC的功能框图可以分为七个部分:

①输入电压:

        ADC输入范围为:VREF- ≤ VIN ≤ VREF+。由VREF-、 VREF+ 、VDDA 、VSSA、这四个外部引脚决定。

        我们在设计原理图的时候一般把VSSA和VREF-接地, 把VREF+和VDDA 接3V3,得到ADC的输入电压范围为:0~3.3V。 在64脚以下的CPU中,没有VREF-和VREF+这两个引脚,ADC电压输入范围直接由VDDA和VSSA决定。

②输入通道:STM32每个ADC有18个通道,16个外部通道和2个内部通道,具体通道和IO口的匹配关系如下表:

③通道分类:外部通道中又分为规则通道和注入通道,规则通道最多16个,注入通道最多4个。

规则通道:规则通道就是普通的通道,通常使用的都是规则通道。

注入通道:注入通道有点像中断,可以插入到规则通道组中,如果规则通道组转换过程中触发了注入通道,注入通道会打断规则通道的转换,所有注入通道转换完后规则通道才能继续转换。

 ④触发源:ADC触发转换的方式有两种,给ADC_CR2寄存器的ADON位写1或者通过外部事件触发,外部事件包括定时器触发,EXTI触发等。

⑤转换时间:ADC输入时钟ADC_CLK由PCLK2经过分频产生,最大是14M,分频因子由RCC时钟配置寄存器RCC_CFGR的位15:14 ADCPRE[1:0]设置, 可以是2/4/6/8分频,注意这里没有1分频。一般我们设置PCLK2=HCLK=72M。

        ADC使用若干个ADC_CLK周期对输入的电压进行采样, 采样的周期数可通过ADC 采样时间寄存器ADC_SMPR1和ADC_SMPR2中的SMP[2:0]位设置, ADC_SMPR2控制的是通道0~9,ADC_SMPR1控制的是通道10~17。每个通道可以分别用不同的时间采样。其中采样周期最小是1.5个, 即如果我们要达到最快的采样,那么应该设置采样周期为1.5个周期,这里说的周期就是1/ADC_CLK。

        ADC的转换时间公式为:Tconv = 采样时间 + 12.5个周期。当ADCLK = 14MHZ (最高), 采样时间设置为1.5周期(最快),那么总的转换时间(最短)Tconv = 1.5周期 + 12.5周期 = 14周期 = 1us,一般我们设置PCLK2=72M,经过ADC预分频器能分频到最大的时钟只能是12M(6分频),采样周期设置为1.5个周期, 算出最短的转换时间为1.17us,这个才是最常用的。

 ⑥数据寄存器:ADC 规则组数据寄存器 ADC_DR 是一个 32 位的寄存器,独立模式时只使用到该寄存器低 16 位保存 ADC1/2/3 的规则转换数据。因为 ADC 的精度是 12 位的,ADC_DR 寄存器无论高 16 位还是低 16,存放数据的位宽都是 16 位的,所以需要选择数据对齐方式是左对齐还是右对齐。规则组最多有 16 个输入通道,而 ADC 规则数据寄存器只有一个,如果使用多通道转换,那么这些通道的数据也会存放在 DR 里面,按照规则组的顺序,上一个通道转换的数据,会被下一个通道转换的数据覆盖掉,所以当通道转换完成后要及时把数据取走。比较常用的方法是使用 DMA 模式。当规则组的通道转换结束时,就会产生 DMA 请求,这样就可以及时把转换的数据搬运到用户指定的目的地址存放。注意:只有 ADC1 和 ADC3 可以产生 DMA 请求,而由 ADC2 转换的数据可以通过双 ADC 模式,利用 ADC1 的 DMA 功能传输。

⑦中断:ADC有三种中断,规则组转换结束中断,注入组转换结束中断和模拟看门狗中断。当输入模拟电压低于低阈值或高于高阈值时会触发模拟看门狗中断。

扫描模式和连续模式的区别

①扫描模式(Scan Mode):在扫描模式下,ADC可以配置为对多个输入通道进行连续转换。ADC将按照通道号的顺序对设置的多个通道进行转换,并将结果按顺序保存在对应的数据寄存器中。可以通过使用EOC(End of Conversion)标志或DMA传输等方式来获取每个通道的转换结果。

②连续模式(Continuous Conversion Mode):在连续转换模式下,ADC在完成一次转换后自动开始下一次转换,无需外部触发。这种模式适用于需要持续采样的应用场景,如数据采集。

具体到单通道和多通道的情况:

①单通道:在单通道的情况下,扫描模式失能,因为只有一个通道需要进行转换。如果配置为单次模式使能,则该通道转换一次后停止转换;如果配置为连续模式使能,则该通道会不断进行连续的转换。

②多通道:在多通道的情况下,必须使用扫描模式。如果配置为单次模式使能且扫描模式使能,则多个通道会按照配置的顺序依次转换一次后停止转换;如果配置为连续模式使能且扫描模式使能,则多个通道会按照配置的顺序依次转换一次后接着进行下一次转换,实现不断连续的转换。

综上所述,扫描模式只在多通道的条件下有效,使得各个通道按照配置循序依次转换。而单次模式无论在单通道还是多通道下只对这些或者这个通道进行一次转换,连续模式无论是在单通道还是多通道下都对这些或者这个通道不断进行连续的转换。

ADC多通道采集(DMA读取)实验

①使能ADC、DMA和ADC通道IO时钟

②设置ADC分频因子为6分频,72/6=12M

③配置ADC通道IO为模拟输入模式

④复位ADC

⑤配置ADC工作模式

⑥配置ADC规则通道转换顺序

⑦使能ADC,使能复位校准,等待校准技术,开启ADC校准,等待校准结束,使能ADC软件触发

⑧DMA通道复位

⑨DMA配置

⑩使能DMA,使能ADC的DMA

 volatile  uint16_t ADC_ConvertedValue[3]={0,0,0};	//存放ADC数据的缓冲区
//初始化ADC
//这里我们仅以规则通道为例
//我们默认将开启通道0~3                                                                       
void  Adc_Init(void)
{     
    ADC_InitTypeDef ADC_InitStructure; 
    GPIO_InitTypeDef GPIO_InitStructure;
    DMA_InitTypeDef DMA_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA |RCC_APB2Periph_ADC1, ENABLE );//使能ADC1通道时钟
    RCC_AHBPeriphClockCmd(RCC_AHBPeriph_DMA1, ENABLE);//使能DMA时钟
 

    RCC_ADCCLKConfig(RCC_PCLK2_Div6);   //设置ADC分频因子6 72M/6=12,ADC最大时间不能超过14M

    //PA1为ADC通道1 作为模拟通道输入引脚                         
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //模拟输入引脚
    GPIO_Init(GPIOA, &GPIO_InitStructure);    
    
     //PA2为ADC通道2 作为模拟通道输入引脚                         
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //模拟输入引脚
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
     //PA3为ADC通道3 作为模拟通道输入引脚                         
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AIN;        //模拟输入引脚
    GPIO_Init(GPIOA, &GPIO_InitStructure);
    
    

    ADC_DeInit(ADC1);  //复位ADC1,将外设 ADC1 的全部寄存器重设为缺省值

    ADC_InitStructure.ADC_Mode = ADC_Mode_Independent;    //ADC工作模式:工作在独立模式,只用到一个ADC
    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数据右对齐
    ADC_InitStructure.ADC_NbrOfChannel = 3;    //顺序进行规则转换的ADC通道的数目
    ADC_Init(ADC1, &ADC_InitStructure);    //根据ADC_InitStruct中指定的参数初始化外设ADCx的寄存器   
    
    //配置ADC规则通道转换顺序
    ADC_RegularChannelConfig(ADC1,ADC_Channel_1,1,ADC_SampleTime_239Cycles5);
    ADC_RegularChannelConfig(ADC1,ADC_Channel_2,2,ADC_SampleTime_239Cycles5);
    ADC_RegularChannelConfig(ADC1,ADC_Channel_3,3,ADC_SampleTime_239Cycles5);
    
    
    ADC_Cmd(ADC1, ENABLE);    //使能指定的ADC1
    
    ADC_ResetCalibration(ADC1);    //使能复位校准  
     
    while(ADC_GetResetCalibrationStatus(ADC1));    //等待复位校准结束
    
    ADC_StartCalibration(ADC1);     //开启AD校准
 
    while(ADC_GetCalibrationStatus(ADC1));     //等待校准结束
 
    ADC_SoftwareStartConvCmd(ADC1, ENABLE);        //使能指定的ADC1的软件转换启动功能

    //DMA初始化
    DMA_DeInit(DMA1_Channel1);//DMA通道复位
    
    DMA_InitStructure.DMA_BufferSize = 3;//三路通道,缓冲区为3
    DMA_InitStructure.DMA_DIR = DMA_DIR_PeripheralSRC; //数据传输方向由外设到内存
    DMA_InitStructure.DMA_M2M = DMA_M2M_Disable;//没用到内存到内存传输
    DMA_InitStructure.DMA_MemoryBaseAddr = (u32)ADC_ConvertedValue;//分配内存地址
    DMA_InitStructure.DMA_MemoryDataSize = DMA_MemoryDataSize_HalfWord;//设置内存数据宽度为半字
    DMA_InitStructure.DMA_MemoryInc=DMA_MemoryInc_Enable;//内存地址进行增加,因为需要进行对数据的存储
    DMA_InitStructure.DMA_Mode=DMA_Mode_Circular;//设置传输模式位连续不断的循环模式
    DMA_InitStructure.DMA_PeripheralBaseAddr=( u32 ) ( & ( ADC1->DR ) );//DMA的外设基地址
    DMA_InitStructure.DMA_PeripheralDataSize=DMA_PeripheralDataSize_HalfWord;//设置外设数据字长
    DMA_InitStructure.DMA_PeripheralInc=DMA_PeripheralInc_Disable;//外设的基地址是否进行增加,否
    DMA_InitStructure.DMA_Priority=DMA_Priority_High;//设置DMA的转换的优先级为高优先级
    DMA_Init(DMA1_Channel1,&DMA_InitStructure);
    
    DMA_Cmd( DMA1_Channel1 , ENABLE);// 使能 DMA 通道
    ADC_DMACmd(ADC1,ENABLE);//使能ADC1的DMA

//    ADC_SoftwareStartConvCmd(ADC1, ENABLE);        //使能指定的ADC1的软件转换启动功能
}                  

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/609747.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

6个让你的活动策划成倍回报的策略-华媒舍

活动策划是一个集思广策、全方位考虑的过程,只有通过科学合理的策略规划,才能在有限的资源下取得最大的回报。本文将分享六个让你的活动策划成倍回报的策略,包括目标设定、策划团队、预算控制、宣传推广、参与体验和后期回顾。 1. 目标设定 …

基于LMV358的负电源架构

嘿UU们,中午好啊!吃了没?算算时间我的餐桌上应该快上杨梅和鱼胶冻了。 今天看某群,突然想到Jim williams的书里一个架构,但老爷子的东西是正负输出的,而且略微有点麻烦,我就想怎么样整个更适合…

【小笔记】streamlit使用笔记

【小笔记】streamlit使用笔记 1.streamlit是什么,为什么要用它? 一句话,这个东西是一个python的可视化库,当你想要给你的程序添加个web界面,而又不会或不想用前端技术时,你就可以考虑用它。 类似的可视化库…

论文AI率太高怎么办?笔灵aigc去痕AIGC率直降60%

随着 AI 技术迅猛发展,各种AI辅助论文写作的工具层出不穷! 为了防止有人利用AI工具进行论文代写,在最新的学位法中已经明确规定“已经获得学位者,在获得该学位过程中如有人工智能代写等学术不端行为,经学位评定委员会…

初识Java的main方法

创建一个Java文件 main方法以及用cmd运行程序的过程 面试题JDK\JRE\JVM之间的关系 注意事项 解析String[ ] args 我们想知道String[ ] args里面到底是什么,我们可以用for循环遍历这个数组 Java代码结构 编写Java程序时可能会遇见的错误 注释 注释是为了让代码更…

音频系统模块级实验

加zkhengyang进数字音频系统研究开发交流答疑群(课题组) 1 购买ADC-I2S模块,购买I2S-DAC模块 进行音频系统搭建,可加深对i2s音频总线的理解 2 用电脑的音频输出进行实验

[JAVASE] 类和对象(一)

目录 一.类的基本定义 1.1 类与对象 1.2 类的定义 二. 类的实例化 2.1 创建引用 三. 类中成员的访问 3.1 基本实现 3.2 this引用 四. 构造与初始化 4.1 初始化 4.2 构造方法 五. 总结 一.类的基本定义 1.1 类与对象 类对应着对象 1.2 类的定义 二. 类的实例化 2.1 创建引用…

WPS被指套娃式收费!我快用不起免费的中国互联网了……

接触互联网二十余年,小柴发现,中国互联网与国外互联网有一个很大的区别。 即国外的互联网一般都是收费的,比如杀毒软件、办公软件,以及下载各种APP、游戏,看个视频,基本上都是要单独付费购买的&#xff0c…

2024华为数通HCIP-datacom最新题库(变题版)

请注意,华为HCIP-Datacom考试831已变题 请注意,华为HCIP-Datacom考试831已变题 请注意,华为HCIP-Datacom考试831已变题 近期打算考HCIP的朋友注意了,如果你准备去考试,还是用的之前的题库,切记暂缓。 H1…

Linux(CentOS7)离线使用安装盘部署Telnet

[在线工具网 - 各类免费AI工具合集,免费pdf转word等](https://www.orcc.online) https://orcc.online 挂载镜像CentOS-7-x86_64-DVD-1810.iso到/mnt下(其他位置也行),命令如下: mount /dev/sr0 /mnt 安装包默认在Pa…

RabbitMQ是怎么做消息分发的?——Java全栈知识(14)

RabbitMQ是怎么做消息分发的? RabbitMQ 的消息分发分为五种模式:分别是简单模式、工作队列模式、发布订阅模式、路由模式、主题模式。 1、简单模式 publisher 直接发送消息到队列消费者监听并处理队列中的消息 简单模式是最基本的工作模式,…

ubuntu中的docker记录(5)——如何使用阿里云的镜像加速配置docker镜像加速器

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、镜像加速器介绍1. 什么是docker镜像加速器?2. 为什么要配置镜像加速器? 二、配置镜像加速器1. 注册阿里云账号2. 注册镜像容器服务3…

Go-Zero自定义goctl实战:定制化模板,加速你的微服务开发效率(四)

前言 上一篇文章带你实现了Go-Zero和goctl:解锁微服务开发的神器,快速上手指南,本文将继续深入探讨Go-Zero的强大之处,并介绍如何使用goctl工具实现模板定制化,并根据实际项目业务需求进行模板定制化实现。 通过本文…

CSP-j 计算机硬件

计算机系统 计算机系统由计算机硬件和软件两部分组成。硬件包括中央处理器、存储器和外部设备等;软件是计算机的运行程序和相应的文档。计算机系统具有接收和存储信息、按程序快速计算和判断并输出处理结果等功能。 主要技术指标 字长:字长是指CPU能够同…

浅谈冯诺依曼体系与Linux操作系统

目录 前言 1.1冯诺依曼体系下的存储器 二、操作系统 1.关于操作系统 2.关于管理方式 总结 前言 不知道你是否有着这样的疑问: 什么是内存?什么是磁盘?他们有什么区别?可不可以相互替代? 操作系统是如何对数据进行管…

聚类分析 | 基于GA遗传算法优化kmeans聚类(Matlab)

聚类分析 | 基于GA遗传算法优化kmeans聚类(Matlab) 目录 聚类分析 | 基于GA遗传算法优化kmeans聚类(Matlab)效果一览基本介绍程序设计参考资料 效果一览 基本介绍 GA-kmeans聚类算法,通过GA遗传算法优化kmeans聚类&…

vue2实现右键菜单功能——vue-diy-rightmenu——基础积累

五一之前遇到一个需求,就是关于要实现自定义右键菜单的功能,普通的右键展示的菜单有【返回/前进/重新加载/另存为】等,希望实现的效果就是右键出现自定义的菜单,比如【编辑/删除/新增】等。 遇到这种的需求,可以直接去…

C#进阶-OleDb操作Excel和数据库

在C#编程中,使用OleDb可以方便地实现对Excel文件和数据库的操作。本文探讨了在C#中使用OleDb技术操作Excel和数据库的策略。文章详述了OleDb的定义、配置环境的步骤,并通过实际代码示例演示了如何高效读写Excel文件和交互数据库。文中还评估了OleDb技术的…

【C++初阶】第十站:vector 中通用函数的模拟实现

目录 vector中的三个重要迭代器 默认成员函数 构造函数(无参构造) 构造函数(函数模板) 构造函数(带有默认参数) size_t int 拷贝构造函数 赋值重载 析构函数 迭代器相关函数 begin和end 容量和大小相关函数 size capacity resize 修改容器内容相关函数 reser…

Django项目之电商购物商城 -- 创建收货地址

Django项目之电商购物商城 – 创建收货地址 一. 在users中创建新的视图与路由用于创建收货地址 # 设置收货地址 class AddressView(View):def get(self , request):return render(request , "user_center_site.html")# 设置收货地址path(user_center_site/, views.…
最新文章