#include "reg51.h"
#include "intrins.h"
#define uchar unsigned char
#define uint unsigned int
sbit SDO = P1^0; // 芯片的三个关键的输入数据端口,主要是靠外电压来提供的
sbit CS = P1^1;
sbit SCLK = P1^2;
sbit wei0 = P2^0;
sbit wei1 = P2^1;
sbit wei2 = P2^2;
sbit wei3 = P2^3;
// 数据是从0-9显示
uchar seg[] = {0x3F, 0x06, 0x5B, 0x4F, 0x66, 0x6D, 0x7D, 0x07, 0x7F, 0x6F};
void delay(uint N){ // 延时
uint i;
for (i = 0; i < N; i++){
_nop_();
}
}
uchar convert(){
uchar i, dat = 0;
CS = 0; // 初状态,CS拉低,看SPI总线的定义
for (i = 0; i < 8; i++){
dat <<= 1;
if (SDO == 1) dat |= 0x01; // 有数据,最低为置1
/* SCLK 完成一次1到0的脉冲,即可实现数据的发送 */
SCLK = 1;
delay(4);
SCLK = 0;
delay(4);
}
CS = 1; // 完成数据转换,CS重新置高
return dat;
}
void main(){
uint value;
while(1){
/*
数据的接收位在这个,一字节的接收和转换,将5V模拟量转为255的离散数字量
*/
value = convert() * 19.607; // 5000 / 255
wei0 = 0;
P0 = seg[value/1000] + 0x80; // 这个是为了把小数点显示出来
delay(500);
wei0 = 1;
wei1 = 0;
P0 = seg[value%1000/100];
delay(500);
wei1 = 1;
wei2 = 0;
P0 = seg[value%100/10];
delay(500);
wei2 = 1;
wei3 = 0;
P0 = seg[value%10];
delay(500);
wei3 = 1;
}
}
在单片机测控系统中,非电量如温度、压力、流量、速度等,经传感器先转换成连续变化的模拟电信号(电压或电流),然后再将模拟电信号转换成数字量后才能在单片机中进行处理。实现模拟量转换成数字量的器件称为ADC(A/D转换器)。
单片机处理完毕的数字量,有时根据控制要求需要转换为模拟信号输出。数字量转换成模拟量的器件称为DAC(D/A转换器)。本章从应用的角度,介绍典型的ADC、DAC芯片与AT89S51单片机的硬件接口设计以及接口驱动程序设计。
单片机只能输出数字量,但是对于某些控制场合,常常需要输出模拟量,例如直流电动机的转速控制。下面介绍单片机如何扩展DAC。
目前集成化的DAC芯片种类繁多,设计者只需要合理选用芯片,了解它们的性能、引脚外特性以及与单片机的接口设计方法即可。由于现在部分单片机的芯片中集成了DAC,位数一般在10位左右,且转换速度也很快,所以单片的DAC开始向高的位数和高转换速度上转变。而低端的并行8位DAC,开始面临被淘汰的危险,但是在实验室或涉及某些工业控制方面的应用,低端8位DAC以其优异的性价比还是具有较大的应用空间。
1.D/A转换器简介
购买和使用D/A转换器时,要注意有关D/A转换器选择的几个问题。
(1)D/A转换器的输出形式
D/A转换器有两种输出形式:电压输出和电流输出。电流输出的D/A转换器在输出端加一个运算放大器构成的I-V转换电路,即可转换为电压输出。
(2)D/A转换器与单片机的接口形式
单片机与D/A转换器的连接,早期多采用8位的并行传输的接口,现在除了并行接口外,带有串行口的D/A转换器品种也不断增多,目前较为流行多采用SPI串行接口。在选择单片D/A转换器时,要根据系统结构考虑单片机与D/A转换器的接口形式。
2.主要技术指标
D/A转换器的指标很多,设计者最关心的几个指标如下。
(1)分辨率
分辨率指单片机输入给D/A转换器的单位数字量的变化,所引起的模拟量输出的变化,通常定义为输出满刻度值与2n之比(n为D/A转换器的二进制位数),习惯上用输入数字量的位数表示。显然,二进制位数越多,分辨率越高,即D/A转换器输出对输入数字量变化的敏感程度越高。例如,8位的D/A转换器,若满量程输出为10V,根据分辨率定义,则分辨率为10V/2n,分辨率为10V/256 = 39.1mV,即输入的二进制数最低位数字量的变化可引起输出的模拟电压变化39.1mV,该值占满量程的0.391%,常用符号1LSB表示。
同理:
10位D/A转换 1 LSB = 9.77mV = 0.1%满量程
12位D/A转换 1 LSB = 2.44mV = 0.024%满量程
16位D/A转换 1 LSB = 0.076mV = 0.00076%满量程
使用时,应根据对D/A转换器分辨率的需要选定D/A转换器的位数。
(2)建立时间
建立时间是描述D/A转换器转换速度的参数,表明转换时间长短。其值为从输入数字量到输出达到终值误差± (1/2)LSB(最低有效位)时所需的时间。电流输出的转换时间较短,而电压输出的转换器,由于要加上完成I-V转换的时间,因此建立时间要长一些。快速D/A转换器的建立时间可控制在1us以下。
(3)转换精度
理想情况下,转换精度与分辨率基本一致,位数越多精度越高。但由于电源电压、基准电压、电阻、制造工艺等各种因素存在误差。严格地讲,转换精度与分辨率并不完全一致。两个相同位数的不同的DAC,只要位数相同,分辨率则相同,但转换精度会有所不同。例如,某种型号的8位DAC精度为±0.19%,而另一种型号的8位DAC精度为±0.05%
串行A/D转换器与单片机连接具有占用I/O口线少的优点,使用较多,大有取代并行A/D转换器的趋势。下面介绍单片机扩展串行8位 AD转换器TLC549的应用设计。
TLC549是美国TI公司推出的价廉、高性能的带有SPI接口的8位 AD转换器,其转换速度小于17µs,最大转换速率为 40kHz,内部系统时钟的典型值为4MHz,电源为3~6V。能方便与各种单片机通过SPI串行接口连接。
(1)串行数据中高位A7先输出,最后输出低位A0;
(2)在每一次I/O COLCK高电平期间DATA OUT 线上数据产生有效输出,每出现一次I/O COLCK,DATA OUT线就输出1位数据。一个周期出现8 次I/O COLCK 信号并对应8位数据输出;
(3)在CS*变为低电平后,最高有效位(A7)自动置于DATA OUT 总线 。其余7位(A6~A0)在前7 个I/O CLOCK 下降沿由时钟同步输出。B7~B0 以同样方式跟在其后;
(4)tsu在片选信号CS*变低后,I/O COLCK 开始正跳变的最小时间间隔1.4μs;
(5)ten是从CS*变低到DATA OUT 线上输出数据最小时间(1.2μs);
(6)只要I/O COLCK 变高就可读取DATA OUT 线上数据;
(7)只有在CS*端为低时,TLC549 才工作;
(8)TLC549的A/D转换电路没有启动控制端,只要读取前一次数据后马上就可以开始新的A/D 转换。转换完成后就进入保持状态。TLC549 每次转换所需时间是17μs, 它开始于 变为低电平后I/OCLOCK 的第8个下降沿,没有转换完成标志信号。
当CS变为低电平后,TLC549芯片被选中, 同时前次转换结果的最高有效位MSB (A7)自 DATA OUT 端输出,接着要求从I/O CLOCK端输入8个外部时钟信号,前7个 I/O CLOCK信号的作用,是配合TLC549 输出前次转换结果的的A6~A0 位,并为本次转换做准备:在第4个 I/O CLOCK 信号由高至低的跳变之后,片内采样/保持电路对输入模拟量采样开始,第8个 I/O CLOCK 信号的下降沿使片内采样/保持电路进入保持状态并启动 A/D开始转换。转换时间为 36 个时钟周期,最大为 17µs。直到 A/D转换完成前的这段时间内,TLC549 的控制逻辑要求:或者CS保持高电平,或者 I/O CLOCK 时钟端保持36个系统时钟周期低电平。
由此可见,在TLC549的 I/O CLOCK 端输入8个外部时钟信号期间需要完成以下工作:读入前次A/D转换结果;对本次转换的输入模拟信号采样并保持;启动本次 A/D转换开始。