单片机第一季:零基础13——AD和DA转换

1,AD转换基本概念

51 单片机系统内部运算时用的全部是数字量,即0 和1,因此对单片机系统而言,无法直接操作模拟量,必须将模拟量转换成数字量。所谓数字量,就是用一系列0 和1 组成的二进制代码表示某个信号大小的量。用数字量表示同一个模拟量时,数字位数可以多也可以少,位数越多则表示的精度越高,位数越少表示的精度就越低。 

ADC(analog to digital converter)也称为模数转换器,是指一个将模拟信号转变为数字信号。单片机在采集模拟信号时,通常都需要在前端加上A/D 芯片。 

 A(A,analog,模拟的,D,digital,数字的)现实世界是模拟的,连续分布的,无法被分成有限份;计算机世界是数字的,离散分布的,是可以被分成有限份的;AD转换就是把一个物理量从模拟的转换成数字的。

AD转换中的主要概念:
(1)位数,AD转换后转出来的二进制数由几位二进制来表示。位数越多,越细腻;
(2)量程,AD转换器可以接受的模拟量的范围;
(3)精度,简单理解就是转出来到底有多准;
(4)分辨率,AD转换器转出来的二进制数,每一格表示多少;
(5)转换速率(转换时间); 

例:输入电压范围0-5V,AD转换输出位数是10,精度是0.01V,则:量程为0-5V,分辨率为:(5-0)/2exp(10)=0.00488V,譬如一次AD转换后得到的数据是1010101010,则对应的电压值为:3.328V,考虑精度后为3.33V 。

AD转换在系统中存在的方式:
(1)CPU外部扩展专用AD芯片;
(2)CPU内部集成AD模块(内部外设); 

电池单体的电压采集芯片有一种叫AFE的(Anlog Front End),即是一种AD转换模块,采集单体的电压转换为数字量发给MCU。 

2,AD转换原理图和数据手册 

 ET2046 AD转换模块通过AIN0/AIN1/AIN2分别连接滑线变阻器、热敏电阻、光敏电阻。与单片机连接的接口为CS(使能接口,低有效)、CLK(时钟信号)、DI(数据输入,从单片机到AD转换模块)、DO(数据输出、从AD转换模块到单片机)。

X+、Y+、VBAT 和AUX 模拟信号经过片内的控制寄存器选择后进入ADC,ADC 可以配置为单端或差分模式。选择VBAT和AUX 时应该配置为单端模式;作为触摸屏应用时,应该配置为差分模式。

单片机在对AD转换模块进行控制时,控制字节由DIN 输入的控制字命令格式如下所示:

Bit7为开始位,为1表示一个新的控制字节到来,为0则忽略PIN引脚上的数据;

A2-A0为通道选择位,表示选择哪个通道的输入电压进行AD转换;

MODE为12/8位转换分辨率选择位,为1选择8位转换分辨率,为0选择12位分辨率;

SER/DFR:单端输入方式/差分输入方式选择,为1是单端输入方式,为0是差分输入方式;

PD1-PD0为低功耗模式选择位,若为11,器件总处于供电状态,若为00,器件在转换之间处于低功耗模式。

单端模式时采集通道的选择如下表所示(通过上述控制字节的A2-A1进行选择): 

选择X+通道、12位分辨率、单端模式、低功耗模式的控制字节命令:0b1001 0100 = 0x94。 

AD转换模块的时序图如下所示: 

从时序图上可见,转换模块进入工作状态时,CS为低,DCLK为低,DIN和DOUT不用关注;首先通过DIN数据线从单片机发送控制字节到AD转换模块,在DCLK的上升沿AD转换模块读入数据(从高到低进行读入),当8位控制字节命令发送完成后,转换模块进入busy状态,即转换模块开始进行AD转换,此时间可从数据手册获取,一般程序中通过延迟一段时间来进行处理;然后单片机在DOUT数据线读取转换模块发出的数据,每个DCLK的下降沿转换模块会将一位数据发送到DOUT数据线上,仍然是从高到低的顺序。

可见AD转换和单片机的通讯方式类似于SPI通讯。 

3,AD转换代码 

AD采样转换代码包括单片机和AD转换模块写入命令和读取数据的底层时序代码,通过串口显示采样数据代码,以及main文件。

ET2046.c底层时序代码: 

#include "ET2046.h"
#include <intrins.h>void delay10us(void)   //误差 0us
{unsigned char a,b;for(b=1;b>0;b--)for(a=2;a>0;a--);
}unsigned int read_AD_value(unsigned char cmd)
{unsigned char i = 0;unsigned int AD_Value = 0;CS = 0;SCLK = 0;for(i = 0;i < 8;i++){DIN = cmd >> 7;cmd <<= 1;   //注意将一个数据移位后再赋给本身的运算符位 <<=SCLK = 1;_nop_();SCLK = 0;_nop_();}delay10us();SCLK = 1;	  			//发送一个时钟周期,清除BUSY_nop_();_nop_();SCLK = 0;_nop_();_nop_();for(i = 0;i<12;i++){AD_Value <<= 1;SCLK = 1;_nop_();SCLK = 0;_nop_();AD_Value |= DOUT;}CS = 1;return AD_Value;}

ET2046.h 


#ifndef __ET2046_H__
#define __ET2046_H__#include <reg51.h>sbit SCLK = P1^0;
sbit CS = P1^1;sbit DIN = P1^2;
sbit DOUT = P1^3;unsigned int read_AD_value(unsigned char cmd);#endif

串口调试代码: 

#include "uart.h"// 串口设置为: 波特率9600、数据位8、停止位1、奇偶校验无
// 使用的晶振是11.0592MHz的,注意12MHz和24MHz的不行
void uart_init(void)
{// 波特率9600SCON = 0x50;   	// 串口工作在模式1(8位串口)、允许接收PCON = 0x00;	// 波特率不加倍// 通信波特率相关的设置TMOD = 0x20;	// 设置T1为模式2TH1 = 253;TL1 = 253;	   	// 8位自动重装,意思就是TH1用完了之后下一个周期TL1会// 自动重装到TH1去TR1 = 1;		// 开启T1让它开始工作
//	ES = 1;
//	EA = 1;
}// 通过串口发送1个字节出去
void uart_send_byte(unsigned char c)
{// 第1步,发送一个字节SBUF = c;// 第2步,先确认串口发送部分没有在忙while (!TI);// 第3步,软件复位TI标志位TI = 0;
}void uart_send_adVal(unsigned int val)
{uart_send_byte(val>>8);   //AD采样的数据为12位的,首先左移8位串口输出高4位uart_send_byte(val);	   //再输出低8位
}

注意:因为AD采样的数据是12位的数据,串口每次只能发送8位数据,需要分两次将12位数据进行发送; 

#ifndef __UART_H__
#define __UART_H__#include <reg51.h>void uart_init(void);
void uart_send_byte(unsigned char c);
void uart_send_adVal(unsigned int val);#endif

main.c函数 

#include "ET2046.h"
#include "uart.h"#define AIN0 0x94	  //滑动变阻器
#define AIN1 0xd4	  //热敏电阻
#define AIN2 0xa4	  //光敏电阻void delay1s(void)   //误差 0us
{unsigned char a,b,c;for(c=167;c>0;c--)for(b=171;b>0;b--)for(a=16;a>0;a--);
}void main()
{unsigned int ad_val = 0;uart_init();//uart_send_adVal(0xabc);	  //测试代码//uart_send_byte(0x0d);//uart_send_byte(0x0a);//while(1);while(1){ad_val= read_AD_value(AIN2);uart_send_adVal(ad_val);uart_send_byte(0);      	//发送数据0区分每次采样数值delay1s();				  //如何实现在串口调试助手中发送一次采样数据后换行?}}

思考:上述代码中,main函数是通过while()不断采样和发送AD转换的数据,如何通过中断来采样和发送AD转换数据? 

4,AD转换代码-直接在串口显示电压值 

串口助手中看到的数据以16进制显示或以对应字符形式来显示,因此在显示AD转换的电压时不直观,为了直观显示采集到的电压值,通过对采集到的电压值根据ASCii表对每一个十进制数转化为对应的数字符号,如下图所示,入药显示电压值中的数字5,只需要发送5+48的十进制数,在串口助手中就可以看到对应的符号5。

代码如下: 

5,DA转换 

待完善 

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

winform中嵌入cefsharp, 并使用selenium控制

正常说&#xff0c; 需要安装的包 下面是所有的包 全部代码 using OpenQA.Selenium.Chrome; using OpenQA.Selenium; using System; using System.Windows.Forms; using CefSharp.WinForms; using CefSharp;namespace WindowsFormsApp2 {public partial class Form1 : Form{//…

【Python】Web学习笔记_flask(5)——会话cookie对象

HTTP是无状态协议&#xff0c;一次请求响应结束后&#xff0c;服务器不会留下对方信息&#xff0c;对于大部分web程序来说&#xff0c;是不方便的&#xff0c;所以有了cookie技术&#xff0c;通过在请求和响应保温中添加cookie数据来保存客户端的状态。 html代码&#xff1a; …

数据统计与可视化的Dash应用程序

在数据分析和可视化领域&#xff0c;Dash是一个强大的工具&#xff0c;它结合了Python中的数据处理库&#xff08;如pandas&#xff09;和交互式可视化库&#xff08;如Plotly&#xff09;以及Web应用程序开发框架。本文将介绍如何使用Dash创建一个简单的数据统计和可视化应用程…

使用 BERT 进行文本分类 (02/3)

​ 一、说明 在使用BERT&#xff08;1&#xff09;进行文本分类中&#xff0c;我向您展示了一个BERT如何标记文本的示例。在下面的文章中&#xff0c;让我们更深入地研究是否可以使用 BERT 来预测文本是使用 PyTorch 传达积极还是消极的情绪。首先&#xff0c;我们需要准备数据…

冉冉升起的星火,再度升级迎来2.0时代!

文章目录 前言权威性评测结果 星火大模型多模态功能插件功能简历生成文档问答PPT生成 代码能力 福利 前言 前几天从技术群里看到大家都在谈论《人工智能大模型体验报告2.0》里边的内容&#xff0c;抱着好奇和学习的态度把报告看了一遍。看完之后瞬间被里边提到的科大讯飞的星火…

PHP实现在线年龄计算器

1. 输入日期查询年龄 2. php laravel框架实现 代码 /*** 在线年龄计算器*/public function ageDateCal(){// 输入的生日时间$birthday $this->request(birthday);// 当前时间$currentDate date(Y-m-d);// 计算周岁$age date_diff(date_create($birthday), date_create($…

SQL Server基础之游标

一&#xff1a;认识游标 游标是SQL Server的一种数据访问机制&#xff0c;它允许用户访问单独的数据行。用户可以对每一行进行单独的处理&#xff0c;从而降低系统开销和潜在的阻隔情况&#xff0c;用户也可以使用这些数据生成的SQL代码并立即执行或输出。 1.游标的概念 游标是…

LiveDataBus 其中的一个库LiveEventBus库的源码解析

EventBus事件通知的框架我们用了很久了&#xff0c;随着LiveData的出现&#xff0c;出现了LiveDataBus来替代EventBus,因为LiveDataBus 会考虑生命周期&#xff0c;EventBus你可能要注意在生命周期结束的时候unregister的&#xff0c;否则会有内存泄漏等问题&#xff0c;而Live…

采用pycharm在虚拟环境使用pyinstaller打包python程序

一年多以前&#xff0c;我写过一篇博客描述了如何虚拟环境打包&#xff0c;这一次有所不同&#xff0c;直接用IDE pycharm构成虚拟环境并运行pyinstaller打包 之前的博文&#xff1a; 虚拟环境venu使用pyinstaller打包python程序_伊玛目的门徒的博客-CSDN博客 第一步&#xf…

【深入了解PyTorch】PyTorch模型解释性和可解释性:探索决策过程与预测结果的奥秘

【深入了解PyTorch】PyTorch模型解释性和可解释性:探索决策过程与预测结果的奥秘 PyTorch模型解释性和可解释性:探索决策过程与预测结果的奥秘1. 引言2. 梯度可视化3. 特征重要性分析4. 结论PyTorch模型解释性和可解释性:探索决策过程与预测结果的奥秘 在机器学习和深度学习…

临床试验设计-平行设计、析因设计、交叉设计

平行设计、析因设计、交叉设计是临床试验中最重要的三种设计方法。 平行设计&#xff1a;最常见 交叉设计&#xff1a;生物等效性试验 析因设计&#xff1a;药物配伍 一、平行设计 双臂试验&#xff08;two-arm study&#xff09;&#xff08;两组&#xff09;&#xff1a;试验…

Steam 灵感的游戏卡悬停效果

先看效果&#xff1a; 再看代码&#xff08;查看更多&#xff09;&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Steam 灵感的游戏卡悬停效果</title><style>* {margin: …

【IMX6ULL驱动开发学习】04.应用程序和驱动程序数据传输和交互的4种方式:非阻塞、阻塞、POLL、异步通知

一、数据传输 1.1 APP和驱动 APP和驱动之间的数据访问是不能通过直接访问对方的内存地址来操作的&#xff0c;这里涉及Linux系统中的MMU&#xff08;内存管理单元&#xff09;。在驱动程序中通过这两个函数来获得APP和传给APP数据&#xff1a; copy_to_usercopy_from_user …

【Docker】Docker network之bridge、host、none、container以及自定义网络的详细讲解

&#x1f680;欢迎来到本文&#x1f680; &#x1f349;个人简介&#xff1a;陈童学哦&#xff0c;目前学习C/C、算法、Python、Java等方向&#xff0c;一个正在慢慢前行的普通人。 &#x1f3c0;系列专栏&#xff1a;陈童学的日记 &#x1f4a1;其他专栏&#xff1a;CSTL&…

分布式定时任务系列5:XXL-job中blockingQueue的应用

传送门 分布式定时任务系列1&#xff1a;XXL-job安装 分布式定时任务系列2&#xff1a;XXL-job使用 分布式定时任务系列3&#xff1a;任务执行引擎设计 分布式定时任务系列4&#xff1a;任务执行引擎设计续 Java并发编程实战1&#xff1a;java中的阻塞队列 引子 这篇文章的…

二.net core 自动化发布到docker (Jenkins安装之后向导)

目录 ​​​​​​​​​​​​​​ 参考资料&#xff1a;https://www.jenkins.io/doc/book/installing/docker/#setup-wizard Post-installation setup wizard.(安装后安装向导) 基于上一篇文章安装&#xff0c;在安装并运行Jenkins&#xff08;不包括使用Jenkins Opera…

日志采集分析ELK

这里的 ELK其实对应三种不同组件 1.ElasticSearch&#xff1a;基于Java&#xff0c;一个开源的分布式搜索引擎。 2.LogStash&#xff1a;基于Java&#xff0c;开源的用于收集&#xff0c;分析和存储日志的工具。&#xff08;它和Beats有重叠的功能&#xff0c;Beats出现之后&a…

6.3 社会工程学攻击

数据参考&#xff1a;CISP官方 目录 社会工程学攻击概念社会工程学攻击利用的人性 “弱点”典型社会工程学攻击方式社会工程学攻击防护 一、社会工程学攻击概念 什么是社会工程学攻击 也被称为 "社交工程学" 攻击利用人性弱点 (本能反应、贪婪、易于信任等) 进…

Reis过期删除策略

介绍 在Redis中&#xff0c;我们可以为键值对设置有效期&#xff0c;现在面临一个问题&#xff0c;如果一个键值对过期了&#xff0c;那么我们应该怎么删除呢&#xff1f; 我们目前有三种方案&#xff1a; 定时删除&#xff1a;在设置键的过期时间的同时&#xff0c;为此键设…

小游戏扫雷实现教学(详解)

目录 【前言】 一、模块化程序设计&#xff08;多文件编程&#xff09;介绍 1.概述 2.传统编程的方式 3.模块化程序设计的方法 二、扫雷代码设计思路 三、扫雷代码设计 1.创建菜单函数 2.实现9x9扫雷 3.初始化棋盘 4.打印棋盘 5.随机布置雷的位置 6.排查雷的信息 7.回…