10.3 单片机开发系统应用实例 10.3.1 数据采集与显示电路的设计 1.系统硬件电路的设计 10.3 单片机开发系统应用实例 10.3.1 数据采集与显示电路的设计 1.系统硬件电路的设计 图10-1为数据采集与显示AT89C51单片机系统的电路原理图。下面对各部分电路予以说明。
1) 模拟量采集电路 8路模拟量采集由A/D转换器ADC0809完成,它具有8路模拟输入端,传感器检测的信号经模拟电路(略)转换成0~5 V的直流信号后送给ADC0809,地址线(A、B、C端)决定对哪一路模拟输入作A/D转换。 2) 8路开关故障信号检测 8路开关量信号采用中断查询相结合的方法检测。
3) 显示电路 正常的模拟量显示和故障信息显示采用4位共阳极LED数码显示电路,显示内容由串行口输出给串入并出移位寄存器74LS164,驱动数码管显示,采用动态扫描方法逐位显示相关内容,显示的位数由P3.3~P3.6口控制。 4) 其它电路 上电复位电路,外晶振电路如图10-1所示。
图10-1 数据采集显示电路原理图
2.系统软件设计 1) 主程序 主程序完成的功能是初始化,然后循环调用显示子程序和模拟量测量子程序,对每一通道的模拟量进行采集并循环显示通道号和采集数据,每个通道显示时间为1 s。其程序流程图如图10-2所示。
图10-2 主程序流程图
2) 中断服务子程序 中断服务子程序主要用于判断故障源,并显示相应的故障信息。故障信息只用数码管的后两位表示,故障信息码是固定的,存在于固定的内存单元中。其程序流程图如图10-3所示。
图10-3 中断服务程序流程图
3) 显示子程序 显示子程序功能是显示某一模拟量输入通道的通道号和对应的采集数据,而并不显示开关量故障信息码。采用动态扫描法实现4位数码管的数据显示。采样所得的A/D转换数据存放在60H~67H内存单元中,采集数据在显示时需转换成十进制BCD码,其个位、十位、百位分别存放在68H~6AH内存单元中,对应通道号存放在7BH单元中。寄存器R0用作显示数据地址指针。动态扫描周期为20 ms。其程序流程图如图10-4所示。
图10-4 显示子程序流程图
4) 模拟量测量子程序 模拟量测量子程序的功能是控制A/D转换器0809对8路模拟量输入电压信号进行A/D转换,并将转换数据存入60H~67H单元中。其程序流程图如图10-5所示。
图10-5 测量子程序
程序如下: ORG 0000H AJMP INITZ ;跳至主程序 ORG 0003H ;外中断0中断入口地址 AJMP FLTRT ;转外中断0子程序 NOP ******主程序******
ORG 0052H INITZ:CLR A MOV P2,A ;A/D转换准备 MOV R0,#7FH ;内存循环清零(00H~7FH) RAMX:MOV @R0,A DJNZ R0,RAMX MOV TCON,A ;定时器0停止计数 MOV TMOD,#01H ;定时器0工作方式1 MOV SCON,#00H ;串行口工作在方式0
MOV SP,#15H ;置堆栈指针 SETB EA ;开中断 SETB EX0 ;允许外中断0中断 CLR IT0 ;外中断0为电平触发 WAITX: LCALL CLST ;循环测量一次 LCALL XSZC ;循环显示数据一次 AJMP WAITX ;返回WAITX循环 ******测量子程序******
CLST:CLR A MOV R0,#60H ;测量值存放首址 MOV R7,#00H ;置初始通道号 CLST1: MOV A,R7 MOV P2,A ;输出通道地址 SETB P2.3 ;锁存通道地址 SETB P2.4 ;A/D启动准备 NOP ;延时2 μs CLR P2.4 ;A/D启动
JNB P3.7,$ ;等待转换结束 SETB P2.5 ;允许0809数据输出 MOV A,P0 ;读入A/D转换值 MOV @R0,A ;存入内存 CLR P2.5 ;关闭0809输出 INC R0 ;内存地址,通道号增1 INC R7 CJNE R7,#08H,CLST1 ;采集结束了吗?没有结束则采集下一个通道
MOV P2,#00H ;一次测量结束 RET ;子程序返回 ******显示子程序******* XSZC:MOV R0,#60H ;显示数据地址初值 MOV 6BH,#00H ;置通道号初值
XSZC1: MOV R3,#32H ;扫描频率 MOV A,@R0 ;显示数据转换为三位BCD码 MOV B,#100 DIV AB MOV 6AH,A ;百位BCD码存于6AH中
MOV A,#10 XCH A,B DIV AB MOV 69H,A ;存十位BCD码 MOV 68H,B ;存个位BCD码 XSZC2: MOV TH0,#27H ;扫描周期由T0定时20 ms MOV TL0,#10H SETB TR0 ;启动T0 SETB P3.6 ;关闭通道号显示位
MOV A,68H ;取出各位显示数据 MOV DPTR,#MAB ;显示段码首址 MOVC A,@A+DPTR MOV SBUF,A ;显示数据由串行口输出 JNB TI,$ ;等待传送结束 CLR P3.3 ;显示个位 CLR TI ;清除TI LCALL YS1 ;调延时1 ms子程序 SETB P3.3 ;消去个位显示 MOV A,69H ;取十位显示数据显示
MOV A,@A+DPTR MOV SBUF,A JNB TI,$ CLR P3.4 CLR TI LCALL YS1 SETB P3.4 MOV A,6AH ;取百位显示数据显示 MOVC A,@A+DPTR
JNB TI,$ CLR P3.5 CLR TI LCALL YS1 SETB P3.5 MOV A,6BH ;取通道号显示 MOVC A,@A+DPTR MOV SBUF,A CLR P3.6
SETB P3.6 JNB TF0,$ ;是否到20 ms?若不到则等待 CLR TR0 ;关闭定时器T0 DJNZ R3,XSZC2 ;1 s不到继续显示该通道数据 INC R0 ;显示下一个通道数据 INC 6BH MOV A,6BH CJNE A,#08H,XSZC1 ;八个通道显示一次吗?没有则继续 RET ;循环显示一次结束,返回
YS1: MOV R2,#0AH ;1 ms延时子程序 YS11: MOV R6,#0CH YS12: DJNZ R6,YS12 DJNZ R2,YS11 RET ******中断服务程序******
FLTRT: CLR EX0 ;关中断 CLR EA JNB P3.2,FLTRT1 ;真的有中断请求吗?有,转移 RETI ;没有中断,退出 FLTRT1: MOV R0,#00H ;置故障码偏移地址 CLR TR0 ;关定时器T0 CLR TI ;清除TI标志 JB P1.0,DLC1 ;判断故障源
INC R0 ;改变故障码偏移地址 INC R0 JB P1.1,DLC1 JB P1.6,DLC1
DLC1: MOV A,R0 ;取出故障码偏移地址 SETB P3.5 ;关闭高两位数码管 SETB P3.6 MOV TH0,#27H ;定时器T0定时20 ms MOV TL0,#10H SETB TRO ;启动T0 MOV DPTR,#MCD ;置故障信息段码首址 MOVC A,@A+DPTR ;取出故障信息段码低位 MOV SBUF,A ;输出故障信息段码
JNB TI,$ ;等待输出结束 CLR P3.3 ;显示故障信息低位 CLR TI LCALL YS1 ;延时1 ms SETB P3.3 INC R0 MOV A,R0 MOVC A,@A+DPTR ;取出故障信息段码高位
MOV SBUF,A ;输出故障信息段码高位 JNB TI,$ CLR P3.4 ;显示故障信息段码高位 CLR TI LCALL YS1 ;延时1 ms SETB P3.4 JNB TF0,$ ;等待20 ms结束 CLR TR0 ;关闭T0 AJMP DLC1 ;循环显示故障信息 END
LED数码显示管共阳段码表,分别对应0~9。 CLR TR0 ;关闭T0 AJMP DLC1 ;循环显示故障信息 MAB: DB 0C0H,0F9H,0A4H,0B0H ;共阳数码管段码表,分别对应0~9 DB 99H,92H,82H,0F8H,80H,90H MCD: DB LED数码显示管用故障信息段码表,根据需要编制(略) END