目录
一、什么是AD转换
ADC(analog to digital converter)也称为模数转换器,是指一个将模拟信号转变为数字信号。单片机在采集模拟信号时,通常都需要在前端加上 A/D 芯片。
1. 采样:采样是指在一定时间间隔内获取模拟信号的离散样本。采样频率决定了每秒采样的样本数,通常以赫兹(Hz)为单位。
2. 量化和编码:量化是将连续的模拟信号幅度值转换为离散的数字值。通过将模拟信号幅度值映射到离散级别上,实现对模拟信号的离散表示;编码将量化后的样本值表示为二进制数据,以便将其存储或传输。常用的编码方法包括二进制编码和压缩编码。
二、什么是DA转换
DAC(Digital to analog converter)即数字模拟转换器,它可以将数字信号转换为模拟信号。它的功能与 ADC 相反。在常见的数字信号系统中,大部分传感器信号被转化成电压信号,而 ADC 把电压模拟信号转换成易于计算机存储处理的数字编码,由计算机处理完成后,再由 DAC 输出电压模拟信号,该电压模拟信号常常用来驱动某些执行器件,使人类易于感知。如音频信号的采集及还原就是这样一个过程。
1. 数字数据:数字数据通常以二进制形式表示,并存储在计算机系统或其他数字设备中。
2. 重构:DA转换器通过重构技术将数字数据转换为连续的模拟信号。重构过程中,数字样本被插值和滤波,使其变得连续且光滑。
3. 输出模拟信号:DA转换器的输出是通过模拟电路和滤波器处理后的连续模拟信号。输出信号的连续性和精确性取决于DA转换器的性能。
三、相关硬件电路
![db35281f520c40f8a31ae40b89fba5bf.png](https://i-blog.csdnimg.cn/blog_migrate/75526baddfd2dd34548914c37ed4fe0a.png)
![6a4baac4e2b0429ead774a38d2175e60.png](https://i-blog.csdnimg.cn/blog_migrate/80cbf1e681b11d0dc4f8018cb8e1f053.png)
![e7b0a0b590b443f58888deb310a2aacb.png](https://i-blog.csdnimg.cn/blog_migrate/378e6c5bb4f1b05b1f95116c54a5876d.png)
四、运算放大器
![50d2bde0b46c4c3c93565a3dc79210b9.png](https://i-blog.csdnimg.cn/blog_migrate/168085bd0af7186d48dc3dafbd225fd7.png)
![51feaf4840784369817c8b895c5cc620.png](https://i-blog.csdnimg.cn/blog_migrate/e7ff0b129a0b25916437d0fcaa16be3e.png)
五、XPT2046芯片介绍
XPT2046 是一款 4 线制电阻式触摸屏控制器,内含 12 位分辨率 125KHz转换速率逐步逼近型 A/D 转换器。XPT2046 支持从 1.5V 到 5.25V 的低电压I/O 接口。XPT2046 能通过执行两次 A/D 转换查出被按的屏幕位置,除此之外,还可以测量加在触摸屏上的压力。内部自带 2.5V 参考电压,可以作为辅助输入、温度测量和电池监测之用,电池监测的电压范围可以从 0V 到 6V。XPT2046 片内集成有一个温度传感器。在 2.7V 的典型工作状态下,关闭参考电压,功耗可小于 0.75mW。XPT2046 采用微小的封装形式:TSSOP16,QFN-16 和 VFBGA-48。工作温度范围为-40℃~+85℃。与ADS7846、TSC2046、AK4182A 完全兼容。
对DIN进行剖析:
1.起始位——第一位,即 S 位。控制字的首位必须是 1,即 S=1。在 XPT2046 的 DIN 引脚检测到起始位前,所有的输入将被忽略。
2.地址——接下来的 3 位(A2、A1 和 A0)选择多路选择器的现行通道,触摸屏驱动和参考源输入。
3.模式选择位,用于设置 ADC 的分辨率。MODE=0,下一次的转换将是 12 位模式;MODE=1,下一次的转换将是 8 位模式。
4.SER/ ——DFR ——SER/ —— DFR 位控制参考源模式,选择单端模式(SER/ —— DFR =1),或者差分模式(SER/ ——DFR =0)。在X坐标、Y坐标和触摸压力测量中,为达到最佳性能,首选差分工作模式。参考电压来自开关驱动器的电压。在单端模式下,转换器的参考电压固定为VREF相对于GND引脚的电压。(在此学习中,X-直接接地,所以我们只需在单端模式下读取X+即可)
5.低功率模式选择位。若为 11,器件总处于供电状态;若为 00,器件在变换之间处于低功率模式。(此处我们选用00)
*模式选择位插图
1.XPT2046.c
#include <REGX52.H>
#include <INTRINS.H>
//引脚定义
sbit XPY2046_DIN=P3^4;
sbit XPY2046_CS=P3^5;
sbit XPY2046_DCLK=P3^6;
sbit XPY2046_DOUT=P3^7;
/**
* @brief XPT2046读取AD值
* @param Command 命令字,范围:头文件内定义的宏,结尾的数字表示转换的位数
* @retval AD转换后的数字量,范围:8位为0~255,12位为0~4095
*/
unsigned int XPT2046_ReadAD(unsigned char Command)
{
unsigned char i;
unsigned int Data=0;
XPY2046_DCLK=0;//一开始为低电频
XPY2046_CS=0;//一开始为低电频
for(i=0;i<8;i++)//此循环依次将DIN中的八位发出去
{
XPY2046_DIN=Command&(0x80>>i);
XPY2046_DCLK=1;//上升沿后DIN发出数据
XPY2046_DCLK=0;//下降沿后循环8次
}
for(i=0;i<16;i++)//此循环依次将DOUT中的16位读出来
{
XPY2046_DCLK=1;
XPY2046_DCLK=0;//先给上升沿再给下降沿数据才会到DOUT
if(XPY2046_DOUT){Data|=(0x8000>>i);}
}
XPY2046_CS=1;
if(Command&0x08)
{
return Data>>8;//当DIN中的MODE=1,DOUT读取八位而时序中有16位且后八位为零填充 所以右移八位目的是只读取前八位
}
else
{
return Data>>4;//当DIN中的MODE=0,DOUT读取十二位而时序中有16位且后4位为零填充 所以右移4位目的是只读取前十二位
}
}
2.XPT2046.h
#ifndef __XPT2046_H__
#define __XPT2046_H__
//分别对VBAT、AUX、XP、YP进行测量
#define XPT2046_VBAT_8 0xAC
#define XPT2046_AUX_8 0xEC
#define XPT2046_XP_8 0x9C//0x8C
#define XPT2046_YP_8 0xDC
#define XPT2046_VBAT_12 0xA4
#define XPT2046_AUX_12 0xE4
#define XPT2046_XP_12 0x94//0x84
#define XPT2046_YP_12 0xD4
unsigned int XPT2046_ReadAD(unsigned char Command);
#endif
(1).AD模数转换代码
#include <REGX52.H>
#include "Delay.h"
#include "LCD1602.h"
#include "XPT2046.h"
unsigned int ADValue;
void main(void)
{
LCD_Init();
LCD_ShowString(1,1,"ADJ NTC GR");
while(1)
{
ADValue=XPT2046_ReadAD(XPT2046_XP_8); //读取AIN0,可调电阻
LCD_ShowNum(2,1,ADValue,3); //显示AIN0
ADValue=XPT2046_ReadAD(XPT2046_YP_8); //读取AIN1,热敏电阻
LCD_ShowNum(2,6,ADValue,3); //显示AIN1
ADValue=XPT2046_ReadAD(XPT2046_VBAT_8); //读取AIN2,光敏电阻
LCD_ShowNum(2,11,ADValue,3); //显示AIN2
Delay(100);
}
}
现象:调节可调电阻时屏幕的ADJ值会发生变化,相应的热敏电阻和光敏电阻与其一样
(2).DA模数转换代码
#include <REGX52.H>
#include "Delay.h"
#include "Timer0.h"
sbit DA=P2^1;
unsigned char Counter,Compare; //计数值和比较值,用于输出PWM
unsigned char i;
void main()
{
Timer0_Init();
while(1)
{
for(i=0;i<100;i++)
{
Compare=i; //设置比较值,改变PWM占空比
Delay(10);
}
for(i=100;i>0;i--)
{
Compare=i; //设置比较值,改变PWM占空比
Delay(10);
}
}
}
void Timer0_Routine() interrupt 1
{
TL0 = 0x9C; //设置定时初值
TH0 = 0xFF; //设置定时初值
Counter++;
Counter%=100; //计数值变化范围限制在0~99
if(Counter<Compare) //计数值小于比较值
{
DA=1; //输出1
}
else //计数值大于比较值
{
DA=0; //输出0
}
}
现象:AD/DA模块的灯会以呼吸灯形式呈现