D/A转换器:数字量D和模拟量A之间的转换。
D——》A:((高电平-低电平)/2^8 )*n n:输出的八位对应的十六进制数据对应的十进制
基本原理:
性能指标:
1、分辨率
分辨率是指输入数字量的最低有效位(LSB)发生变化时,所
对应的输出模拟量(电压或电流)的变化量。它反映了输出模
拟量的最小变化值。
分辨率与输入数字量的位数有确定的关系,可以表示成FS/2n。
FS表示满量程输入值,n为二进制位数。对于5V的满量程,采
用8位的DAC时,分辨率为5V/256=19.5mV;当采用12位的DAC
时,分辨率则为5V/4096=1.22mV。显然,位数越多分辨率就
越高。
2、线性度
线性度(也称非线性误差)是实际转换特性曲线与理想直线特
性之间的最大偏差。常以相对于满量程的百分数表示。如±1
%是指实际输出值与理论值之差在满刻度的±1%以内。
3、绝对精度和相对精度
v绝对精度(简称精度)是指在整个刻度范围内,任一输入数码所对应的模拟量实际输出值与理论值之间的最大误差。绝对精度是由DAC的增益误差(当输入数码为全1时,实际输出值与理想输出值之差)、零点误差(数码输入为全0时,DAC的非零输出值)、非线性误差和噪声等引起的。绝对精度(即最大误差)应小于1个LSB。
v相对精度与绝对精度表示同一含义,用最大误差相对于满刻度的百分比表示。
4、建立时间
v建立时间是完成一次数字量和模拟量的转换所用的时间。
电流输出型DAC的建立时间短。电压输出型DAC的建立时间主要决定于运算放大器的响应时间。根据建立时间的长短,可以将DAC分成超高速(<1μS)、高速(10~1μS)、中速(100~10μS)、低速(≥100μS)几档。
应当注意,精度和分辨率具有一定的联系,但概念不同。DAC的位数多时,分辨率会提高,对应于影响精度的量化误差会减小。但其它误差(如温度漂移、线性不良等)的影响仍会使DAC的精度变差。
DAC0832:
这里使用的是:直通工作方式
当DAC0832芯片的片选信号、写信号、及传送控制信号的引脚全部接地,允许输入锁存信号ILE引脚接+5V时,DAC0832芯片就处于直通工作方式,数字量一旦输入,就直接进入DAC寄存器,进行D/A转换。
应用:
时序图:
code:
#include <reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit cs=P3^1;
sbit wr=P3^4;
//************************************************
//延时函数,在12MHz的晶振频率下
//大约50us的延时
//************************************************
void delay_50us(uint t)
{
uchar j;
for(;t>0;t--)
for(j=19;j>0;j--);
}
void main()
{
uchar a;
P1=0x00;//关掉点阵
//时序图
cs=0;
wr=0;
while(1)
{
P0=a;
delay_50us(100);
a++; //00000000——11111111——00000000(高位自动丢失即可)
}
}
A/D转换器:
Vin:模拟量输入
START:开启标志。启动信号
EOC:转换完成中断信号
OE:输出使能
VREF:参考电压5v
计算:x/2^8 = v/v0 解得x ( v测得电压 v0标准电压一般是5v )
技术指标:
ADC0804:
AGND:模拟地
DGND:数字地
INTR:中断
GUNAGMING:光敏电阻
应用:
#include<reg52.h>
#define uchar unsigned char
#define uint unsigned int
sbit rs=P2^4;
sbit rw=P2^5;
sbit e=P2^6;
//ADC
sbit adcs=P3^5;
sbit adrd=P3^0;
sbit adwr=P3^3;
sbit P23=P2^3;
//基于数码管
uchar table1[]=" www.tlxmcu.com ";
uchar table3[]="0123456789";
void delay_50us(uint t)
{
uchar j;
for(;t>0;t--)
for(j=19;j>0;j--);
}
void write_com(uchar com)
{
e=0;
rs=0;
rw=0;
P0=com;
delay_50us(10);
e=1;
delay_50us(20);
e=0;
}
void write_data(uchar dat)
{
e=0;
rs=1;
rw=0;
P0=dat;
delay_50us(10);
e=1;
delay_50us(20);
e=0;
}
void init(void)
{
delay_50us(300);
write_com(0x38);
delay_50us(100);
write_com(0x38);
delay_50us(100);
write_com(0x38);
write_com(0x38);
write_com(0x08);
write_com(0x01);
write_com(0x06);
write_com(0x0c);
}
void main()
{
uchar value;
uchar k,l,m,n;
uchar i;
P23=1;
P1=0x00;
P23=0;
P1=0xff;
while(1)
{
adcs=0;
adwr=0;
delay_50us(2);
adwr=1;
adcs=1;
delay_50us(10);
//数据放入储存器中了
adcs=0;
adrd=0;
delay_50us(1);
value=P1; //178
adrd=1;
adcs=1;
//读数据
k=value/100; //1
l=value%100; //78
m=l/10; //7
n=l%10; //8
table1[2]=table3[n];
table1[1]=table3[m];
table1[0]=table3[k];
//拆数据并存入数组
init();
write_com(0x80);//第一行
for(i=0;i<3;i++)
{
write_data(table1[i]);
delay_50us(20);
}
//把table1数组显示出来,init()不需要再改动了,驱动已经写好
}
}