当前位置: 首页 > news >正文

【单片机】15-AD和DA转换

1.AD转换及其相关背景知识

1.基本概念

1.什么是AD转换?

A(A,analog,模拟的,D,digital,数字的)

现实世界是模拟的,连续分布的,无法被分成有限份;

计算机世界是数字的,离散分布的,可以被分成有限份的

AD转换就是把一个物理量从模拟的转换成数字的。

2.AD转换的意义

想要计算机来实现现实世界

3.什么情况下需要AD转换

CPU是数字的【要准确的0V或者5V】

2.AD转换的原理

1.比较器

将差一点的电压转换为准确的二进制

所有的AD转换芯片内部都是用比较器来实现的。

2.和十进制转二进制有点像

使用除法

3.AD转换中的主要概念

1.位数

AD转换后转出来的二进制数由几位二进制来表示。【实际结果是一样大】

位数越多,越细腻。【精度越高】

2.量程

AD转换器可以接受的模拟量的范围

3.精度

精度==准确度

简单理解就是转出来有多准

【精度越小可靠率越高】

4.分辨率

AD转换器转出来的二进制数,每一格表示多少

5.转换速率(转换时间)

时间越短,速率越大

6.例子

输入电压范围:0-5V,AD转换输出位数是10,精度是0.01V

量程:0-5V

分辨率:(5-0)/2exp(10)=0.00488V

比如一次AD转换后得到数据为:【1010101010】,对应电压值:1010101010-->十进制:682,电压=682*0.00488=3.328V,考虑精度后为=3.33V

4.AD转换在系统中存在的方式

1.CPU外部扩展专用AD芯片

2.CPU内部集成AD模块(内部外设)

2.原理图和数据手册

https://www.semiee.com/file/ETEK/ETEK-ET2046.pdf

1.原理图

2.数据手册

 AIN0-AIN3:不能同时采集,同一时间只能采集一路

3.SPI接线

CLK接P1.0

CS接P1.1

DI接P1.2

DO接P1.3

4.3种模拟电压变化原理

AIN0靠滑动变阻器控制电压变化

AIN1靠热敏电阻NTC

AIN2靠光敏电阻

5.ET2046控制字

bit7:起始位【高表示开始传输】:1

bit6-bit4:决定采样哪一路(AIN1,AIN0,AINT2,AINT3):

AIN0:001/011         X+

AIN1:101                Y+

AIN2:010                VBAT

AIN3:110                VBAT

bit3:设置ADC精度:【1:使用bit8位】【0:使用bit12位--一般使用这个】:0

bit2:【1:表示用单端模式】【0:表示差分模式(触摸屏)】:1

bit1:power down模式使能,00表示使能

 读AIN0:0b 1001 0100=0x94

读AIN1:0b 1101 0100=0xd4

读AIN2;0b 1010 0100=0xa4
读AIN3:0b 1110 0100=0xe4

AIN0:001/011         X+

AIN1:101                Y+

AIN2:010                VBAT

AIN3:110                VBAT

3.分析时序

1.时序图

1.SPI变种

回顾SPI知识点:【单片机】13-实时时钟DS1302-CSDN博客

有CS,DCLK,I/O

2.上升沿写入下降沿读出

之前DS1302(SPI)的时候也是这样

上升沿写入:当CLK为上升沿的时候,数据通过DI从SPI主设备写入到SPI从设备

下降沿读出:当CLK为下降沿的时候,数据通过DO从SPI从设备读入到SPI主设备

3.读写都是高位在前

之前DS1302(SPI)的时候是低位在前

4.注意写和读的交界点

2.官方例程分析

1.ET2046写数据

/*******************************************************************************
* 函 数 名       : xpt2046_wirte_data
* 函数功能		 : XPT2046写数据
* 输    入       : dat:写入的数据
* 输    出    	 : 无
*******************************************************************************/
void xpt2046_wirte_data(u8 dat)
{u8 i;CLK = 0;//可以忽略的_nop_();for(i=0;i<8;i++)//循环8次,每次传输一位,共一个字节{//先准备好数据,在置CLK=0DIN = dat >> 7;//先传高位再传低位dat <<= 1;//将低位移到高位CLK = 0;//CLK由低到高产生一个上升沿,从而写入数据_nop_();	CLK = 1;_nop_();}
}

2.ET2046读数据

/*******************************************************************************
* 函 数 名       : xpt2046_read_data
* 函数功能		 : XPT2046读数据
* 输    入       : 无
* 输    出    	 : XPT2046返回12位数据
*******************************************************************************/
u16	xpt2046_read_data(void)
{u8 i;u16 dat=0;CLK = 0;_nop_();for(i=0;i<12;i++)//循环12次,每次读取一位,大于一个字节数,所以返回值类型是u16{dat <<= 1;CLK = 1;_nop_();CLK = 0; //CLK由高到低产生一个下降沿,从而读取数据_nop_();dat |= DOUT;//先读取高位,再读取低位。	}return dat;	
}

3.ET2046返回AD值

/*******************************************************************************
* 函 数 名       : xpt2046_read_adc_value
* 函数功能		 : XPT2046读AD数据
* 输    入       : cmd:指令
* 输    出    	 : XPT2046返回AD值
*******************************************************************************/
u16 xpt2046_read_adc_value(u8 cmd)
{u8 i;u16 adc_value=0;CLK = 0;//先拉低时钟CS  = 0;//使能XPT2046xpt2046_wirte_data(cmd);//发送命令字for(i=6; i>0; i--);//延时等待转换结果,这个时候进行AD转换CLK = 1;//发送应该_nop_();CLK = 0;//发送一个时钟,清除BUSY_nop_();adc_value=xpt2046_read_data();CS = 1;//关闭XPT2046return adc_value;
}

4.main函数

/*******************************************************************************
* 函 数 名       : main
* 函数功能		 : 主函数
* 输    入       : 无
* 输    出    	 : 无
*******************************************************************************/
void main()
{	u16 adc_value=0;float adc_vol;//ADC电压值u8 adc_buf[3];while(1){	//0x94:对应AINT0--0b 1001 1100			adc_value=xpt2046_read_adc_value(0x94);//测量电位器adc_vol=5.0*adc_value/4096;//将读取的AD值转换为电压adc_value=adc_vol*10;//放大10倍,即保留小数点后一位adc_buf[0]=gsmg_code[adc_value/10]|0x80;adc_buf[1]=gsmg_code[adc_value%10];adc_buf[2]=0x3e;//显示单位Vsmg_display(adc_buf,6);		}		
}

4.代码实践【AD转换】

1.将12bit位的数值分2次输出

//AD value是12bit的,分2波出去【因为一次只能输出8位】
void uart_send_advalue(u16 val){uart_send_byte((val>>8)&0xff);	//高8位uart_send_byte(val&0xff);	//低8位uart_send_byte(0);//分割符
}

2. 计算电压值

3.读取AD数值:

ET2046.c

#include"ET2046.h"/*******************************************************************************
* 函 数 名       : xpt2046_read_adc_value
* 函数功能		 : XPT2046读AD数据
* 输    入       : cmd:指令
* 输    出    	 : XPT2046返回AD值
*******************************************************************************/
u16 xpt2046_read_adc_value(u8 cmd)
{u8 i;u16 adc_value=0; //局部变量的初始化非常重要CLK = 0;//先拉低时钟CS  = 0;//使能XPT2046//写入数据for(i=0;i<8;i++)//循环8次,每次传输一位,共一个字节{//先准备好数据,在置CLK=0DIN = cmd >> 7;//先传高位再传低位cmd <<= 1;//将低位移到高位CLK = 0;//CLK由低到高产生一个上升沿,从而写入数据_nop_();	CLK = 1;_nop_();}for(i=6; i>0; i--);//延时等待转换结果,这个时候进行AD转换CLK = 1;//发送应该_nop_();CLK = 0;//发送一个时钟,清除BUSY_nop_();for(i=0;i<12;i++)//循环12次,每次读取一位,大于一个字节数,所以返回值类型是u16{adc_value <<= 1;CLK = 1;_nop_();CLK = 0; //CLK由高到低产生一个下降沿,从而读取数据_nop_();adc_value |= DOUT;//先读取高位,再读取低位。	}CS = 1;//关闭ET2046return adc_value;
}

ET2046.h

#ifndef _xpt2046_H
#define _xpt2046_H#include "reg51.h"
#include  "intrins.h" typedef unsigned int u16;	//对系统默认数据类型进行重定义
typedef unsigned char u8;
typedef unsigned long u32;//管脚定义
sbit DOUT = P1^3;	  //输出
sbit CLK  = P1^0;	  //时钟
sbit DIN  = P1^2;	  //输入
sbit CS   = P1^1;	  //片选//函数声明
u16 xpt2046_read_adc_value(u8 cmd);#endif

main.c

#include"ET2046.h"
#include"uart.h"#define CMD_READ_AIN0 0x94	//滑动变阻器
#define CMD_READ_AIN1 0xD4	//NTC--热敏电阻
#define CMD_READ_AIN2 0xA4	//GR1--光敏电阻
#define CMD_READ_AIN3 0xE4	//外部输入的电压值void Delay400000us()		//@11.0592MHz
{unsigned char i, j, k;_nop_();_nop_();i = 17;j = 208;k = 27;do{do{while (--k);} while (--j);} while (--i);
}//AD value是12bit的,分2波出去【因为一次只能输出8位】
void uart_send_advalue(u16 val){uart_send_byte((val>>8)&0xff);	//高8位uart_send_byte(val&0xff);	//低8位uart_send_byte(0);//分割符
}void main(){//注意:定义一个变量要记得初始化,要不然后面可能出现问题u16 val=0;//12bit数值uart_init();while(1){val=xpt2046_read_adc_value(CMD_READ_AIN0);uart_send_advalue(val);Delay400000us();}
}

4.串口直接显示电压值

1.关键点

(1)直接显示电压值,而不是采样AD值

(2)以文本方式显示,而不是十六进制方式

2.将数值转换为十进制

//以文本方式发送c过去,意思就是要串口助手用文本方式来查看,看到的是
//这个数字本身
void uart_send_text(unsigned char c){//思路就是把c以十进制方式显示的几个数字,挨个变成文本发出去unsigned char i;//因为c是unsigned char 范围是0-255//先计算得出c的最高位,然后发出去i=c/100;uart_send_byte(i+48);//+48是对应ASCII//计算次高位c=c%100;i=c/10;uart_send_byte(i+48);//计算个位c=c%10;i=c;uart_send_byte(i+48);//发送一个换行uart_send_byte('\r');uart_send_byte('\n');
}

因为我们这里的电压是5V,对应5000mV,明显上面的0-255不在范围内,所以我们要求传入的是unsigned int c,【0-2的16次方】才足够

//因为这个函数的范围是unsigned char---->是2的8次方
//但是我们最大电压值为:5V----5000mV,所以我们这里要使用unsigned int
//以文本方式发送c过去,意思就是要串口助手用文本方式来查看,看到的是
//这个数字本身
void uart_send_text2(unsigned int c){//思路就是把c以十进制方式显示的几个数字,挨个变成文本发出去unsigned char i;//因为c是unsigned char 范围是0-255//因为我们知道电压值不会超过5000mV,所以只考虑显示1万以内的数据//先计算得出c的最高位,然后发出去i=c/1000;uart_send_byte(i+48);//+48是对应ASCIIc=c%1000;i=c/100;uart_send_byte(i+48);//+48是对应ASCII//计算次高位c=c%100;i=c/10;uart_send_byte(i+48);//计算个位c=c%10;i=c;uart_send_byte(i+48);//发送一个换行uart_send_byte('\r');uart_send_byte('\n');
}

5.DA转换

将数字转换为模拟的

1.DA转换的原理

为了让数字量转换成模拟量,必须将每一位代码按其权重的大小转换为相应的模拟量,然后再把这些模拟量相加。

2.原理图和案例分析

1.运算放大器(LM358)

放大作用:将数字信号-----》模拟信号

隔离作用:防止输出信号影响输入信号

2.PWM数字信号

当输入的PWM数字信号一直为1,则输出的模拟信号一直为高电压

如果输入的PWM数字信号一直为0,则输出的模拟信号一直为低电压

关键点:取决于输入的PWM信号的高低电平所占的时间。【连续变化的模拟量】

3.LM358

其实不接LM358,直接用IO口连接LED实现现象也一样。(说明灯的亮度只与PWM输入的电压值的大小有关)

4.注意点

真正的DA一般是专用芯片或者CPU内置模块,给数字值输出平滑模拟量

相关文章:

【单片机】15-AD和DA转换

1.AD转换及其相关背景知识 1.基本概念 1.什么是AD转换&#xff1f; A&#xff08;A&#xff0c;analog&#xff0c;模拟的&#xff0c;D&#xff0c;digital&#xff0c;数字的&#xff09; 现实世界是模拟的&#xff0c;连续分布的&#xff0c;无法被分成有限份&#xff1b;…...

基于FPGA的I2C读写EEPROM

文章目录 前言一、I2C协议1.1 I2C协议简介1.2 物理层1.3 协议层 二、EEPROM2.1 型号及硬件规格2.2 各种读写时序 三、状态机设计四、项目源码&#xff1a;五、实现效果参考资料 前言 本次项目所用开发板FPGA芯片型号为&#xff1a;EP4CE6F17C8 EEPROM芯片型号为&#xff1a;24L…...

Viva Employee Communications Communities部署方案

目录 Viva Employee Communications & Communities产品介绍 1. 沟通中心(Communications Center) 2. 新闻和公告(News and Announcements)...

WPF向Avalonia迁移(三、项目结构)

前提&#xff1a; Avalonia版本11.0.0 1.配置文件 1.1 添加配置文件 1.2 读取配置文件 添加System.Configuration.ConfigurationManager using Avalonia.Controls; using System.Configuration;namespace AvaloniaApplication7.Views {public partial class MainWindow : W…...

cvpr24写作模板pdfLaTex编译器注意点小结

文章目录 1 更改作者显示 Anonymous CVPR submission2 \label标签3 换行符// 与换列符&4 \medskip5 首行缩进6 插入图片6.1 单幅图片6.2 并排显示\hfill Reference https://cvpr.thecvf.com/Conferences/2024 1 更改作者显示 Anonymous CVPR submission 这一行开头加上% …...

windows版php扩展包下载

php8有些扩展需自己下载&#xff0c;像redis 看下phpinfo中的PHP Extension Build&#xff0c;确定自己的php版本 windows.php.net - /downloads/pecl/releases/...

计算机竞赛 题目:基于深度学习的中文汉字识别 - 深度学习 卷积神经网络 机器视觉 OCR

文章目录 0 简介1 数据集合2 网络构建3 模型训练4 模型性能评估5 文字预测6 最后 0 简介 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 基于深度学习的中文汉字识别 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff01; &a…...

Django跨域访问 nginx转发 开源浏览器

Django跨域访问 https://blog.csdn.net/lonelysnowman/article/details/128086205 nginx转发 https://blog.csdn.net/faye0412/article/details/75200607/ 开源浏览器 https://www.oschina.net/p/chromiumengine 浏览器油猴开发 https://blog.csdn.net/mukes/article/detail…...

Docker Alist 在线网盘部署

文章目录 拉取镜像创建并运行查看容器自动生成的密码在浏览器中进行访问 挂载本地磁盘 拉取镜像 docker pull xhofe/alist-aria2创建并运行 # -v /data/alist:/opt/alist/data 挂载本地目录 docker run -d --restartalways -v /data/alist:/opt/alist/data -p 5244:5244 -e P…...

Jmeter吞吐量控制器使用小结

吞吐量控制器(Throughput Controller)场景: 在同一个线程组里, 有10个并发, 7个做A业务, 3个做B业务,要模拟这种场景,可以通过吞吐量模拟器来实现.。 添加吞吐量控制器 用法1: Percent Executions 在一个线程组内分别建立两个吞吐量控制器, 分别放业务A和业务B 吞吐量控制器采…...

3分钟轻松实现网关网口连接罗克韦尔AB CompactLogix系列PLC

目录 EG网关网口连接罗克韦尔AB CompactLogix系列PLC 一. 准备工作 1.1 在对接前我们需准备如下物品 1.2 EG20网关准备工作 1.3 PLC准备工作 二. EMCP平台设置 2.1 新增EG设备 2.2 远程配置网关 2.3 网关绑定 2.4 通讯参数设置 2.5 创建设备驱动 2.5.1 添加变量 2.…...

vscode刷leetcode使用Cookie登录

1、打开vscode&#xff0c;选择扩展&#xff0c;搜索leetcode&#xff0c;选择第一个&#xff0c;带有中文力扣字样&#xff0c;安装后重启 2、选择这个小球&#xff0c;切换中文版本&#xff0c;切换后&#xff0c;会显示一个打勾 3、选择小球旁边的有箭头的小门&#xff0…...

每次启动Docker容器指定IP、hosts和端口

每次启动Docker容器指定IP、hosts和端口 1问题描述1解决办法1.1启动容器指定好IP、hostname、端口等信息1.2通过docker-compose启动容器&#xff0c;可以配置extra_hosts属性1.3通过k8s来管理容器&#xff0c;则在可以在创建pod的yaml文件通过hostAliases添加域名IP映射 2问题描…...

PL/SQL增量同步

PL/SQL全量同步_枯河垂钓的博客-CSDN博客 目录 增量同步 增量同步存储过程 ORACEL 独有的 增量更新 merge into 增量同步 逻辑: 用源表的数据更新目标表,数据存在则更新,数据不存在,则插入 实现的逻辑: 1. 首先判断目标表是否有源表的数据 2. 如果有,则用源表的数据更新…...

C++——多态底层原理

虚函数表 先来看这个问题&#xff1a; class Base { public: virtual void Func1() { cout << "Func1()" << endl; } private: int _b 1; }; sizeof(Base)是多少&#xff1f; 答案是&#xff1a;8 因为Base中除了成员变量_b,还有一个虚函数表_vfp…...

asdTools-ReID热力图可视化

文章首发见博客&#xff1a;https://mwhls.top/4869.html。 无图/格式错误/后续更新请见首发页。 更多更新请到mwhls.top查看 欢迎留言提问或批评建议&#xff0c;私信不回。 Github - 开源代码及Readme Blog - 工具介绍 摘要&#xff1a;基于TorchCam实现ReID的热力图可视化的…...

CSS学习笔记

目录 1.CSS简介1.什么是CSS2.为什么使用CSS3.CSS作用 2.基本用法1.CSS语法2.CSS应用方式1. 内部样式2.行内样式3.外部样式1.使用 link标签 链接外部样式文件2.import 指令 导入外部样式文件3.使用举例 3.选择器1.基础选择器1.标签选择器2.类选择器3.ID选择器4.使用举例 2.复杂选…...

linux操作命令

VMware版本&#xff1a; 17.0 ubantu版本&#xff1a;22.04.3 命令&#xff1a; # 查看当前目录文件 ls# 切换路径 []内是路径 cd [snap/] cd ../ #返回上一层# 创建文件 []内是文件名 touch [test.txt]# 创建文件夹 []内是文件夹名 mkdir [myself]# 测试一下网络 ping www.b…...

猜数字游戏(Python)

一、猜数字游戏是一个古老的密码破译类、益智类小游戏&#xff0c;通常由两个人参与&#xff0c;一个人设置一个数字&#xff0c;一个人猜数字&#xff0c;当猜数字的人说出一个数字&#xff0c;由出数字的人告知是否猜中&#xff1a;若猜测的数字大于设置的数字&#xff0c;出…...

可视化模块

目录 可视化送入网络的图片可视化网络层的热力图 可视化送入网络的图片 送入的数据为imgs&#xff0c;其大小为(8,3,256,256)&#xff0c;并以2行8列进行展示 import matplotlib.pyplot as plt import numpy as np# 假设你的张量名为 tensor&#xff0c;形状为 (8, 3, 256, 2…...

MyBatis insert标签

<insert id"addWebsite" parameterType"string">insert into website(name)values(#{name}) </insert> 在 WebsiteMapper 接口中定义一个 add() 方法 public int addWebsite(String name); 参数为 Sting 类型的字符串&#xff1b;返回值为 …...

扬尘监测:智能化解决方案让生活更美好

随着工业化和城市化的快速发展&#xff0c;扬尘污染问题越来越受到人们的关注。扬尘不仅影响城市环境&#xff0c;还会对人们的健康造成威胁。为了解决这一问题&#xff0c;扬尘监测成为了一个重要的手段。本文将介绍扬尘监测的现状、重要性以及智能化解决方案&#xff0c;帮助…...

【AI视野·今日NLP 自然语言处理论文速览 第四十五期】Mon, 2 Oct 2023

AI视野今日CS.NLP 自然语言处理论文速览 Mon, 2 Oct 2023 Totally 44 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Computation and Language Papers Efficient Streaming Language Models with Attention Sinks Authors Guangxuan Xiao, Yuandong Tian, Beidi C…...

The little schemer 学习

参考文章&#xff1a; The Little Schemer 阅读笔记-CSDN博客 前言 原子是Scheme的基本元素之一。首先定义了过程atom?&#xff0c;用来判断一个S-表达式是不是原子&#xff1a; (define atom?(lambda (x)(and (not (pair? x)) (not (null? x))))) 这个“pair”实际上…...

yolov5+bytetrack算法在华为NPU上进行端到端开发

自从毕业后开始进入了华为曻腾生态圈&#xff0c;现在越来越多的公司开始走国产化路线了&#xff0c;现在国内做AI芯片的厂商比如&#xff1a;寒武纪、地平线等&#xff0c;虽然我了解的不多&#xff0c;但是相对于瑞芯微这样的AI开发板来说&#xff0c;华为曻腾的生态比瑞芯微…...

【Java-LangChain:使用 ChatGPT API 搭建系统-1】简介

简介 欢迎来到课程《使用 ChatGPT API 搭建系统》 , 旨在指导开发者如何基于 ChatGPT 搭建完整的智能问答系统。 使用 ChatGPT 不仅仅是一个单一的 Prompt 或单一的模型调用&#xff0c;本课程将分享使用 LLM 构建复杂应用的最佳实践。 本课程以构建客服助手为例&#xff0c…...

BJT晶体管

BJT晶体管也叫双极结型三极管&#xff0c;主要有PNP、NPN型两种&#xff0c;符号如下&#xff1a; 中间的是基极&#xff08;最薄&#xff0c;用于控制&#xff09;&#xff0c;带箭头的是发射极&#xff08;自由电子浓度高&#xff09;&#xff0c;剩下的就是集电极&#xff0…...

ORACLE中SQL运算符的优先级

SQL运算符优先级: 注&#xff1a; 1、可以使用括号改变优先级顺序 2、可以看出OR的优先级最低&#xff0c;算术运算符的优先级最高 另&#xff1a;操作符优先级 * / - 1、乘除的优先级高于加减&#xff1b; 2、同一优先级运算符从左向右执行&#xff1b; 3、括号内的…...

springboot和vue:十一、Axios网络请求的安装引入与使用、跨域问题解决(CORS)

Axios简介与安装 Axios是一个基于promise的网络请求库&#xff0c;作用于node.js和浏览器中Axios在浏览器端使用XMLHttpRequests发送网络请求&#xff0c;并自动完成json数据的转换安装&#xff1a;npm install axios官方文档&#xff1a;https://www.axios-http.cn/ Axios基…...

外汇天眼:真实记录,投资者在盗版MT4平台SCE Group上做交易的经历!

外汇市场是全球最大的金融市场&#xff0c;比起其他市场有着更多天然的优势&#xff0c;但也因为资讯的不对等&#xff0c;导致很多人上当受骗。而在外汇市场上最常见的骗局之一&#xff0c;就是黑平台使用盗版MT4/5交易软件&#xff0c;因为截至目前MT4/5仍是外汇市场交易使用…...