数字电子表.docx
《数字电子表.docx》由会员分享,可在线阅读,更多相关《数字电子表.docx(20页珍藏版)》请在冰豆网上搜索。
数字电子表
河北工业大学计算机
硬件技术基础(MCS-51)2008年秋季综合性、开放性实验报告
学院土木学院班级姓名:
学号:
成绩
一、题目:
数字电子表
二、问题的提出
通过外部中断INT0随时检测有没有调时按键按下,转入提取键值部分程序。
三、总体设计
1、调试功能:
按下K1键进入调试,再通过键盘输入数字以调整时间。
2、系统总体结构设计
1)硬件设计:
MCS-51单片机、硬件试验设备。
2)软件设计:
首先时用LED显示数字的问题,可以利用试验十四的程序设计;然后进入整体程序设计,做流程图整理思路,然后根据流程图一步步进行。
四、详细设计:
1、硬件详细设计:
将硬件设备上的数码显示器区的SDA接A区的P17,SCL接P16,RST接P10,INT_KEY接P3.2;
2、所用存储单元为ACC,R0,R1,R2,R3,CY
3、设计中的主要困难及解决方案
利用键盘输入数字以调整时间这段程序,没有完善,导致最终没能做出调时这个功能。
三、程序清单
SDABITP1.7;I2C总线定义串行数据存取位
SCLBITP1.6
;I2C总线定义串行时钟位
RSTBITP1.0;MCU复位输出信号,低电平复位ZLG7290
INT_KEYBITP3.2;MCU中断信号输入,有效的按键动作使该引脚信号变为低电平
MTDEQU40H;I2C总线发送数据缓冲区(8字节)
MRDEQU48H;I2C总线接收数据缓冲区(8字节)
DisBufEQU38H;显示缓冲区(8字节,可对应8位数码管显示)
;定义ZLG7290器件地址及子地址
ZLG7290EQU70H;ZLG7290的器件地址
ACKBIT10H;应答标志位
SLADATA50H;器件的从地址
SUBADATA51H;器件的子地址
NUMBYTEDATA52H;读/写的字节数变量
KeyDATA53H;返回用户按键值
SystemRegEQU00H;系统寄存器地址,保存ZLG7290系统状态
KeyRegEQU01H;键值寄存器,表示被压按键的键值
CmdBuf0EQU07H;命令缓冲区0
CmdBuf1EQU08H;命令缓冲区1
DpRamEQU10H;显示缓存寄存器
SECONDEQU30H
MINITEEQU31H
HOUREQU32H
ORG8000H
LJMPMAIN
ORG8003H
LJMPINT_T0
;-------主程序如下:
MAIN:
MOVSP,#70H;堆栈区从70H开始
CLRRST;复位ZLG7290
LCALLDELAY;等待复位完成,ZLG7290复位周期比较长,必须等待
SETBRST;结束复位
LCALLDELAY
lcallClsDisp;清除显示
MainLoop:
movDisBuf+0,#0;上电运行时,8位数码管显示00120000
movDisBuf+1,#0;给显示缓冲区赋值,00120000
movDisBuf+2,#0
movDisBuf+3,#0
movDisBuf+4,#2
movDisBuf+5,#1
movDisBuf+6,#1FH
movDisBuf+7,#1FH
MOVR4,#00H
lcallDisplay;调用显示子程序,显示内容
MOVTMOD,#01H
MOVTH0,#4CH
MOVTL0,#00H
SETBTR0
SETBEA
SETBIT0
SETBEX0
MOVSECOND,#00H
MOVMINITE,#00H
MOVHOUR,#12
MAINSC:
JBCTF0,KS
SJMPMAINSC
KS:
MOVTH0,#4CH
MOVTL0,#00H
INCR4
CJNER4,#20,MAINSC
MOVR4,#00H
MOVA,SECOND
ADDA,#01H
MOVSECOND,A
CJNEA,#60,NS602
MOVSECOND,#00H
MOVA,MINITE
ADDA,#01H
MOVMINITE,A
NS602:
MOVA,SECOND
MOVB,#10
DIVAB
MOVDisBuf+1,A
MOVA,B
MOVDisBuf+0,A
KM:
MOVA,MINITE
CJNEA,#60,NM602
MOVMINITE,#00H
MOVA,HOUR
ADDA,#01H
MOVHOUR,A
NM602:
MOVA,MINITE
MOVB,#10
DIVAB
MOVDisBuf+3,A
MOVA,B
MOVDisBuf+2,A
KH:
MOVA,HOUR
CJNEA,#24,NH602
MOVHOUR,#00H
NH602:
MOVA,HOUR
MOVB,#10
DIVAB
MOVDisBuf+5,A
MOVA,B
MOVDisBuf+4,A
LCALLDisplay
SJMPMAINSC
;子程序名:
ClsDisp
;功能:
清除显示内容
;调用:
VI2C_ASM.INC
;入口参数:
无
;出口参数:
无
;占用资源:
R0,R1,R2,R3(工作寄存器组1),ACC,Cy,R5(当前工作寄存器组)
ClsDisp:
movR5,#8;循环计数器初值,8位数码管
movA,#01100000B;按位下载数据且译码指令01100A2A1A0
;A2~A0:
对应显示位置1~8位数码管
Cls1:
MOVSLA,#ZLG7290;指定器件地址
MOVSUBA,#CmdBuf0;指定子地址
MOVMTD,A;命令送I2C总线发送数据缓冲区
movMTD+1,#1FH;命令参数,1FH:
无显示
MOVNUMBYTE,#02H;待发送数据2字节
pushACC;保护ACC
pushPSW;保护PSW
setbRS0;切换工作寄存器,I2C通信软件使用工作寄存器组1
clrRS1
LCALLIWRNBYTE;调用写2字节数据程序(VI2C_ASM.INC,I2C模拟软件包)
popPSW;恢复PSW
popACC;恢复ACC
incA;按位下载数据且译码指令地址部分+1
LCALLDELAY;延时,等待ZLG7290执行上述命令
djnzR5,Cls1;没有达到8次,继续循环
ret;子程序返回
;子程序名:
Display
;功能:
在8段LED数码管显示
;调用:
VI2C_ASM.INC
;入口参数:
Disbuf+0~Disbuf+7,8字节显示缓冲区
;出口参数:
无
;占用资源:
R0,R1,R2,R3(工作寄存器组1),ACC,Cy,R0,R5(当前工作寄存器组)
Display:
movR5,#8;循环计数器初值,8位数码管
movA,#01100000B;按位下载数据且译码指令01100A2A1A0
;A2~A0:
对应显示位置1~8位数码管
movR0,#Disbuf;R0->Disbuf
Disp1:
MOVSLA,#ZLG7290;指定器件地址
MOVSUBA,#CmdBuf0;指定子地址
MOVMTD,A;命令送I2C总线发送数据缓冲区
movMTD+1,@R0;命令参数,待显示数据送I2C总线发送数据缓冲区
MOVNUMBYTE,#02H;待发送数据2字节
pushACC;保护ACC
pushPSW;保护PSW
setbRS0;切换工作寄存器,I2C通信软件使用工作寄存器组1
clrRS1
LCALLIWRNBYTE;调用写2字节数据程序(VI2C_ASM.INC,I2C模拟软件包)
popPSW;恢复PSW
popACC;恢复ACC
incA;按位下载数据且译码指令地址部分+1
incR0;R0+1,指向下一个待显示数据
LCALLDELAY;延时,等待ZLG7290执行上述命令
djnzR5,Disp1;没有达到8次,继续循环
ret;子程序返回
;子程序名:
GetKey
;功能:
获取用户按键值(Key)
;调用:
VI2C_ASM.INC
;入口参数:
无
;出口参数:
Key
;占用资源:
R0,R1,R2,R3(工作寄存器组1),ACC,Cy
GetKey:
MOVSLA,#ZLG7290;指定器件地址
MOVSUBA,#01H;指定子地址
MOVNUMBYTE,#01H;读1字节数据
pushACC;保护ACC
pushPSW;保护PSW
setbRS0;切换工作寄存器,I2C通信软件使用工作寄存器组1
clrRS1
LCALLIRDNBYTE;调用读1字节数据程序
popPSW;恢复PSW
popACC;恢复ACC
movKey,MRD;读取的数据送Key
ret;子程序返回
;子程序名:
DELAY
;功能:
延时约36.5ms(11.0592MHz时钟)
;调用:
YS500US
;入口参数:
无
;出口参数:
无
;占用资源:
R7,R6
DELAY:
MOVR7,#80H
MIN:
LCALLYS500US
DJNZR7,MIN
RET
;子程序名:
YS500US
;功能:
延时约279us(11.0592MHz时钟)
;调用:
无
;入口参数:
无
;出口参数:
无
;占用资源:
R6
YS500US:
MOVR6,#80H
DJNZR6,$;延时128×2T=256T(T=1/1159200)
RET
;子程序名:
中断程序
INT_T0:
lcallGetKey;获取键值
movA,Key
PUSHACC
CJNEA,#01,COUT1
ADDA,#01H
DAA
MOVMINITE,A
CJNEA,#60,NS60
MOVMINITE,#00H
NS60:
MOVA,MINITE
MOVB,#10
DIVAB
MOVDisBuf+3,A
MOVA,B
MOVDisBuf+2,A
LCALLDisplay
SJMPFHCX
COUT1:
JNCFHCX
MOVA,HOUR
ADDA,#01H
DAA
MOVHOUR,A
CJNEA,#24,NH60
MOVHOUR,#00H
NH60:
MOVA,HOUR
MOVB,#10
DIVAB
MOVDisBuf+5,A
MOVA,B
MOVDisBuf+4,A
LCALLDisplay
FHCX:
RETI
$INCLUDE(VI2C_ASM.INC);将VIIC软件包加入到本段代码后
END
;--------------------------------------------------------------------------------------------------------
;MCS-51单片机模拟I2C软件包(V1.1)
;文件名:
VI2C_ASM.INC
;功能说明:
本模拟I2C软件包包含了I2C操作的底层子程序,使用前要定义
;好SCL和SDA。
在标准8051模式(12Clock)下,对主频要求是不高于12MHz(即1个
;机器周期1us);若Fosc>12MHz则要增加相应的NOP指令数。
(总线时序符合I2C标
;准模式,100Kbit/S)
;版本说明:
本版新增了两个子程序,IWRNBYTEEXT,IRDNBYTEEXT两个子程序,
;这两个子程序用于主从通讯上及一此特殊器件的读写操作较为方便.
;更新时间:
2002.06.04
;--------------------------------------------------------------------------------------------------------
;启动I2C总线子程序
START:
SETBSDA
NOP
SETBSCL;起始条件建立时间大于4.7us
NOP
NOP
NOP
NOP
NOP
CLRSDA
NOP;起始条件锁定时大于4us
NOP
NOP
NOP
NOP
CLRSCL;钳住总线,准备发数据
NOP
RET
;结束总线子程序
STOP:
CLRSDA
NOP
SETBSCL;发送结束条件的时钟信号
NOP;结束总线时间大于4us
NOP
NOP
NOP
NOP
SETBSDA;结束总线
NOP;保证一个终止信号和起始信号的空闲时间大于4.7us
NOP
NOP
NOP
RET
;发送应答信号子程序
MACK:
CLRSDA;将SDA置0
NOP
NOP
SETBSCL
NOP;保持数据时间,即SCL为高时间大于4.7us
NOP
NOP
NOP
NOP
CLRSCL
NOP
NOP
RET
;发送非应答信号
MNACK:
SETBSDA;将SDA置1
NOP
NOP
SETBSCL
NOP
NOP;保持数据时间,即SCL为高时间大于4.7us
NOP
NOP
NOP
CLRSCL
NOP
NOP
RET
;检查应答位子程序
;返回值,ACK=1时表示有应答
CACK:
SETBSDA
NOP
NOP
SETBSCL
CLRACK
NOP
NOP
MOVC,SDA
JCCEND
SETBACK;判断应答位
CEND:
NOP
CLRSCL
NOP
RET
;发送字节子程序
;字节数据放入ACC
;每发送一字节要调用一次CACK子程序,取应答位
WRBYTE:
MOVR0,#08H
WLP:
RLCA;取数据位
JCWR1
SJMPWR0;判断数据位
WLP1:
DJNZR0,WLP
NOP
RET
WR1:
SETBSDA;发送1
NOP
SETBSCL
NOP
NOP
NOP
NOP
NOP
CLRSCL
SJMPWLP1
WR0:
CLRSDA;发送0
NOP
SETBSCL
NOP
NOP
NOP
NOP
NOP
CLRSCL
SJMPWLP1
;读取字节子程序
;读出的值在ACC
;每取一字节要发送一个应答/非应答信号
RDBYTE:
MOVR0,#08H
RLP:
SETBSDA
NOP
NOP
NOP
NOP
SETBSCL;时钟线为高,接收数据位
NOP
NOP
NOP;+1
NOP;+1
NOP;+1
NOP;+1
NOP;+1
MOVC,SDA;读取数据位
MOVA,R2
CLRSCL;将SCL拉低,时间大于4.7us
RLCA;进行数据位的处理
MOVR2,A
NOP
NOP
NOP
NOP;+1
NOP;+1
NOP;+1
NOP
NOP
NOP;+1
NOP
NOP;+1
NOP;+1
DJNZR0,RLP;未够8位,再来一次
RET
;========================================================================================
;========================================================================================
;以下是用户接口子程序
;
;无子地址器件写字节数据
;入口参数:
数据为ACC、器件从地址SLA
;占用:
A、R0、CY
IWRBYTE:
PUSHACC
IWBLOOP:
LCALLSTART;起动总线
MOVA,SLA
LCALLWRBYTE;发送器件从地址
LCALLCACK
JNBACK,RETWRB;无应答则跳转
POPACC;写数据
LCALLWRBYTE
LCALLCACK
LCALLSTOP
RET
RETWRB:
POPACC
LCALLSTOP
RET
;无子地址器件读字节数据
;入口参数:
器件从地址SLA
;出口参数:
数据为ACC
;占用:
A、R0、R2、CY
IRDBYTE:
LCALLSTART
MOVA,SLA;发送器件从地址
INCA
LCALLWRBYTE
LCALLCACK
JNBACK,RETRDB
LCALLRDBYTE;进行读字节操作
LCALLMNACK;发送非应信号
RETRDB:
LCALLSTOP;结束总线
RET
;向器件指定子地址写N字节数据
;入口参数:
器件从地址SLA、器件子地址SUBA、发送数据缓冲区MTD、发送字节数NUMBYTE
;占用:
A、R0、R1、R3、CY
IWRNBYTE:
MOVA,NUMBYTE
MOVR3,A
LCALLSTART;起动总线
MOVA,SLA
LCALLWRBYTE;发送器件从地址
LCALLCACK
JNBACK,RETWRN;无应答则退出
MOVA,SUBA;指定子地址
LCALLWRBYTE
LCALLCACK
MOVR1,#MTD
WRDA:
MOVA,@R1
LCALLWRBYTE;开始写入数据
LCALLCACK
JNBACK,IWRNBYTE
INCR1
DJNZR3,WRDA;判断写完没有
RETWRN:
LCALLSTOP
RET
;向器件指定子地址读取N字节数据
;入口参数:
器件从地址SLA、器件子地址SUBA、接收字节数NUMBYTE
;出口参数:
接收数据缓冲区MTD
;占用:
A、R0、R1、R2、R3、CY
IRDNBYTE:
MOVR3,NUMBYTE
LCALLSTART
MOVA,SLA
LCALLWRBYTE;发送器件从地址
LCALLCACK
JNBACK,RETRDN
MOVA,SUBA;指定子地址
LCALLWRBYTE
LCALLCACK
LCALLSTART;重新起动总线
MOVA,SLA
INCA;准备进行读操作
LCALLWRBYTE
LCALLCACK
JNBACK,IRDNBYTE
MOVR1,#MRD
RDN1:
LCALLRDBYTE;读操作开始
MOV@R1,A
;NOP;+1
;NOP;+1
DJNZR3,SACK
LCALLMNACK;最后一字节发非应答位
RETRDN:
LCALLSTOP;并结束总线
RET
SACK:
LCALLMACK
INCR1
SJMPRDN1
;无子地址器件写N字节数据
;入口参数:
器件从地址SLA、发送数据缓冲区MTD、发送字节数NUMBYTE
;占用:
A、R0、R1、R3、CY
;不发送子地址SUBA,直接发送多个数据.
IWRNBYTEEXT:
MOVA,NUMBYTE
MOVR3,A
LCALLSTART;起动总线
MOVA,SLA
LCALLWRBYTE;发送器件从地址
LCALLCACK
JNBACK,RETWRNE;无应答则退出
MOVR1,#MTD
WRDAE:
MOVA,@R1
LCALLWRBYTE;开始写入数据
LCALLCACK
JNBACK,RETWRNE
INCR1
DJNZR3,WRDAE;判断写完没有
RETWRNE:
LCALLSTOP
RET
;无子地址器件读取N字节数据
;入口参数:
器件从地址SLA、器件子地址SUBA、接收字节数NUMBYTE
;出口参数:
接收数据缓冲区MTD
;占用:
A、R0、R1、R2、R3、CY
;说明:
此函数不发送子址,也不重新启动总线,而是直接读取多个数据.
IRDNBYTEEXT:
MOVR3,NUMBYTE
LCALLSTART
MOVA,SLA
INCA
LCALLWRBYTE;发送器件从地址
LCALLCACK
JNBACK,RETRDNE
MOVR1,#MRD
RDNE1:
LCALLRDBYTE;读操作开始
MOV@R1,A
DJNZR3,SACKE
LCALLMNACK;最后一字节发非应答位
RETRDNE:
LCALLSTOP;并结束总线
RET
SACKE:
LCALLMACK
INCR1
SJMPRDNE1
;*****************************************