一、DA转换器的分类
权电阻网络D/A转换器
一个多位二进制数中每一位的1所代表的数值大小称为这一位的权。
对于N位的权电阻网络D/A转换器,当反馈电阻为Rf=R/2时,输出电压的计算公式为:
V 0 = − V R E F 2 n ( d n − 1 2 n − 1 + d n − 2 2 n − 2 + . . . + d 1 2 1 + d 0 2 0 ) = − − V R E F 2 n D n V_{0}=-\frac{V_{REF}}{2^n}(d_{n-1}2^{n-1}+d_{n-2}2^{n-2}+...+d_{1}2^{1}+d_{0}2^{0})=--\frac{V_{REF}}{2^n}D_{n} V0=−2nVREF(dn−12n−1+dn−22n−2+...+d121+d020)=−−2nVREFDn
其中,V0为输出电压,VREF为参考电压,d为模拟量每位的值,2n为位权。
权电阻网络D/A转换器的优点:简单。
权电阻网络D/A转换器的缺点:电阻值相差大,难以保证精度,且不宜于集成在IC内部。
倒T形电阻网络D/A转换器
倒T形电阻网络D/A转换器较为常用,ADC0832就是采用了倒T形电阻网络。
倒T形电阻网络D/A转换器的优点:有较高的转换速度。
倒T形电阻网络D/A转换器的缺点:转换误差较大,转换精度较低。
具有双极性输出的D/A转换器
通过偏移电流可以获得双极性输出的D/A转换器。
二、D/A转换器主要参数指标
1.分辨率
分辨率为D/A转换器模拟输出电压可能被分离的等级数。
n位的D/A转换器分辨率为:
分 辨 率 = 1 2 n − 1 分辨率=\frac{1}{2^{n}-1} 分辨率=2n−11
2.误差
与A/D转换器类似,分为非线性误差,绝对精度等。
3.建立时间
指输入数字量变化时,输出电压变化到相应稳定电压值所需要时间。
4.转换速率
大信号工作状态下模拟电压的变化率。
5.温度系数
输入不变时,输出模拟电压与温度的变化量。
三、DAC0832
概况
DAC0832是采用T型解码网络的8位D/A转换器,转换时间为1μs,工作电压为+5V~+15V,共有20个引脚。
1.引脚详情
引脚 | 名称 | 解释 |
---|---|---|
1 | C S ‾ \overline{CS} CS | 片选信号输入端,低电平有效 |
2 | W R 1 ‾ \overline{WR1} WR1 | 输入寄存器的写选通输入端,负脉冲有效 |
3 | AGND | 模拟地 |
4-7 | DI3-DI0 | 数据输入端 |
8 | VREF | 基准电压输入端 |
9 | Rfb | 反馈电阻端 |
10 | DGND | 数字地 |
11 | IOUT1 | 电流输出端,,当输入全为1时Iout1最大 |
12 | IOUT2 | 电流输出端,与IOUT1端电流和为常数 |
13-16 | DI7-DI14 | 数据输入端 |
17 | X F E R ‾ \overline{XFER} XFER | 数据传输控制信号输入端,低电平有效 |
18 | W R 2 ‾ \overline{WR2} WR2 | DAC寄存器的写选通输入端,负脉冲有效 |
19 | ILE | 数据锁存允许信号输入端,高电平有效 |
20 | Vcc | 电源电压端口 |
2.时序图
3.例程:D/A转换制作呼吸灯
#include <reg52.h>
typedef unsigned int u16;
typedef unsigned char u8;sbit dula=P2^6; //申明U1锁存器的锁存端
sbit wela=P2^7; //申明U2锁存器的锁存端
sbit dawr=P3^6; //定义DA的WR端口
sbit dacs=P3^2; //定义DA的CS端口
sbit beep=P2^3; //定义蜂鸣器端口u8 val = 0,flag = 0;//val为模拟信号值,flag控制灯的呼吸void DA_Init(); //DA初始化函数
void DA_led(); //DA实现呼吸灯
void delay(u16);//延时函数void main()
{DA_Init();while(1){DA_led();}
}
void DA_Init() //DA初始化函数
{dula=0; wela=0; //打开两个锁存器dacs=0; //打开片选CSdawr=0; //低电平写信号P0=0x00; //初始化使模拟信号值最低/*由于是连续读写,所以不需要把CS和WR信号拉高,只需改变数字位*/}
void DA_led() //DA实现呼吸灯
{if(flag==0) //flag为0,小灯变亮{val+=5; //模拟电压每次加5/255P0=val; //通过P0口给DA数据口赋值if(val==255)//如果模拟电压达到最大值{flag=1; //由最亮转向最暗beep=0; delay(100);beep=1; //蜂鸣器响一次}delay(50); //小灯在最亮时亮50ms}else //flag为1,小灯变灭{val-=5; //模拟电压每次减小5/255P0=val; //通过P0口给DA数据口赋值if(val==0) //如果模拟电压达到最小值{flag=0; //flag改变,小灯重复beep=0; delay(100);beep=1; //蜂鸣器响一次}delay(50); //小灯在最暗时灭50ms}
}
void delay(u16 ms) //延时函数
{u16 i,j;for(i=ms;i>0;--)for(j=110;j>0;j--);
}
三、PWM
含义
- PWM一种以数字方式控制模拟电路的方式。
- 占空比是指在一个脉冲循环内,通电时间相对于总时间所占的比例。
例程:定时器制作呼吸灯
#include "reg52.h"
typedef unsigned int u16;
typedef unsigned char u8;sbit PWM=P2^1; // P2^1口连接单片机的SCL,也就是时钟线
bit DIR = 1000; //bit是位变量,类似bool,不过比bool省内存 此处DIR用来控制LED呼吸 //--定义一个全局变量--//
u16 value,time,count; //value 有效值 time时间 count 用来计时使有效值变化 void Timer1_Init(); //定时器1初始化函数
void breatheLED(); //该函数输出呼吸信号, 参数是每次呼吸的时间的一半 void main()
{ Timer1_Init(); //定时器1初始化while(1){breatheLED(); }
}void Timer1_Init() //定时器1初始化函数
{TMOD|=0X10; //选择为定时器1模式,工作方式1,仅用TR1打开启动TH1 = 0xff; TL1 = 0xff; //计时1us ET1=1; //打开定时器1中断EA=1; //打开总中断TR1=1; //打开定时器
}void breatheLED() //该函数输出呼吸信号
{if(count>100) //每100us使得value变化一次 { count=0; //100us结束,count归零 if(DIR==1) //如果现在是变亮 {value++; //占空比/有效值增加,灯变亮 } if(DIR==0) //如果现在是变暗 {value--; //占空比/有效值变小 } }if(value==1000) //如果有效值/占空比等于一个呼吸周期了 也就是现在亮度最大 {DIR=0; //DIR置0,改为变暗}if(value==0) //如果有效值/占空比等于0了 {DIR=1; //DIR置1,改为变亮 } if(time < value)//PWM,如果在一个1000us周期里,有value的时间,灯亮着的 {PWM=1;}else if(time > 1000) //如果 time大于1000us,进行下一周期 {time = 0; //time归零,下一个周期开始 }else //在1000us里,除了value的时间,灯是灭的 {PWM=0;}}void Time1(void) interrupt 3 //3 为定时器1的中断号
{TH1 = 0xff; //重装计时器 TL1 = 0xff; //1ustime++; //1us,时间增长 count++;
}