目录
1.AD/DA元件介绍


一般传感器的值会随参数的值变化,AD一般对电压进行转换,AD有多个通道,但是DA只有一个通道,且AD的运用较为广泛,DA的可代替性强,一般使用PWM就可实现,运用没有AD那么广。
2.运算放大器



3.原理分析
(1)DA

占用较多L口,但是波形更加稳定,精度不可变,只有256这个精度,如果需要提高精度需要增加电路(较复杂)

两个低通滤波器滤波是为了让波形的效果更好,但这种方式波形较不稳定,精度较高,调节精度容易,占用较少L口.
(2)AD

通过用已知的DAC去比较未知的电压,不断去逼近未知的电压,去模拟未知电压的的值
4.性能指标

5.内部芯片时序

单独一个CS片选,通讯线共用,上升沿输入,下降沿输出,DIN和DOUT可以同时进行
cs拉低开始通信,第一个发送的为状态控制字,前三位(A2,A1,A0)为多路选择,8位和12位模式等等,发送完后可以读出两个字节,多出来的用0填充。

6.程序实操
1.AD模数转换
#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 ZPT2046读取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++)
{
XPY2046_DIN=Command&(0x80>>i);
XPY2046_DCLK=1;
XPY2046_DCLK=0;
}
for(i=0;i<16;i++)
{
XPY2046_DCLK=1;
XPY2046_DCLK=0;
if(XPY2046_DOUT){Data|=(0x8000>>i);}
}
XPY2046_CS=1;
return Data>>8;
}
---------------------------------------------------------------------------------
//.h文件
#ifndef __XPT2046_H__
#define __XPT2046_H__
#define XPT2046_VBAT 0xAC
#define XPT2046_AUX 0xEC
#define XPT2046_XP 0x9C //0xBC
#define XPT2046_YP 0xDC
unsigned int XPT2046_ReadAD(unsigned char Command);
#endif
--------------------------------------------------------
//main文件
#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); //读取AIN0,可调电阻
LCD_ShowNum(2,1,ADValue,3); //显示AIN0
ADValue=XPT2046_ReadAD(XPT2046_YP); //读取AIN1,热敏电阻
LCD_ShowNum(2,6,ADValue,3); //显示AIN1
ADValue=XPT2046_ReadAD(XPT2046_VBAT); //读取AIN2,光敏电阻
LCD_ShowNum(2,11,ADValue,3); //显示AIN2
Delay(100);
}
}
2.DA数模转换(和PWM类似)
#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
}
}
