51单片机-AD/DA

一、运算放大器

  • 运算放大器(简称:运放)是具有很高效的放大倍数的放大电路单元
  • 运算放大器可构成的电路有:电压比较器、反向放大器、同向放大器、电压跟随器、加法器、积分器、微分器等

  下面是四种运放电路和输出电压公式

  • 电压比较器
    Alt
    Alt

  • 反向放大器
    Alt
    Alt

  • 同向放大器
    Alt
    Alt

  • 电压跟随器
    Alt
    Alt

二、AD/DA介绍

  • AD(Analog to Digital):模拟-数字转换,将模拟信号转换为计算机可以操作的数字信号,例如将模拟电压转换为数字量,可以应用在光敏、热敏、麦克风等等一些外设上
  • DA(Digital to Analog):数字-模拟转换,将计算机输出的数字信号转换为模拟信号

2.1 AD/DA硬件电路模型

  • AD硬件电路模型如下所示

Alt

  • DA硬件电路模型如下所示

Alt

  • AD转换通常有多个输入通道,用多路选择开关连接至AD转换器,以实现AD多路复用的目的,提高硬件利用率
  • AD/DA与单片机数据传送可使用并行口或者串行口
  • 可以将AD/DA模块直接集成在单片机内,这样直接写入/读出寄存器就可以进行AD/DA转换,单片机的IO口可以直接复用为AD/DA的通道

2.2 AD/DA工作原理图

2.2.1 AD工作原理图

  下面两张图为一个AD转换模块内部原理图
  IN0-IN7是8路输入通道,通过地址锁存确定哪路开关打开,经过逐次逼近最终得到数字量

Alt
  具体的逐次逼近图如下所示
  逐次逼近型:DAC的模拟电压已知编码电压,VIN的量是未知编码电压(待测)的,两者同时输入到电压比较器(输出高低电平判断谁大谁小)不断比较DAC的输出电压和VIN,如果DAC大,就调小DAC数据,反之就增大DAC数据,通过不断调整DAC的模拟电压,直到DAC的输出电压无限接近外部通道输入的电压VIN,DAC的输入数据(SAR完成-二分法)就是外部电压的编码数据,即VIN的8位数字量,存到缓冲器,最终输出8位数字量
  数字量公式如下

在这里插入图片描述  其中VIN是输入电压,VREF是参考电压,51系列单片机是5V,D7-D0是输出的八位数字量

Alt

2.2.2 DA工作原理图

  下图为PWM型DA转换器输出电压V0为(PWM占空比)×Vh

Alt
  下图为DA模块内部原理图,输入数据经过DA模块,输出模拟电压值

Alt

  下面为8位D/A转换器具体原理图

在这里插入图片描述Alt

  VREF就是我们输入的参考电压,Rfb是反馈电阻,D7-D0是当我们将开关拨到0或者1时的二进制数

2.3 AD/DA性能指标

  • 分辨率:指AD/DA数字量的精细程度,通常用位数表示。例如在5v系统中,8位的AD将5V等分为256份,即数字量变化最小一个单位时,模拟量变化5V/256,所以位数越高,则分辨率越高
  • 转换速度:表示AD/DA的最大采样/建立频率,通常用转换频率或者转换时间来表示,对于采样/输出高速信号,应该注意转换速度

三、AD应用-XPT2046

  DA可以用PWM波去模拟,所以这里不用去特地了解,AD在日常开发过程中用的比较多,这里以XPT2406去应用一下AD

3.1 XPT2046介绍

  • XPT2046是一款触摸屏控制器,这点我们无需理会,只需要知道它内置了12分辨率AD转换器

  下图为XPT2046模块电路原理图,其含逐次逼近型AD转换模块
  CS使能,DCLK串行时钟线,DIN是地址输入,DOUT是输出AD转换完成的数字量
  AIN0、1、2连接在了传感器的模拟输出口
  传感器的模拟量通过AINx进入AD模块,转换成数字量以后通过DOUT引脚输出给单片机
在这里插入图片描述

3.2 XPT2046时序介绍

  CS非作为使能线,可以接多个设备进行片选,每一个芯片单独有一个CS非,同一时间如果想和哪个设备通信,则就给CS非0
  DCLK串行时钟线,一次转换需要24个时钟来完成,上升沿输入,下降沿输出DIN输入,在前8个时钟里,主要是对通信地址一些配置;DOUT主要是发送AD转换后的数字量,可以看出在后4位都是以0进行填充的

在这里插入图片描述

3.3 XPT2046代码编写

  本次代码的编写,主要是对通信时序的编写,此通信协议主要分为两块,MCU先给XPT2046发送数据,随之XPT2046再给MCU发送转换好的数字量
  下面给出XPT2046.c

#include <REGX52.H>

sbit XPT2046_CS = P3^5;
sbit XPT2046_DCLK = P3^6;
sbit XPT2046_DIN = P3^4;
sbit XPT2046_DOUT = P3^7;

/*
函数功能:XPT去读取指定传感器的模拟值,内置的AD模块会得到数字量发送给MCU
形式参数:命令字(读那个通道)
返回值:传感器数字量
*/
unsigned int XPT2046_ReadAD(unsigned char Command)			//命令字(手册):起始位+地址(AD通道)+模式选择...
{
	unsigned char i;
	unsigned int ADValue = 0;		//XPT2046发给MCU的数字量
	XPT2046_DCLK = 0;		//初始化
	XPT2046_CS = 0;		//使能
	for(i = 0;i<8;i++)		//MCU将前8位发送给XPT2046,以配置地址
	{
		XPT2046_DIN = Command&(0x80>>i);		//高位在前
		XPT2046_DCLK = 1;
		XPT2046_DCLK = 0;		//上升沿输入,MCU给芯片发
	}
	for(i = 0;i<16;i++)		//后16位是XPT2046发送给MCU
	{
		XPT2046_DCLK = 1;
		XPT2046_DCLK = 0;		
		if(XPT2046_DOUT){ADValue|=(0x8000>>i);}		//下降沿输出,芯片给MCU发16位数据,DOUT上就是存的数字量
	}
	XPT2046_CS = 1;
	if(Command&0x08)		//8位分辨率
	{
		return ADValue>>8;		//ADValue一共16位,低8位全是0,
	}
	else		//12位分辨率
	{
		return ADValue>>4;		//ADValue一共16位,低4位全是0
	}
}

  宏定义地址和分辨率

#define XPT2046_XP_8			0x9C
#define XPT2046_YP_8			0xDC
#define XPT2046_VBAT_8			0xAC
#define XPT2046_AUX_8			0xEC

#define XPT2046_XP_12			0x94
#define XPT2046_YP_12			0xD4
#define XPT2046_VBAT_12			0xA4
#define XPT2046_AUX_12			0xE4

  上述代码中8和12分别代表分辨率,可以进行不同分辨率的显示

  在LCD1602显示出转换后的数字量,给出main.c

#include <REGX52.H>
#include "Delayms.h"
#include "LCD1602.h"
#include "XPT2046.h"

unsigned int ADValue;

void main()
{
	LCD_Init();
	LCD_ShowString(1,1,"ADJ  NTC  RG");			//可变电阻  热敏电阻 光敏电阻
	while(1)
	{
		ADValue = XPT2046_ReadAD(XPT2046_XP_8);		//单片机发送地址给XPT读某一个传感器的模拟值,经过AD处理后返回数字量,发送给单片机
		LCD_ShowNum(2,1,ADValue,3);
		ADValue = XPT2046_ReadAD(XPT2046_YP_8);
		LCD_ShowNum(2,6,ADValue,3);
		ADValue = XPT2046_ReadAD(XPT2046_VBAT_8);
		LCD_ShowNum(2,11,ADValue,3);
		Delayms(10);
	}
}
### 51单片机AD转换基础知识 51单片机本身并不具备模拟到数字(A/D)转换的功能,因此通常需要外接专用的A/D转换芯片来完成这一功能。常用的A/D转换器之一是ADC0808,它是一款具有8位分辨率的逐次逼近型模数转换器[^1]。 #### ADC0808的主要特性 - **输入通道数量**:支持多达8路模拟信号输入。 - **分辨率**:提供8位二进制输出,表示范围为0至255之间的整数值。 - **工作电压**:典型的工作电源电压为+5V。 - **接口方式**:通过三态缓冲器与微处理器的数据总线连接,便于数据读取操作。 #### 连接配置说明 为了使能ADC0808正常运行并与51系列单片机协同作业,需按照如下方式进行硬件连线设置: - 将START引脚拉高触发一次转换过程;EOC作为结束标志通知CPU可以获取结果; - OE开放允许访问内部寄存器中的数字化后的样本值; - 地址锁存允许ALE控制多路选择开关切换不同的输入源端口INn(n=0~7)[^1]. 以下是基于Keil C编写的简单测试程序用于演示如何利用定时中断驱动ADC采样流程: ```c #include <reg51.h> sbit START = P2^1; // 定义启动信号 sbit EOC = P2^2; // 转换完成状态检测 sbit OEU = P2^3; // 输出使能 unsigned char AdcValue; void delay(unsigned int i){ while(i--); } void Init_ADC(){ START = 0; EOC = 0; OEU = 0; } // 开始一次新的测量周期 void Start_Adc(void){ START = 1; delay(1); // 短暂延时确保指令生效 START = 0; } // 查询模式等待直到当前任务完毕后再继续执行其他动作 unsigned char GetAdcResult(void){ unsigned char result; while(!EOC); // 循环监视直至准备好为止 OEU = 1; // 打开门电路让主机能够看见最终答案 result=P0; // 直接映射P0口得到量化等级编码形式的结果 OEU = 0; // 关闭共享资源防止干扰后续逻辑判断依据 return result; } void main() { Init_ADC(); while (1) { Start_Adc(); AdcValue = GetAdcResult(); /* 对采集回来的数据做进一步处理 */ } } ``` 上述代码片段展示了基本框架结构下的初始化步骤以及核心函数定义部分。实际应用过程中可能还需要考虑更多细节比如校准误差补偿机制或者抗混叠滤波设计等问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值