2025年十四、51单片机之AD转换

十四、51单片机之AD转换1 AD 相关简介 1 1 什么是 AD 转换 1 A 是指 analog 模拟的 D 是指 digital 数字的 2 现实世界是模拟的 连续分布的 无法被分成有限份 计算机世界是数字的 离散分布的 是可以被分成有限份的

大家好,我是讯享网,很高兴认识大家。

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-4 A2-A0,选择模拟通道
bit3 设置采样位数。0表示12bit,1表示8bit
bit2 为1表示用单端模式,为0表示差分模式。此处用单端模式。
bit1-0 power 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转换输入的模拟量(电压值),有时会受一些物理量的影响。所以物理量的值对应电压值。

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

小讯
上一篇 2025-03-03 20:25
下一篇 2025-01-09 21:48

相关推荐

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/39545.html