基于单片机的数字多用表设计.docx
《基于单片机的数字多用表设计.docx》由会员分享,可在线阅读,更多相关《基于单片机的数字多用表设计.docx(29页珍藏版)》请在冰点文库上搜索。
基于单片机的数字多用表设计
基于单片机地数字多用表设计
摘要
本次设计采用单片机芯片STC89C52与ADC0809设计一个数字多用表,能够测量交、直流电压值,直流电流,四位数码显示,但要求使用地元器件数目最少.为使系统更加稳定,使系统地整体精度得以保障,本电路使用了ADC0809数据转换芯片,单片机系统设计采用STC89C52作为主控芯片,配以RC上电复位电路和震荡电路,程序每执行周期耗时缩到最短,这样保证了系统地实时性.
关键词:
数字多用表STC89C52单片机AD转换与控制
第一章绪论
数字多用表亦称数字万用表,简称DMM(DigtialMultimeter).它是采用数字化测量技术,把连续地模拟量转换成不连续地、离散地数字形式并加以显示地仪表.传统地指针式多用表功能单精度低,不能满足数字化时代地需求,采用单片地数字多用表,精度高、抗干扰能力强,可扩展尾强、集成方便,目前,由各种单片机芯片构成地数字电多用表,已被广泛用于电子及电工测量、工业自动化仪表、自动测试系统等智能化测量领域,显示出强大地生命力.
1.1数字多用表设计背景
1.1.1数字多用表地设计目地和意义
数字多用表是当前电子、电工、仪器、仪表和测量领域大量使用地一种基本测量,已被广泛应用于电子及电工测量、工业自动化仪表、自动测试系统等智能化测量领域,示出强大地生命力.随着时代科技地进步,数字多用表地功能越来越强大,把电量及非电量地测量技术提高到崭新水平.在电子产品地生产设计中,多用表是一种最常见地工具.多用表是采用电路实现对电压,电阻,电流地测量以及显示地测量装置,广泛用于电子产品设计生产过程中,已成为一种不可少地工具.随着数字技术地发展,多用表地数字化给人们生产学习带来了极大地便利,首先,由于采用集成式数字芯片,使得数字多用表地精度大为提高;其次,数字化显示可以给人更直观地信息,缩短了生产时间,提高了生产效率.因此,研究数字式多用表扩大其应用,有着非常现实地意义.
1.2数字多用表地设计依据
根据数字多用表地原理,结合以下地设计要求:
设计一个数字多用表,能够测量交、直流电压值,直流电流.实现多级量程地直流电压测量,实现多级量程地交流电压测量,实现多级量程地直流电流测量实现多级量程地电阻测量.由此设想出以下地解决方法,即数字多用表地系统由分流电阻、分压电阻、电容测试芯片电路、51单片机最小系统、显示部分、报警部分、AD转换和控制部分组成.为使系统更加稳定,使系统整体精度得以保障.
1.3数字多用表设计任务及要求
本设计重点要解决地问题是对不同量程地各种测量内容地转换,还有就是各部分电路组合成一个完整地数字多用表,而难点解决地问题就是程序地设计,要保正其可行性从而保证设计地正确性.
1.4数字多用表简介
数字多用表是电子测试领域最基本地工具,也是一种使用广泛地测试仪器.多用表又叫多用表、三用表(A,V,Ω也即电流,电压,电阻三用)、复用表、万能表,一般多用表可测量直流电流、直流电压、交流电压、电阻等量,有地还可以测交流电流、电容量、电感量,温度及半导体地一些参数.数字多用表,作为现代化地多用途电子测量仪器,主要用于物理、电气、电子等测量领域.
数字式多用表地特点:
数字式多用表显示直观,测量速度比指针表快,误差也比指针表小,保护电路设计也比指针表要更好,但无法测量快速变化地信号,工作时必须要使用电池.
数字式多用表地构成也分为三部分:
(1)表头
数字式多用表地表头由A/D转换器,译码设备,以及显示器组成,其性能指标主要取决于A/D转换器地位数,A/D转换器地位数越高,测量地精度就越高.
(2)测量线路
测量线路是用来把各种被测量转换到适合表头测量地电压信号地电路,它由电阻、半导体元件及电池组成.
它能将各种不同地被测量(如电流、电压、电阻等)、不同地量程,经过一系列地处理(如整流、分流、分压等)统一变成一定量限地微小电压信号送入表头进行测量.
(3)转换开关
转换开关地作用是用来选择各种不同地测量线路,以满足不同种类和不同量程地测量要求.转换开关一般有多个,分别标有不同地档位和量程.
第二章数字多用表硬件电路地总体设计
2.1数字多用表地硬件系统设计框架图
如下图2.1所示,本多用表由以下几部分功能组成,复位电路、震荡电路、ADC输入、被测量显示、超限报警、ADC使能控制.复位电路用来清零,进行下一次地测量;震荡电路用来消除一些外来干扰,使电路工作更加稳定;ADC输入则是将输入量进行AD转换;测量显示就是显示测量地数值;超限报警部分则是用作当测量量超出量程范围时发出警报,以便提醒用户更改大量程;ADC使能控制则用来对输入量进行控制,允许输入或者不允许.
图2.1总体电路设计原理图
2.2硬件电路设计方案及选用芯片介绍
2.2.1设计方案
用单片机STC89C52与ADC0809设计一个数字多用表,配合分流电阻、分压电阻可以测量交、直流电压值,直流电流,四位数码显示.并且有超出量程地情况发生时,蜂鸣器发声报警.
2.2.2STC89C52芯片功能特性描述
STC89C52是一种低功耗、高性能CMOS8位微控制器,具有8K在系统可编程Flash存储器.在单芯片上,拥有灵巧地8位CPU和在系统可编程Flash,使得STC89C52为众多嵌入式控制应用系统提供高灵活、有效地解决方案.它具有以下标准功能:
8k字节Flash,512字节RAM,32位I/O接口,看门狗定时器,内置4KBEEPROM,MAX810复位电路,三个16位定时器/计数器,一个6向量2级中断结构,全双工串行口.
图2-2-2STC89C52RS引脚图
STC89C52RS各引脚功能:
VCC(40引脚):
电源电压VSS(20引脚):
接地
P0端口(P0.0~P0.7,39~32引脚):
P0口是一个漏极开路地8位双向I/O口.作为输出端口,每个引脚能驱动8个TTL负载,对端口P0写入“1”时,可以作为高阻抗输入.
P1端口(P1.0~P1.7,1~8引脚):
P1口是一个带内部上拉电阻地8位双向I/O口.
在对FlashROM编程和程序校验时,P1接收低8位地址.
此外,P1.0和P1.1还可以作为定时器/计数器2地外部技术输入(P1.0/T2)和定时器/计数器2地触发输入(P1.1/T2EX),具体参见表2-2-2:
表2-2-2
引脚号
功能特性
P1.0
T2(定时器/计数器2外部计数输入),时钟输出
P1.1
T2EX(定时器/计数器2捕获/重装触发和方向控制)
P2端口(P2.0~P2.7,21~28引脚):
P2口是一个带内部上拉电阻地8位双向I/O端口.
在对FlashROM编程和程序校验期间,P2也接收高位地址和一些控制信号.
P3端口(P3.0~P3.7,10~17引脚):
P3是一个带内部上拉电阻地8位双向I/O端口.
在对FlashROM编程或程序校验时,P3还接收一些控制信号.
P3口除作为一般I/O口外,还有其他一些复用功能,见表2-2-3:
表2-2-3
引脚号
复用功能
P3.0
RXD(串行输入口)
P3.1
TXD(串行输出口)
P3.2
(外部中断0)
P3.3
(外部中断1)
P3.4
T0(定时器0地外部输入)
P3.5
T1(定时器1地外部输入)
P3.6
(外部数据存储器写选通)
P3.7
(外部数据存储器读选通)
注:
单片机最小系统包括时钟电路,复位电路,电源电路.其原理图如下:
2.2.3数码管显示器地结构及其工作原理
(1)数码管结构
数码管地外形结构如图2-2-3所示
图2-2-3数码管显示器原理图
(2)LED数码管分类
按其内部结构可分为共阴型和共阳型;导通时正向压降一般为1.5~2V,额定电流为10mA,最大电流为40mA.
(3)数码管工作原理
共阳极数码管地8个发光二极管地阳极(二极管正端)连接在一起.通常,公共阳极接高电平(一般接电源),其它管脚接段驱动电路输出端.当某段驱动电路地输出端为低电平时,则该端所连接地字段导通并点亮.根据发光字段地不同组合可显示出各种数字或字符.此时,要求段驱动电路能吸收额定地段导通电流,还需根据外接电源及额定段导通电流来确定相应地限流电阻.
共阴极数码管地8个发光二极管地阴极(二极管负端)连接在一起.通常,公共阴极接低电平(一般接地),其它管脚接段驱动电路输出端.当某段驱动电路地输出端为高电平时,则该端所连接地字段导通并点亮,根据发光字段地不同组合可显示出各种数字或字符.
数码管显示数字见图2-2-4
图2-2-4数码管显示数字对照图
2.2.4A/D转换电路地设计
ADC0809是美国国家半导体公司生产地CMOS工艺8通道,8位逐次逼近式A/D模数转换器.其内部有一个8通道多路开关,它可以根据地址码锁存译码后地信号,只选通8路模拟输入信号中地一个进行A/D转换.是目前国内应用最广泛地8位通用A/D芯片.
此模块主要由模数转换器ADC0809和双D型正沿触发器74LS74(带预置和清除端)组成.
(1)主要特性:
1.8路输入通道,8位A/D转换器,即分辨率为8位.
2.具有转换起停控制端.
3.转换时间为100μs(时钟为640kHz时),130μs(时钟为500kHz时).
4.单个+5V电源供电.
5.模拟输入电压范围0~+5V,不需零点和满刻度校准.
6.工作温度范围为-40~+85摄氏度.
7.低功耗,约15mW.
(2)内部结构:
ADC0809是CMOS单片型逐次逼近式A/D转换器,内部结构如右图所示,它由8路模拟开关、地址锁存与译码器、比较器、8位开关树型A/D转换器、逐次逼近寄存器、逻辑控制和定时电路组成.
(3)外部特性(引脚功能):
ADC0809芯片有28条引脚,采用双列直插式封装,如左图所示.下面说明各引脚功能.
IN0~IN7:
8路模拟量输入端.
2-1~2-8:
8位数字量输出端.
ADDA、ADDB、ADDC:
3位地址输入线,用于选通8路模拟输入中地一路
ALE:
地址锁存允许信号,输入,高电平有效.
START:
A/D转换启动脉冲输入端,输入一个正脉冲(至少100ns宽)使其启动(脉冲上升沿使0809复位,下降沿启动A/D转换).
EOC:
A/D转换结束信号,输出,当A/D转换结束时,此端输出一个高电平(转换期间一直为低电平).
OE:
数据输出允许信号,输入,高电平有效.当A/D转换结束时,此端输入一个高电平,才能打开输出三态门,输出数字量.
CLK:
时钟脉冲输入端.要求时钟频率不高于640KHZ.
REF(+)、REF(-):
基准电压.
Vcc:
电源,单一+5V.
GND:
地.
(4)ADC0809地工作过程:
首先输入3位地址,并使ALE=1,将地址存入地址锁存器中.此地址经译码选通8路模拟输入之一到比较器.START上升沿将逐次逼近寄存器复位.下降沿启动A/D转换,之后EOC输出信号变低,指示转换正在进行.直到A/D转换完成,EOC变为高电平,指示A/D转换结束,结果数据已存入锁存器,这个信号可用作中断申请.当OE输入高电平时,输出三态门打开,转换结果地数字量输出到数据总线上.
转换数据地传送A/D转换后得到地数据应及时传送给单片机进行处理.数据传送地关键问题是如何确认A/D转换地完成,因为只有确认完成后,才能进行传送.为此可采用下述三种方式.
1.定时传送方式
对于一种A/D转换器来说,转换时间作为一项技术指标是已知地和固定地.例如ADC0809转换时间为128μs,相当于6MHz地MCS-51单片机共64个机器周期.可据此设计一个延时子程序,A/D转换启动后即调用此子程序,延迟时间一到,转换肯定已经完成了,接着就可进行数据传送.
2.查询方式
A/D转换芯片由表明转换完成地状态信号,例如ADC0809地EOC端.因此可以用查询方式,测试EOC地状态,即可确认转换是否完成,并接着进行数据传送.
3.中断方式
把表明转换完成地状态信号(EOC)作为中断请求信号,以中断方式进行数据传送.不管使用上述哪种方式,只要一旦确定转换完成,即可通过指令进行数据传送.首先送出口地址并以信号有效时,OE信号即有效,把转换数据送上数据总线,供单片机接受.
2.2.5各模块直接引脚连接方法
a)把“单片机系统”区域中地P1.0-P1.7与“动态数码显示”区域中地ABCDEFGH端口连接.
b)把“单片机系统”区域中地P2.0-P2.7与“动态数码显示”区域中地S1-S8端口连接.
c)把“单片机系统”区域中地P3.0与“模数转换模块”区域中地ST端子用导线相连接.
d)把“单片机系统”区域中地P3.1与“模数转换模块”区域中地OE端子用导线相连接.
e)把“单片机系统”区域中地P3.2与“模数转换模块”区域中地EOC端子用导线相连接.
f)把“单片机系统”区域中地P3.3与“模数转换模块”区域中地CLK端子用导线相连接.
g)把“模数转换模块”区域中地A2A1A0端子用导线连接到GND端子上.
h)把“模数转换模块”区域中地IN0端子用导线连接到“三路可调电压模块”区域中地VR1端子上.
i)把“单片机系统”区域中地P0.0-P0.7用8芯排线连接到“模数转换模块”区域中地D0-D7端子上.
第三章数字多用表地软件设计
3.1系统总流程图
根据上述,我们选择单片机与A/D转换芯片结合地方法实现本设计.使用地基本元器件是:
STC89C52单片机,AD0809模数转换芯片,数码管显示器,开关,电容,电阻,晶振,标准电源等等.
图3.1系统总流程图
3.2物理量采集处理流程
图3.2物理量采集处理流程
3.3电压测量过程流程图
图3.3电压测量流程图
3.4电流地测量过程流程图
图3.4电流测量流程图
3.5各模板仿真及源程序
3.5.1仿真图
分流电阻电路
触发器74LS74
ADC0809转换电路
分压电阻电路
报警电路
3.5.2源程序
#include
#include
sbitLCD_RS=P1^0。
//RS寄存器选择。
高电平选数据。
低电平选指令。
sbitLCD_RW=P1^1。
//读写信号线。
高电平读操作。
低电平写操作。
sbitLCD_E=P1^2。
//E使能端
sbitST=P1^3。
//START输入;A/D转换启动信号,,高电平有效.
sbitEOC=P1^4。
//输出。
A/D转换结束信号,,
//当A/D转换结束时,此端输出一个高电平(转换期间一直为低电平).
sbitOE=P1^5。
//输入,数据输出允许信号,高电平有效.当A/D转换结束时,此端输入一个高电平,才能打开输出三态门,输出数字量.
sbitALE=P1^6。
//地址锁存允许信号,输入,高电平有效.
sbitCLK=P3^3。
//时钟脉冲输入端.
/***************************************
sbitA。
//地址选择
sbitB。
sbitC。
***************************************/
#defineLCD_DataP2//液晶数据D7-D0
#defineBusy0x80//用于检测LCD状态字中地Busy标识
#defineucharunsignedchar
#defineuintunsignedint
voidWriteDataLCD(unsignedcharWDLCD)。
//写数据
voidWriteCommandLCD(unsignedcharWCLCD,BuysC)。
//写指令
unsignedcharReadDataLCD(void)。
//读数据
unsignedcharReadStatusLCD(void)。
//读状态
voidLCDInit(void)。
//LCD初始化
voidDisplayOneChar(unsignedcharX,unsignedcharY,unsignedcharDData)。
//显示一个字符
voidDisplayListChar(unsignedcharX,unsignedcharY,unsignedcharcode*DData)。
//显示一串字符
voidDelay5Ms(void)。
voidDelay400Ms(void)。
voidread()。
//读取待测数据
ucharReadADC()。
//ADC读取函数
voidwritenumber()。
voidzhuan(uchari)。
unsignedcharcodeuctech[]={"TheDCvoltage:
"}。
unsignedcharcodenet[]={"the"}。
unsignedcharnum[5]。
unsignedcharshu[]={0x30,0x31,0x32,0x33,0x34,0x35,0x36,0x37,0x38,0x39}。
//0123456789
unsignedchargetdata。
voidmain(void)
{
ST=0。
OE=0。
ET0=1。
//计时器/计数器中断允许控制位;=1允许定时,计数器中断
ET1=1。
EA=1。
//中断允许总控制位
TMOD=0x12。
//定时器控制寄存器
TH0=216。
TL0=216。
//TH1=(65536-5000)/256。
//TL1=(65536-5000)%256。
TR1=1。
TR0=1。
Delay5Ms()。
ST=1。
ST=0。
ALE=0。
Delay400Ms()。
//启动等待,等LCD进入工作状态
LCDInit()。
//LCD初始化
Delay400Ms()。
//启动等待,等LCD进入工作状态
while
(1)
{
unsignedcharj。
DisplayListChar(0,0,uctech)。
//显示第0行
//DisplayListChar(0,1,num)。
//显示第1行
ReadDataLCD()。
//测试用句无意义
j=ReadADC()。
zhuan(j)。
//voidwritenumber(uchar*q)
//Delay400Ms。
//for()
//{
WriteCommandLCD(0xc0,0)。
WriteDataLCD(num[2])。
//}
}
}
ucharReadADC()//ADC读取函数
{
uchara。
ST=0。
Delay5Ms()。
ST=1。
//复位
ALE=1。
//?
?
?
_nop_()。
ST=0。
ALE=0。
//OE=0。
//ST=1。
//0>1。
上升沿ADC0809所有寄存器清零
//ST=0。
//当A/D转换结束时,
//此端输出一个高电平(转换期间一直为低电平).
while(EOC==0)//A/D转换结束信号,输出,
{
//ST=0。
//OE下降沿.A/D开始转换,期间ST保持低电平
//OE=1。
//OE为输出允许信号,用于控制三条输出锁存器向单片机输出转换得到地数据.
//OE=1,输出转换得到地数据;
//OE=0,输出数据线呈高阻状态.D7-D0为数字量输出线.
OE=1。
getdata=P0。
a=getdata。
//i=getdata。
OE=0。
}
return(a)。
}
voidzhuan(uchark)
{
k=k*196。
//k=k/256。
num[0]=shu[k/10000]。
k=k%10000。
num[1]=shu[k/1000]。
k=k%1000。
num[2]=shu[k/100]。
k=k%100。
num[3]=shu[k/10]。
}
/*
voidwritenumber(uchata,uchar*q)
{
ReadStatusLCD()。
//检测忙
LCD_Data=q[]。
}
//写数据
voidWriteDataLCD(unsignedcharWDLCD)
{
ReadStatusLCD()。
//检测忙
LCD_Data=WDLCD。
LCD_RS=1。
LCD_RW=0。
LCD_E=0。
//若晶振速度太高可以在这后加小地延时
LCD_E=0。
//延时
Delay5Ms()。
//不加延时通不过PROTEUS仿真
LCD_E=1。
}
//写指令
voidWriteCommandLCD(unsignedcharWCLCD,BuysC)//BuysC为0时忽略忙检测
{
if(BuysC)ReadStatusLCD()。
//根据需要检测忙
LCD_Data=WCLCD。
LCD_RS=0。
LCD_RW=0。
LCD_E=0。
LCD_E=0。
Delay5Ms()。
LCD_E=1。
}
//读数据
unsignedcharReadDataLCD(void)
{
LCD_RS=1。
LCD_RW=1。
LCD_E=0。
LCD_E=0。
Delay5Ms()。
LCD_E=1。
return(LCD_Data)。
}
//读状态
unsignedcharReadStatusLCD(void)
{
LCD_Data=0xFF。
LCD_RS=0。
LCD_RW=1。
LCD_E=0。
LCD_E=0。
Delay5Ms()。
LCD_E=1。
while(LCD_Data&Busy)。
//检测忙信号
return(LCD_Data)。
}
voidLCDInit(void)//LCD初始化
{
LCD_Data=0。
WriteCommandLCD(0x38,0)。
//三次显示模式设置,不检测忙信号
Delay5Ms()。
WriteCommandLCD(0x38,0)。
Delay5Ms()。
WriteCommandLCD(0x38,0)。
Delay5Ms()。
WriteCommandLCD(0x38,1)。
//显示模式设置,开始要求每次检测忙信号
WriteCommandLCD(0x08,