STM32--ADC模数转换

文章目录

  • ADC简介
  • 逐次逼近型ADC
  • ADC框图
  • 转换模式
  • 数据对齐
  • 转换时间
  • 校准
  • ADC基本结构
  • ADC单通道工程
    • 代码:

ADC简介

STM32的ADC(Analog-Digital Converter)模拟-数字转换器是一种逐次逼近型模拟数字转换器,可以将引脚上连续变化的模拟电压转换为内存中存储的数字变量,建立模拟电路到数字电路的桥梁。拥有18个输入通道,可测量16个外部通道和2个内部信号源。各通道的A/D转换可以单次、连续、扫描或间断模式执行。 ADC的结果可以左对齐或右对齐方式存储在16位数据寄存器中。

模拟看门狗特性允许应用程序检测输入电压是否超出用户定义的高/低阀值。

输入电压范围:0-3.3V,转换结果范围:0~4095

在STM32F103C8T6 ADC资源:ADC1、ADC2,10个外部输入通道
在这里插入图片描述

逐次逼近型ADC

在这里插入图片描述
这个一个经典的逐次逼近型ADC,有8个输入通道,会在通道选择开关进行选择,通过地址锁存和译码进行锁定要输出的信号。利用ADDA,ADDB,ADDC进行锁存,ALE进行译码。

接着到比较器,它将输入信号与DAC(数值模拟转换器)的输出进行比较,在开始转换之前,DAC会输出一个初始值,然后与输入信号进行比较,比较结果会被送到一个控制逻辑电路上,控制逻辑电路根据比较结果调整ADC的输出值,这个过程会重复进行,直到ADC的输出与输入信号精度足够接近。每次调整DAC的输出,都使其更加接近于输入信号的值。当DAC的输出与输入信号的差异在可接受范围内时,转换结束。

逐次逼近型寄存器就是将调整DAC输出的值,通过二分查找的方法,找到接近输入信号的值

最后将最终值放入三态锁存寄存器,就可以进行输出了。

上面的CLOCK是ADC的时钟,通过它可以控制ADC的运行速度和转换精度。由于转换需要一定时间,可通过它控制转换速度。还可以实现与外部时钟同步。

START是运行控制位,EOC是转换结束标志位。

ADC框图

在这里插入图片描述
在这里插入图片描述
我们先从输入口看,大体上与传统的逐次逼近型ADC无差异,这里有16个外部通道和两个内部资源通道。接着会通过数据选择器,可以到注入通道或者规则通道。
在这里插入图片描述

注入通道最多可以有4个输入通道涌入,而规则通道可以有16个输入通道涌入
这里的模拟数字转换器原理就是逐次逼近型ADC的原理。

对于规则通道寄存器,只能存储一个结果,所以如果有多个通道进行转换的话,那么先存储的结果会被后来的结果覆盖过去,这有可能造成结果丢失;这里的DMA请求就会解决这种后果,通过对寄存器地址的移动,让数据存储在不同的地址,这样就不会数据丢失,具体下一章讲解。
那注入通道就是一次可以存储4个结果,注入通道还有一些具体的内容,这里不展开叙述。
ADCCLK就是时钟,可控制采样时间和转换时间;

最后汇集到地址数据总线上,进行输出。

左下角是触发转换的部分,对应逐次逼近型的START信号;对于STM32,有两种触发方式,一种是软件触发,通过在程序中进行编写代码,进行启动;另一种是硬件触发,就是图中的触发源;有定时器各个通道和定时器主模式的输出,还有外部中断引脚触发转换。
在这里插入图片描述

模拟看门狗会根据比较的结果,在一定范围内进行判断,一旦超出所在范围,那么将会产生看门狗事件;

转换结束后,规则通道的信号和注入通道的信号都会产生标志位,标志位可以触发中断使能,使其中断;

转换模式

在ADC中,有两种转换模式,可以搭配扫描模式一同使用;
单次转换模式下, ADC只执行一次转换。连续转换模式中,当前面ADC转换一结束马上就启动另一次转换。扫描模式用来扫描一组模拟通道。

单转换,非扫描模式
在这里插入图片描述
每一次转换都需要进行一次触发,转换结束后会置出一个结束标志位;当进行下一次转换时,又需要进行重新触发和置出结束标志位。

连续转换,非扫描模式
在这里插入图片描述
连续转换,只需要在一开始进行转换触发,那么接下来的每一次转换都不需要进行转换触发;
且转换一次后,会迅速进入下一次转换,每一次EOC会被标志,这里可以理解为转换完成后EOC自动标志了。

单次转换,扫描模式
在这里插入图片描述
扫描模式会对所选通道都进行扫描,由于是单次转换,后来的通道内容会将前面的通道内容进行覆盖,所以如图中所示,到最后只有通道6的内容进行输出;

连续转换,扫描模式
在这里插入图片描述
同样的道理,到最后只有通道6的内容会进行输出;
所以扫描模式都会与DMA进行搭配,让数据不产生丢失的情况

数据对齐

在这里插入图片描述
对于规则通道来说,输出结果只有12位有效,而数据存储器有16位,所以这里就会产生两种方式进行存储;
右对齐:数据高位补0,这是我们常用的方式;
左对齐:数据低位补0,这样操作会使数据扩大16倍;

转换时间

AD转换的步骤:采样,保持,量化,编码

STM32 ADC的总转换时间为:
TCONV = 采样时间 + 12.5个ADC周期

例如:当ADCCLK=14MHz,采样时间为1.5个ADC周期
TCONV = 1.5 + 12.5 = 14个ADC周期 = 1μs

校准

ADC有一个内置自校准模式。校准可大幅减小因内部电容器组的变化而造成的准精度误差。在
校准期间,在每个电容器上都会计算出一个误差修正码(数字值),这个码用于消除在随后的转换
中每个电容器上产生的误差。
建议在每次上电后执行一次校准;
启动校准前, ADC必须处于关电状态超过至少两个ADC时钟周期。

ADC基本结构

在这里插入图片描述
通过输入端口到AD转换器,AD转换器需要触发控制和时钟进行初始化。转换结束后会产生标志位;接着将数据结果储存到AD数据寄存器中。该结构需要开关进行控制启动。

ADC单通道工程

接线方式:
在这里插入图片描述
通过对电位器的旋转,在OLED显示屏上显示数字转换后的结果。

代码:

OLED代码所取处

AD.h

#ifndef __AD_H__
#define __AD_H__

void AD_Init();
uint16_t AD_GetValue();

#endif

AD.c

#include "stm32f10x.h"                  // Device header


void AD_Init()
{
	//开启外设时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_ADC1,ENABLE);
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA,ENABLE);
    //配置ADC时钟
    RCC_ADCCLKConfig(RCC_PCLK2_Div6);  // 72M/6=12MHz
	//引脚初始化
    GPIO_InitTypeDef GPIO_InitStructure;
    GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AIN; //模拟输入
    GPIO_InitStructure.GPIO_Pin=GPIO_Pin_0;
    GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
    GPIO_Init(GPIOA,&GPIO_InitStructure);
    //为所选ADC规则通道配置其序列器对应等级和采样时间
    ADC_RegularChannelConfig(ADC1,ADC_Channel_0,1,ADC_SampleTime_55Cycles5);
    //ADC结构体成员
    ADC_InitTypeDef ADC_InitStructure;
    ADC_InitStructure.ADC_ContinuousConvMode=DISABLE; //指定通道模式为连续转换或者单转换
    ADC_InitStructure.ADC_DataAlign=ADC_DataAlign_Right; //数据对齐方式
    ADC_InitStructure.ADC_ExternalTrigConv=ADC_ExternalTrigConv_None; //启动规则通道模拟电压到数字转换的外部触发器
    ADC_InitStructure.ADC_Mode=ADC_Mode_Independent; //配置ADC为独立模式或者双模式
    ADC_InitStructure.ADC_NbrOfChannel=1;
    ADC_InitStructure.ADC_ScanConvMode=DISABLE; //选择是否为扫描模式
    ADC_Init(ADC1,&ADC_InitStructure);
    //ADC运行控制
    ADC_Cmd(ADC1,ENABLE);
    //重置所选ADC校准寄存器
    ADC_ResetCalibration(ADC1);
    //获取ADC复位状态,复位后为0
    while(ADC_GetResetCalibrationStatus(ADC1));
    //开始校准
    ADC_StartCalibration(ADC1);
    //获取ADC所选标准位状态,校准需要时间,校准好后置0
    while(ADC_GetCalibrationStatus(ADC1));
}

uint16_t AD_GetValue()
{
    //启动ADC软件转换,触发方式
    ADC_SoftwareStartConvCmd(ADC1,ENABLE);
    //检查ADC是否已有标志位,还没有就为SET,有为RESET(EOC)
    while(ADC_GetFlagStatus(ADC1,ADC_FLAG_EOC)==RESET);
    //返回一个转换结果
    return ADC_GetConversionValue(ADC1);
}

main.c

#include "stm32f10x.h"                  // Device header
#include "OLED.h"
#include "AD.h"

float V;
int main()
{
	OLED_Init();
	AD_Init();
    OLED_ShowString(1,1,"Value:");
    //显示电压
    OLED_ShowString(2,1,"Volatge:0.00");
    while(1)
    {
        V=(float)(AD_GetValue()/4095*3.3);
        OLED_ShowNum(1,7,AD_GetValue(),4);
        OLED_ShowNum(2,9,V,1);
        OLED_ShowNum(2,11,(uint16_t)(V*100)%100,2);
    }
}

数字范围:0-4095
电压范围:0-3.3V
对于显示屏上的波动效果,是正常效果。由于转换总时间在1/12*(55.5+12.5)=5.6微妙;
转换速度是非常快的,而我们又在一个循环中不断显示结果,每次输出结果是由逐次逼近型ADC进行比较输出的,所以不可能每次比较值都非常精准,多多少少会有些误差的波动。

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

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

相关文章

C++中机器人应用程序的行为树(ROS2)

马库斯布赫霍尔茨 一、说明 以下文章为您提供了对机器人应用程序或框架中经常使用的行为树的一般直觉:ROS,Moveit和NAV2。了解行为 Tress (BT) 框架的原理为您提供了在游戏领域应用知识的绝佳机会。BT可以与Unity或Unreal集成。 由…

操作符详解(1)

1. 操作符分类: 算术操作符 移位操作符 位操作符 赋值操作符 单目操作符 关系操作符 逻辑操作符 条件操作符 逗号表达式 下标引用、函数调用和结构成员 2. 算术操作符 - * / % 1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。 2. 对…

springboot 项目日志配置文件详解

spring boot 项目指定 日志配置文件 在Spring Boot项目中,可以通过在application.properties或application.yml文件中指定日志配置文件来配置日志。 1. 使用application.properties文件: 在application.properties中,您可以使用以下属性来…

元核云私募双录助力私募基金业务高效合规

近年来,私募基金监管政策不断收紧,今年7月发布的《私募投资基金监督管理条例》更是把私募投资基金业务活动纳入法治化、规范化轨道进行监管。 作为保障私募基金业务透明合规的重要手段,“双录”一直是私募流程中非常重要的一环,多…

三、SQL注入之报错注入

文章目录 1、 xpath语法(1)extractvalue(2)updatexml 2、concatrand()group by()导致主键重复 报错注入就是利用了数据库的某些机制,人为地制造错误条件,使得查询结果能够出现在错误信息中。这里主要介绍报…

动漫3D虚拟人物制作为企业数字化转型提供强大动力

一个 3D 虚拟数字人角色的制作流程,可以分为概念设定-3D 建模-贴图-蒙皮-动画-引擎测试六个步骤,涉及到的岗位有原画师、模型师、动画师等。角色概念设定、贴图绘制一般是由视觉设计师来完成;而建模、装配(骨骼绑定)、渲染动画是由三维设计师来制作完成。…

⛳ TCP 协议面试题

目录 ⛳ TCP 协议面试题🐾 一、为什么关闭连接的需要四次挥⼿,⽽建⽴连接却只要三次握⼿呢?🏭 二、为什么连接建⽴的时候是三次握⼿,可以改成两次握⼿吗?👣 三、为什么主动断开⽅在TIME-WAIT状态…

wustojc3001求三角形面积

#include <stdio.h> #include <math.h> int main() {float a,b,c,d;double s;scanf("%f%f%f",&a,&b,&c);if(ab>c&&ac>b&&cb>a){d(abc)/2;ssqrt(d*(d-a)*(d-b)*(d-c));//数学公式printf("%.2f",s);}retur…

(成功踩坑)electron-builder打包过程中报错

目录 注意&#xff1a;文中的解决方法2&#xff0c;一定全部看完&#xff0c;再进行操作&#xff0c;有坑 背景 报错1&#xff1a; 报错2&#xff1a; 1.原因&#xff1a;网络连接失败 2.解决方法1&#xff1a; 3.解决方法2&#xff1a; 3.1查看缺少什么资源文件 3.2去淘…

软件开发bug问题跟踪与管理

一、Redmine 项目管理和缺陷跟踪工具 官网&#xff1a;https://www.redmine.org/ Redmine 是一个开源的、基于 Web 的项目管理和缺陷跟踪工具。它用日历和甘特图辅助项目及进度可视化显示&#xff0c;同时它又支持多项目管理。Redmine 是一个自由开源软件解决方案&#xff0c;…

如何将图片应用于所有的PPT页面?

问题&#xff1a;如何快速将图片应用到所有PPT页面&#xff1f; 解答&#xff1a;有两种方法可以解决这个问题。第一种用母板。第二种用PPT背景功能。 解决有时候汇报的时候&#xff0c;ppt中背景图片修改不了以及不知道如何查找&#xff0c;今天按照逆向过程进行操作 方法1…

详解C#-static void Main(string[] args)

目录 简介: 举例: 输出结果:​编辑 总结&#xff1a; 简介: 在C#中static void Main(string[] args)这个句话有什么作用&#xff0c;分别代表什么意思&#xff01;&#xff01; 这句话是入口函数的声明&#xff0c;指定了C#程序的入口点&#xff0c;并定义了一个名为”Mai…

Go语言GIN框架安装与入门

Go语言GIN框架安装与入门 文章目录 Go语言GIN框架安装与入门1. 创建配置环境2. 配置环境3. 下载最新版本Gin4. 编写第一个接口5. 静态页面和资源文件加载6. 各种传参方式6.1 URL传参6.2 路由形式传参6.3 前端给后端传递JSON格式6.4 表单形式传参 7. 路由和路由组8. 项目代码mai…

wustojc3006水果店收款

#include <stdio.h> int main() {double a,b,c,d,sum;scanf("%lf%lf%lf%lf",&a,&b,&c,&d);suma*2.5b*1.7c*2.0d*1.2;printf("%.2lf",sum);//注意保留几位小数return 0;}

图数据库_Neo4j学习cypher语言_常用函数_关系函数_字符串函数_聚合函数_数据库备份_数据库恢复---Neo4j图数据库工作笔记0008

然后再来看一些常用函数,和字符串函数,这里举个例子,然后其他的 类似 可以看到substring字符串截取函数 可以看到截取成功 聚合函数 这里用了一个count(n) 统计函数,可以看到效果 关系函数,我们用过就是id(r) 可以取出对应的r的id来这样..

Scratch 游戏 之 随机大地图生成教程

在很多生存 / 沙盒类游戏中&#xff0c;地图往往是随机生成的&#xff0c;例如&#xff1a;饥荒、我的世界等。那我们该如何在scratch中实现这一点呢&#xff1f; 在scratch中有两种办法可以实现——画笔和克隆体。我们这次先聊克隆体。 我们可以先将克隆体设置为方形的&#x…

python AI绘图教程

前提 1.安装python 2.安装git 步骤 下载stable-diffusion-webui项目&#xff08;链接&#xff1a;GitHub - AUTOMATIC1111/stable-diffusion-webui: Stable Diffusion web UI&#xff09; git clone https://github.com/AUTOMATIC1111/stable-diffusion-webui.git 安装st…

.netcore grpc客户端工厂及依赖注入使用

一、客户端工厂概述 gRPC 与 HttpClientFactory 的集成提供了一种创建 gRPC 客户端的集中方式。可以通过依赖包Grpc.Net.ClientFactory中的AddGrpcClient进行gRPC客户端依赖注入AddGrpcClient函数提供了许多配置项用于处理一些其他事项&#xff1b;例如AOP、重试策略等 二、案…

azure VM完全复制

创建虚拟机&#xff0c;并创建linux服务&#xff0c;可以参考 https://blog.csdn.net/m0_48468018/article/details/132267096 &#xff0c; https://blog.csdn.net/m0_48468018/article/details/132267315在虚拟机中点击磁盘快照&#xff0c;创建磁盘快照 通过磁盘快照创建磁盘…

我的编程语言学习笔记

前言 作为一名编程初学者&#xff0c;我深知学习编程需要不断积累和记录。在这篇博客文章中&#xff0c;我将分享一些我在学习C/C编程语言过程中记录的常用代码、特定函数、复杂概念以及特定功能。希望能与大家一起切磋进步&#xff01; 常用代码&#xff1a; 1. 输入输出操作…