十四、51单片机之AD转换

news2024/11/16 5:33:41

1、AD相关简介

1.1、什么是AD转换?

(1)A是指analog、模拟的;D是指digital、数字的。

(2)现实世界是模拟的,连续分布的,无法被分成有限份;计算机世界是数字的,离散分布的,是可以被分成有限份的;

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

1.2、AD转换的意义

自然界多数是模拟量,为了方便计算机处理,人为的数字化了自然界的模拟量。

1.3、STC89C516

该单片机本身引脚没有模拟的,所以模拟量不能直接给该单片机。后续很多新的单片机都具有模拟输入输出的引脚,引脚会对应相应的AD转换。

1.4、AD转换原理

(1)采用比较器电路进行AD转换。

1.5、AD转换中的主要概念

(1)位数: AD转换后转出来的数由几位二进制来表示。位数越多,越细腻,精度越高。

(2)量程:AD转换器可以接受的模拟量的范围。

(3)精度:简单理解就是转出来到底有多准

(4)分辨率:AD转换器转出来的二进制数,每一格表示多少

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

1.6、AD转换在系统中存在的方式

(1)CPU外部扩展专用AD芯片

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

2、原理图

2.1、简介

(1)ET2046是我们外接的AD转换芯片。

(2)AIN0、AIN1、AIN2为三路AD转换。

(3)AD1502是一个滑动变阻器;NTC1是一个热敏电阻;GR1是一个光敏电阻。

2.2、接线

(1)CLK 接P1.0、T-CS接P1.1、DI接P1.2、DOUT接P1.3。

(2)CLK为SPI时钟线。

(3)T-CS为使能线。

(4)DI是数字输入线,DOUT是数字输出线。

3、ET2046数据手册

该芯片已停产,官网没搜到,数据手册链接:ET2046 - 百度文库

(1)ET2046是4线触摸屏控制器,在此用于AD转换。ET2046是一个经典的逐次逼近寄存器模数转换器。

(2)转换器模拟通道:X-、Y-、Z坐标、辅助输入(AUX)、电池电压(VBAT)、芯片温度。通过一个多路选择器提供。

(3)控制字

bit7固定为1
bit6-4A2-A0,选择模拟通道
bit3设置采样位数。0表示12bit,1表示8bit
bit2为1表示用单端模式,为0表示差分模式。此处用单端模式。
bit1-0power down模式使能,00表示使能。

4、示例程序

通过ET2046将模拟电压值转换位12bit数字量,并通过串口以文本方式显示。

 (1)app.c文件

#include <reg51.h>
#include "et2046.h"
#include "drv_uart.h"

void Delay500ms();		//@12MHz

void main()
{
	uint AD_Value = 0;   /*AD值*/
	uchar AD_H = 0;      /*AD值高4位*/
	uchar AD_L = 0;      /*AD低8位*/
	UartInit();           /*串口初始化函数*/
	while(1)
	{
		AD_Value = Read_AD_Data(0x94);    /*滑动变阻器*/
		
		/*16进制显示采集的12bitAD值*/
		//AD_H = AD_Value >> 8;
		//AD_L = AD_Value & 0xff;  /*按位与*/
		//UartSendByte(AD_H);
		//UartSendByte(AD_L);
		
		/*文本形式显示采集的AD值,0xFFF = 4095*/
		UartSendString("AD_Value:");
		UartSendByte((AD_Value / 1000) + 48);       /*显示千位*/
		UartSendByte((AD_Value % 1000 /100) + 48);  /*显示百位*/
		UartSendByte((AD_Value % 100 /10) + 48);    /*显示十位*/
		UartSendByte((AD_Value % 10 ) + 48);        /*显示个位*/
		UartSendString(".\r\n");
		
		
		Delay500ms();
	}
}


void Delay500ms()		//@12MHz
{
	unsigned char i, j, k;

	_nop_();
	i = 4;
	j = 205;
	k = 187;
	do
	{
		do
		{
			while (--k);
		} while (--j);
	} while (--i);
}


(2)ET2046.c文件

#include "ET2046.h"


/*
 *功能:SPI写字节函数
 *参数:	Data:写入的数据
 *返回值:无
 */

void SPI_WriteByte(uchar Data)
{
	uchar i = 0;   /*用于for循环*/
	CLK = 0;
	
	
	for(i=0; i<8; i++)
	{
		DIN = Data >> 7;  	//从高位到低位写入
		Data <<= 1;
		CLK = 0;			      //上升沿放置数据
		CLK = 1;
	}
}


/*功能:SPI读12bit
 *参数:无
 *返回值:读取到的数据
 */
uint SPI_Read(void)
{
	uint i = 0;         /*用于for循环*/ 
	uint Data = 0;      /*暂存读取到的书*/
	CLK = 0;
	for(i=0; i<12; i++)	  /*接收12位数据*/
	{
		Data <<= 1;
		CLK = 1;
		CLK = 0;
		Data |= DOUT;
	}
	return Data;	
}

/*
 *功能:读取AD值  
 *参数: cmd:读取对应通道发送的控制字
 *返回值:读取的AD值
 */
uint Read_AD_Data(uchar cmd)
{
	uchar i = 0;    /*用于for循环*/
	uint AD_Value;  /*记录AD的值*/
	
	CLK = 0;
	CS  = 0;
	SPI_WriteByte(cmd);
	for(i=6; i>0; i--); 	/*延时等待转换结果*/
	
	CLK = 1;	            /*发送一个时钟周期,清除BUSY*/
	_nop_();
	_nop_();
	CLK = 0;
	_nop_();
	_nop_();
	AD_Value=SPI_Read();
	CS = 1;
	return AD_Value;	
}


(3)ET2046.h文件

#ifndef __ET2046_H__
#define __ET2046_H__

/*头文件包含*/
#include <reg51.h>
#include <intrins.h>


/*宏定义*/
#define uchar unsigned char
#define uint  unsigned int


/*定义使用的IO口*/
sbit CLK  = P1^0;	  //时钟
sbit CS   = P1^1;	  //片选
sbit DIN  = P1^2;	  //输入
sbit DOUT = P1^3;	  //输出


/*函数声明*/
void SPI_WriteByte(uchar Data);   /*SPI写字节函数*/
uint SPI_Read(void);              /*SPI读12bit*/
uint Read_AD_Data(uchar cmd);




#endif

(4)drv_uart.c文件

#include "drv_uart.h"
#include <reg51.h>


/*
 *功能:串口初始化函数,8数据位,1停止位,无校验位,波特率4800
 *参数:无
 *返回值:无
 */
void UartInit(void)
{
	SCON = 0x50;  //串口工作在模式1,8位数据位,允许串行接收
	PCON = 0x80;  //波特率加倍
	TMOD = 0x20;  //设置T1为模式2 
	TH1 = 243;    //波特率4800	,TH1 = 晶振频率/12/32/波特率
	TL1 = 243;    //8位自动重装,意识是TH1用完了之后下一个周期TL1会自动重装到TH1去。
	TR1 = 1;      //开启定时器1
	ES = 1;       //打开串口中断
	EA = 1;       //打开总中断
}


/*
 *功能:通过串口发送一个字节数据
 *参数:需要发送的内容
 *返回值:无
 */
void UartSendByte(unsigned char Dat)
{
	SBUF = Dat;      //准备好需要发送的一个字节
	while(TI == 0);  //确认串口发送没有再忙,while循环需要加超时判断
	TI = 0;					 //软件复位TI标志位
}


/*
 *功能:通过串口发送字符串
 *参数:待发送的字符串
 *返回值:无
 */
void UartSendString(unsigned char *str)
{
	while(*str != '\0')    //等待字符串发完*/
	{
		UartSendByte(*str);  //发送一个字符
		str++;               //指针指向下一个字符
	}
}


/*
 *功能:串口中断接收函数
 *参数:无
 *返回值:无
 *注意:中断函数通过中断编号识别,中断编号可通过查数据手册得到
 */
void Uart_Isr() interrupt 4 
{
	unsigned char ReceiveBit;
	if(RI == 1)
	{
		ReceiveBit = SBUF;		//读取SBUF,读取串口接收到的一个字节
		RI = 0;
	}
	//UartSendByte(ReceiveBit);		  //接收到的内容原封不动发回去
}

(5)drv_uart.h文件

#ifndef __DRV_UART_H__
#define __DRV_UART_H__


/*函数声明*/
void UartInit(void);                       /*串口初始化函数*/
void UartSendByte(unsigned char Dat);      /*通过串口发送一个字节数据*/
void UartSendString(unsigned char *str);   /*通过串口发送字符串*/

#endif

5、AD转换涉及的值

(1)AD转换芯片引脚输入一个模拟量,这个模拟值本质上讲是电压,根据AD转换的位数,电压值对应一个AD值(数字量)。

(2)AD转换输入的模拟量(电压值),有时会受一些物理量的影响。所以物理量的值对应电压值。

例如:光敏电阻光强不同,采集到的电压也会不相同。即光强度对应电压值。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Springboot +Flowable,详细解释啥叫流程实例(二)

一.简介 上一篇中学习了Flowable 中的流程模板&#xff08;流程定义&#xff09;的部署问题&#xff0c;这一篇来学习什么叫流程实例。 部署之后的流程模板&#xff0c;还不能直接运行&#xff0c;例如我们部署了一个请假流程&#xff0c;现在 张三想要请假&#xff0c;他就需…

交叉小波变换(cross wavelet transform)是什么?

小波变换可以很好的在时频域中分析单个信号的瞬态和突变等时变特性&#xff0c;交叉小波变换是在小波变换的基础上提出的&#xff0c; 主要用来处理两个信号之间的相关程度。传统的互相关分析方法&#xff0c; 是通过傅里叶变换将信号从时域上转换到频域上&#xff0c;然后在频…

JavaScript实现输入数值求运算符的值

以下为a&#xff0c;a--&#xff0c;--a&#xff0c;a等运算符实现结果的代码 目录 前言 一、运算符&#xff08;x&#xff09; 2.1运行流程及思想 2.2代码段 2.3运行截图 二、运算符&#xff08;--x&#xff09; 3.1运行流程及思想 3.2代码段 3.3运行截图 三、输入数…

论文阅读 (88):Adversarial Examples for Semantic Segmentation and Object Detection

文章目录 1. 概述2 算法2.1 稠密对抗生成2.2 选择用于检测的输入提案 1. 概述 题目&#xff1a;用于语义分割和目标检测的对抗样本 核心点&#xff1a;将对抗性样本的概念扩展到语义分割和对象检测&#xff0c;并提出稠密对抗生成算法 (Dense adversary generation, DAG)。 引…

Python每日一练(20230427)

目录 1. 三数之和 &#x1f31f;&#x1f31f; 2. 编辑距离 &#x1f31f;&#x1f31f;&#x1f31f; 3. 翻转字符串里的单词 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏…

无人机监控交通流量实时传输路况智慧交通系统说明

项目介绍&#xff1a; “现在五星花园环岛通行状况良好&#xff0c;涪江路双向的通行状况也未出现拥堵&#xff0c;接送考生的车辆可以畅通行驶……”昨日上午 8 点 20 分&#xff0c;FM91.5南充交通音乐广播首次启用遥控无人飞行器服务考生。对市区易堵路段&#xff0c;特别是…

学成在线笔记+踩坑(10)——课程搜索、课程发布时同步索引库。

导航&#xff1a; 【黑马Java笔记踩坑汇总】JavaSEJavaWebSSMSpringBoot瑞吉外卖SpringCloud黑马旅游谷粒商城学成在线牛客面试题_java黑马笔记 目录 1 【检索模块】需求分析 1.1 全文检索介绍 1.2 业务流程 1.2.1、课程发布时索引库里新增一条记录 1.2.2、课程搜索 2 准…

Matlab论文插图绘制模板第88期—无向图/图论网络图

在之前的文章中&#xff0c;分享了Matlab线图的绘制模板&#xff1a; 进一步&#xff0c;再来分享一种特殊的线图&#xff1a;无向图。 先来看一下成品效果&#xff1a; 特别提示&#xff1a;本期内容『数据代码』已上传资源群中&#xff0c;加群的朋友请自行下载。有需要的朋…

FreeRTOS 信号量(三) ------ 优先级翻转

一、优先级翻转 (1) 任务 H 和任务 M 处于挂起状态&#xff0c;等待某一事件的发生&#xff0c;任务 L 正在运行。 (2) 某一时刻任务 L 想要访问共享资源&#xff0c;在此之前它必须先获得对应该资源的信号量。 (3) 任务 L 获得信号量并开始使用该共享资源。 (4) 由于任务 H…

mysql慢查询日志

概念 MySQL的慢查询日志是MySQL提供的一种日志记录&#xff0c;它用来记录在MySQL中响应时间超过阀值的语句&#xff0c;具体指运行时间超过long_query_time值的SQL&#xff0c;则会被记录到慢查询日志中。long_query_time的默认值为10&#xff0c;意思是运行10秒以上的语句。…

计算机图形学 | 投影变化

计算机图形学 | 投影变化 计算机图形学 | 投影变化7.1 有趣的投影投影的概念平行投影正投影斜投影 透视投影 7.2 规范化的投影变换观察的要素观察空间规范化的投影变换 华中科技大学《计算机图形学》课程 MOOC地址&#xff1a;计算机图形学&#xff08;HUST&#xff09; 计算…

Flink时间和窗口

事件时间 到达时间 处理时间 水位线 1.有序流 2. 无序流 水位线离源越近越好 Flink 自带水位线 有序 WatermarkStrategy.<Event>forMonotonousTimestamps() 或者实现WatermarkStrategy接口 水位线生成 时间字段 乱序 WatermarkStrategy.<Event>forBoundedOut…

【MySQL高级】——InnoDB索引MyISAM索引

一、索引概述 MySQL官方对索引的定义为&#xff1a;索引&#xff08;Index&#xff09;是帮助MySQL高效获取数据的数据结构。 索引的本质&#xff1a;索引是数据结构。你可以简单理解为“排好序的快速查找数据结构”&#xff0c;满足特定查找算法。 这些数据结构以某种方式指向…

Redis基础知识概述

Redis基础知识概述 文章目录 Redis基础知识概述一、Redis简介二、NoSQL技术三、Redis的高并发和快速原因四、Redis为什么是单线程的 五、单线程的优劣势1、优势2、劣势 六、Redis高并发总结七、在java中使用Redis1、添加Jedis依赖 八、Redis在Java Web中的应用1、存储缓存用的数…

亿发软件:按需定制ERP管理解决方案,更合适的企业智能管理软件

亿发软件&#xff1a;按需定制ERP管理解决方案&#xff0c;更合适的企业智能管理软件 在当今瞬息万变的商业环境中&#xff0c;企业面临着新的挑战和机遇。随着国内传统市场的衰落和国际化发展的加速&#xff0c;市场竞争日趋激烈&#xff0c;企业必须寻找新的创新和适应方式才…

Linux基本指令和操作(2)

目录 一. 适配符 * 二. man指令 -- 查看手册 三. echo指令 -- 输出字符串到文件 四. cp指令 -- 复制 五. mv指令 -- 重命名或移动文件&#xff08;剪切&#xff09; 六. which指令 -- 查看指令所在的路径 七. alis指令 -- 指令重命名 八. cat指令 -- 输出文件内容 九…

7.微服务项目实战---Rocketmq--消息驱动

7.1 MQ简介 7.1.1 什么是MQ MQ &#xff08; Message Queue &#xff09;是一种跨进程的通信机制&#xff0c;用于传递消息。通俗点说&#xff0c;就是一个先进先出的数据结构。 7.1.2 MQ的应用场景 7.1.2.1 异步解耦 最常见的一个场景是用户注册后&#xff0c;需要发送注…

怎么注册Google账号(使用国内手机号注册)

怎么注册Google账号&#xff08;使用国内手机号注册&#xff09; 记录一下如何用 国内的手机号 注册Google账号 文章目录 怎么注册Google账号&#xff08;使用国内手机号注册&#xff09;进入Google官网创建账号注册信息填写手机号&#xff08;踩坑版&#xff09;填写手机号&am…

MySQL——超详细数据库触发器教程

文章目录 一、触发器的概念 二、创建触发器 三、查看触发器 四、删除触发器 一、触发器的概念 在实际开发中往往会碰到这样的情况&#xff1a; 当我们对一个表进行数据操作时&#xff0c;需要同步对其它的表执行相应的操作&#xff0c;正常情况下&#xff0c;如果我们使用s…

C语言字符串函数,字符函数,内存操作函数

提示&#xff1a; 本篇文章涉及到以下内容: 求字符串长度 strlen 长度不受限制的字符串函数(被VS认为不安全,就像scanf)–>非法也要完成任务 strcpy 拷贝(将原字符串内容和\0全拷贝过去) strcat 追加(先找到目标空间中的\0,然后把原字符串中的内容直到\0全拷贝过去,原字符串…