串行ADDAWord文件下载.docx
《串行ADDAWord文件下载.docx》由会员分享,可在线阅读,更多相关《串行ADDAWord文件下载.docx(22页珍藏版)》请在冰点文库上搜索。
(c)工作原理:
图2TLC5620引脚图
TLC5620工作时序如图3所示。
当LODA和LDAC均为高时,在每一个CLK时钟的下降沿数据被所存到DATA端,当所有的数据位都被锁入DATA端后,拉低LOAD,串行数据从串行输入寄存器移入被选中的DAC通道,拉低LDAC,更新输出端电压,之后置LDAC为高,可以保持更新后的电压值。
这样,在两个8时钟周期内可以完成一次DA转换。
图3TLC5620工作时序图
(2)TLC0838
TLC0838是美国德州仪器公司推出的8路8位逐次逼近型模/数转换器,具有串行输入输出的方式,采样频率为100KHZ,与外部通信采用SPI总线接口,可用地址逻辑多路器选通8输入通道,输入和输出与TTL、CMOS电平兼容。
(b)器件引脚:
TLC0838引脚图如图4所示。
CH0—CH7:
8个模拟信号输入。
COM:
模拟信号共模输入端。
DGTLGND:
数字信号地。
ANLGGND:
模拟信号地。
REF:
基准电压。
/SE:
数据输出方式选择。
DO:
数据输出。
SARS:
状态转换输出。
时钟信号输入。
DI:
数据输入。
/CS:
片选。
NC:
空角。
VCC:
电源(+5V)
(c)工作原理:
图4
TLC0838采用取样—数据—比较器的结构,用逐次逼近流程转换差分模拟输入信号。
TLC0838的工作时序如图5所示。
图5TLC0838工作时序图
置CS为低,接着从处理器接受时钟,在每个时钟的上沿,脚DI的数据移入多路器地址移位寄存器。
第一位为逻辑高,表示起始位,其后的2、3、4、5、位是配置位。
配置位输完后,转换器开始工作,SARS状态输出变高表示转换过程正在进行,脚DI在转换过程中与移位寄存器间是关断的。
为使选定的通道稳定,在通道配置位输完后,要隔一个时钟周期转换的数据才在时钟的下沿从脚DO输出。
TLC0838的输出数据可从高位开始,也可从低位开始。
在/SE为高时,数据线从最高到最低位输出,并将最低为保持在数据线上,在/SE为低时,数据从低位开始重新输出一遍。
一次模数转换需13个时钟周期,如果时钟频率为250KHZ,那么一次转换时间为32.5us。
脚DI和DO可以连在一起,通过一根线连到处理器的一个双向I/O口进行控制,因为DI和DO在同一时间肯定有一个为高阻。
(3)MC1403:
MC1403可提供准确的2.5V的基准电源,提供给TLC5620作为其模数转换的参考电压。
MC1403引脚图如图6。
引脚1:
输入电压。
引脚2:
输出2.5V电压。
引脚3:
接地。
引脚4—引脚8:
空脚。
图6
3.接口说明
串行ADDA的PCB图如图7所示,实物图如图8所示。
图7
图8
实物图中单片机模块上的外围接口说明如下:
8个模拟信号输入端。
如果只有一路模拟信号,选其中任一端口即可。
GND:
CS:
TLC0838的片选信号。
实际使用时DI和DO用导线相连。
CLK(TLC0838):
TLC0838的时钟信号输入端。
DACA—DACD:
此四路输出的模拟信号是四路参考电压(REFA—REFD)是一一对应的,此模块中四路参考电压相同,所以四路输出的模拟信号也相同,选其中任一端口即可。
CLK(TLC5620):
TLC5620的时钟信号输入端。
LOAD:
DAC转换信号,接低电平。
4.典型程序:
利用串行ADDA和单片机设计的数控电流源的程序。
#include<
reg51.h>
intrins.h>
#defineucharunsignedchar
//数据口定义
#definelcd1602_busP0
/******************tlc549port*********************/
sbitcs_0838=P1^3;
sbitsda_0838=P1^0;
sbitscl_0838=P1^1;
/*******************tlc5620port***********************/
sbitload_5620=P1^5;
sbitclk_5620=P1^6;
sbitdata_5620=P1^7;
/***************lcd1602port******************************/
//引脚定义
sbitrs_1602=P2^5;
sbitrw_1602=P2^6;
sbite_1602=P2^7;
ucharset[3];
//setting
ucharmea[4];
//measure
ucharj;
bitb;
uchardata5620;
unsignedcharbdataadc_0838;
//bdata//bitdataarea
sbitadc_0838low=adc_0838^0;
//最低位
ucharbdatau;
sbitus=u^7;
ucharcodetable[10]=
{0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39};
/**************adc_549convert*******************/
unsignedcharadc_0838convert()
{
uchari;
u=0x80;
scl_0838=0;
sda_0838=1;
cs_0838=0;
_nop_();
scl_0838=1;
for(i=0;
i<
4;
i++)
{
sda_0838=us;
u=u<
<
1;
}
adc_0838=0;
8;
adc_0838=adc_0838<
adc_0838low=sda_0838;
return(adc_0838);
}
voiddac_5620(unsignedchardataa,unsignedchardatab,
unsignedchardatac,unsignedchardatad)
{
unsignedchari;
/****************dataa************/
load_5620=1;
clk_5620=1;
data_5620=0;
clk_5620=0;
if(dataa&
0x80)data_5620=1;
elsedata_5620=0;
dataa=dataa<
load_5620=0;
/************datab*************/
data_5620=1;
if(datab&
datab=datab<
/************datac*******************/
data_5620=0;
if(datac&
datac=datac<
/***************datad***************/
if(datad&
datad=datad<
/*********延时子程序**********/
voiddelay_1602(uchardy)
while(--dy);
}
/***********忙判断标志,返回一个位BF********************/
bitlcd1602_busy(void)
unsignedcharbusy_flag;
rs_1602=0;
rw_1602=1;
e_1602=1;
lcd1602_bus=0xff;
busy_flag=lcd1602_bus;
//e在高电平时读
e_1602=0;
return(bit)(busy_flag&
0x80);
//BF=1;
BUSY返回一个位
/********写命令,有两个参数,一个是要写的命令控制字,
第二个是用来控制是否进行忙标志的判断。
busyflag=1;
判断:
为0
***************/
voidlcd1602_wrcmd(unsignedcharlcdcmd)
while(lcd1602_busy());
//等待空闲
lcd1602_bus=lcdcmd;
rw_1602=0;
//产生一个下沿
/***************向液晶写数据******************/
voidlcd1602_wrdata(unsignedcharlcddata)
while(lcd1602_busy());
lcd1602_bus=lcddata;
//在下沿的时候写数据
rs_1602=1;
//lcd_bus=0xff;
/************液晶的清屏************/
voidlcd1602_clear(void)
lcd1602_wrcmd(0x01);
//液晶清屏控制字并延时>
40us
delay_1602(100);
/***********1602液晶的初始化***************/
voidlcd1602_init(void)
lcd1602_wrcmd(0x38);
//功能设置-----8位数据接口,两行显示,5*7点阵字符显示
lcd1602_wrcmd(0x0c);
//显示开关控制----显示开关开,光标开关关,闪烁开关关
lcd1602_wrcmd(0x06);
//输入方式设置,AC自增1,S=0;
//清屏
/************键盘扫描*************/
ucharkeyscan(void)
ucharscancode,tmpcode;
P3=0xf0;
if((P3&
0xf0)!
=0xf0)
delay_1602(125);
if((P3&
{
scancode=0xfe;
while((scancode&
0x10)!
=0)
{
P3=scancode;
if((P3&
{
tmpcode=(P3&
0xf0)|0x0f;
return((~scancode)+(~tmpcode));
}
elsescancode=(scancode<
1)|0x01;
}
}
return(0);
voidfen(unsignedinthex,uchara[4])
a[0]=table[hex/1000];
hex=hex%1000;
a[1]=table[hex/100];
hex=hex%100;
a[2]=table[hex/10];
hex=hex%10;
a[3]=table[hex];
voidjia(n)
set[j]=table[n];
lcd1602_wrcmd(0x8a-j);
=j;
lcd1602_wrdata(set[i]);
j++;
data5620=data5620*10+n;
main()
ucharkey,i;
unsignedcharstr0[]="
setting:
*10mA"
;
unsignedcharstr1[]="
measure:
mA"
uchardata549=0;
unsignedintcov549=0;
b=0;
j=0;
data5620=0;
delay_1602
(2);
lcd1602_init();
lcd1602_wrcmd(0x80);
16;
i++)
lcd1602_wrdata(str0[i]);
while
(1)
lcd1602_wrcmd(0x8a);
key=0;
while(key==0)
key=keyscan();
while(P3!
P3=0xf0;
if(key==0x18)
dac_5620(data5620,data5620,data5620,data5620);
b=1;
data549=adc_0838convert();
cov549=data549*19.6;
fen(cov549,mea);
lcd1602_wrcmd(0xc0);
14;
lcd1602_wrdata(str1[i]);
lcd1602_wrcmd(0xc8);
lcd1602_wrdata(mea[i]);
elseif(key==0x12)
if(j>
0)
j--;
data5620=(data5620-(set[j]-0x30))/10;
lcd1602_wrdata(0);
j;
}
else
if(j<
3)
if(b==1)
set[0]=0;
set[1]=0;
set[2]=0;
data5620=0;
j=0;
lcd1602_wrcmd(0xc0);
for(i=0;
lcd1602_wrcmd(0x87);
3;
b=0;
switch(key)
case0x14:
jia(0);
break;
case0x28:
jia
(1);
case0x24:
jia
(2);
case0x22:
jia(3);
case0x48:
jia(4);
case0x44:
jia(5);
case0x42:
jia(6);
case0x88:
jia(7);
case0x84:
jia(8);
case0x82:
jia(9);
default:
break;