基于AT89C51与TCL2543的双通道采集电压表的设计Word文件下载.docx
《基于AT89C51与TCL2543的双通道采集电压表的设计Word文件下载.docx》由会员分享,可在线阅读,更多相关《基于AT89C51与TCL2543的双通道采集电压表的设计Word文件下载.docx(13页珍藏版)》请在冰豆网上搜索。
本文介绍了以AT89C51单片机为核心、以TLC2543为转换芯片采样、以四位一体七段数码管显示的具有一定精度电压测量的数字电压表。
2.硬件设计
该系统主要包括以下几个模块:
时钟模块、复位模块、控制模块、A/D转换模块、以及显示模块,其中时钟模块和复位模块是必不可少的部分呢。
时钟模块选择频率为11.0592mhz的晶振,由于是在proteus仿真,则频率大小通过软件设置来完成。
复位模块包括上电复位和手动复位两种方式,按钮s1就是用来实现手动复位操作的。
控制模块比较简单,主要是以单片机AT89C51为控制核心,但是它要通过软件编写程序再载入单片机中,才能实现处理和控制功能。
A/D转换模块是本系统中最为关键的部分,它要实现将采集到的连续变化的模拟电压量转换成离散的数字量的功能,为此我们选择了TLC2543芯片,它是美国ti公司生产的12位串行模数转换器件,使用开关电容逐次逼近技术完成A/D转换过程。
由于是串行输入结构,可以节省AT89c51的I/O资源,且价格适中,分辨率较高,在仪器仪表中广泛应用。
显示模块采用四位一体7端BCD数码管来动态扫描显示。
AT89C51的P0口作为四位LED数码管动态显示的段码控制,P2.0~P2.3引脚作为四位LED数码管动态显示的位码控制。
3.AT89C51与TLC2543的简介
3.1AT89C51单片机
接口分配电路设计如右图2所示:
图2单片机接口电路
P0口:
P0口为一个8位漏级开路双向I/O口,被定义为高阻输入。
P0能够用于外部程序数据存储器,它可以被定义为数据/地址的第八位。
在这里P0口作为输出和数码管显示的输入端相连,且P0外部被阻值为1KΏ的电阻拉高。
P2口:
这里只用到了P2.0~P2.3四个端口,其中P2.1~P2.3都是作为数码管显示的位选端口。
3..2LC2543的使用方法。
3.2.1 控制字的格式
控制字为从DATAINPUT端串行输入的8位数据,它规定了TLC2543要转换的模拟量通道、转换后的输出数据长度、输出数据的格式。
3.2.2 转换过程
上电后,片选CS必须从高到低,才能开始一次工作周期,此时EOC为高,输入数据寄存器被置为0,输出数据寄存器的内容是随机的。
开始时,CS片选为高,I/OCLOCK、DATAINPUT被禁止,DATAOUT呈高阻状,EOC为高。
4.软件设计
系统程序的内容一般包括:
延时子程序、显示子程序、数据采集子程序、主程序等等。
主程序流程图见下图所示。
从单通道数据采集改为双通道数据采集,可以用中断来控制,也可以通过改写程序,使通道0采集的数据转换显示结束时,通道1所采集的数据通过A/D转换后正好显示,且显示时间均可人为的设定为能够被人眼分辨的频率。
同时进行
同时
双通道数据采集主流程图
5.仿真结果如下图
图1系统硬件电路仿真图(通道0采集的数据)
图2系统硬件电路仿真图(通道1采集的数据)
6数据分析
6.1在上图1当中数码管显示的测量电压值是通道0采集的,数值是2.499V,而虚拟电压表的值是+2.50v;
在上图2当中数码管显示的测量电压值是通道1采集的数值是3.399V,而虚拟电压表的值是+3.40v经过多次测验,可以发现所设计的数字电压表的最大误差是0.001v,二者在同一个数码管上交替出现,满足任务要求。
7.结语
本次对数字电压表的软硬件设计,主要是在proteus中硬件仿真,将keil软件编译生成的hex程序文件加载到核心芯片中来实现的。
所设计的数字电压表可以测量0~5v的电压值,经过反复的测试和比较,得知所测电压值的最大误差是0.001v。
它具有结构简单、精度高、实用性强、操作简单的优点
参考文献
[1]刘敏娜,潘宏侠,王乔.基于51单片机的数字电压表仿真设计[j].山西电子技术,2011年第2期.
[2]郑锋.51单片机典型应用开发范例大全[m].北京:
中国铁道出版社,2011
C语言源程序如下
#include<
reg51.h>
intrins.h>
#defineucharunsignedchar
#defineuintunsignedint
sbitCLK=P1^0;
sbitSDI=P1^1;
sbitSDO=P1^2;
sbit_cs=P1^3;
sbitEOC=P1^4;
sbitKEY=P3^2;
uchara1,b1,c1,d1;
floatsum,sum1;
double
sum_final1;
sum_final;
ucharduan[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
ucharwei[]={0xf7,0xfb,0xfd,0xfe};
voiddelay(unsignedcharb)
{
unsignedchara;
for(;
b>
0;
b--)
for(a=22;
a>
a--);
}
voiddisplay(uchara,ucharb,ucharc,uchard)
P0=duan[a]|0x80;
P2=wei[0];
delay(10);
P2=0xff;
P0=duan[b];
P2=wei[1];
P0=duan[c];
P2=wei[2];
P0=duan[d];
P2=wei[3];
uintread1(ucharport)
uchari,al=0,ah=0;
unsignedlongad;
CLK=0;
_cs=0;
port<
<
=4;
for(i=0;
i<
4;
i++)
SDI=port&
0x80;
CLK=1;
=1;
SDI=0;
8;
_cs=1;
delay(5);
ah<
if(SDO)ah|=0x01;
al<
if(SDO)al|=0x01;
ad=(uint)ah;
ad<
=8;
ad|=al;
return(ad);
uintread2(ucharport)
uchari,bl=0,bh=0;
bh<
if(SDO)bh|=0x01;
bl<
if(SDO)bl|=0x01;
ad=(uint)bh;
ad|=bl;
voidmain()
ucharj;
sum=0;
sum1=0;
sum_final=0;
sum_final1=0;
while
(1)
if(KEY==0)
{
for(j=0;
j<
128;
j++)
{
sum1+=read2
(1);
display(a1,b1,c1,d1);
}
sum=sum1/128;
sum_final1=(sum/4095)*5;
sum_final=sum_final1*1000;
a1=(int)sum_final/1000;
b1=(int)sum_final%1000/100;
c1=(int)sum_final%1000%100/10;
d1=(int)sum_final%10;
display(a1,b1,c1,d1);
}
else
{
for(j=0;
sum1+=read1
(1);
}