毕业设计162实时钟设计.docx
《毕业设计162实时钟设计.docx》由会员分享,可在线阅读,更多相关《毕业设计162实时钟设计.docx(27页珍藏版)》请在冰豆网上搜索。
毕业设计162实时钟设计
目录
1.需求分析…………………………………………………………………1
2.概要设计…………………………………………………………………1
3.详细设计…………………………………………………………………1
3.1键盘模块……………………………………………………………………1
3.2实时钟模块…………………………………………………………………4
3.3显示模块……………………………………………………………………6
3.4整点报时模块………………………………………………………………7
3.5主程序模块…………………………………………………………………7
4.调试数据与运行结果分析…………………………………………………7
5.程序说明……………………………………………………………………8
6.软件程序框图………………………………………………………………8
6.1显示子程序流程图…………………………………………………………8
6.2键盘子程序流程图…………………………………………………………9
6.3整点报时子程序流程图……………………………………………………9
6.4实始终子程序流程图………………………………………………………10
7.附录…………………………………………………………………………11
8.参考文献……………………………………………………………………11
9.附录源代码…………………………………………………………………11
10.课设心得……………………………………………………………………18
11.硬件原理图…………………………………………………………………18
实时钟设计
一.需求分析
1.设备和器材
PC机一台,8031芯片一块,并行接口8155A一片,数字开关1个,LED数码管6只,蜂鸣器一只,四行八列键盘。
2.功能实现
⑴采用定时器中断的方法,设计一个一天24小时进制的实时时钟;
⑵用6个发光二极管分别显示时、分、秒的记时;
⑶能进行整点报时;
⑷可以从键盘中预置、修改时钟值。
二.概要设计
本设计共有四个模块,即键盘模块,实时钟模块,显示模块以及整点报时模块。
键盘模块包含两个部分,一个是键盘扫描,判断是哪一个键被按下;另一个是将键码换算成数字,送到显示缓冲区;
1.实时钟模块:
用六个内存单元储存六个显示器所要显示的数据,利用8031内部的定时/计数器实现中断计时;
2.显示模块:
6位显示器采用动态显示方式,8155A的PA口输出位码,以轮流点亮六个LED显示器;缓冲区内的六个单元通过PB口输出控制段码,实现显示的数字控制;
3.整点报时模块:
在实时钟显示到整点的时候启动蜂鸣器报时,即向管脚P1.7输入一个高电平一个低电平,延时,并通过内存单元22H传递整点小时数使得蜂鸣器通过鸣响的次数报时。
三.详细设计
1.键盘模块
A.硬件设置:
8031通过8155H与8759键盘相连,8155的PA口8线控制8根列线,PC口低4位控制4根行线;另外键盘这个模块是通过外部中断实现的,只有在外部输入负脉冲的时候才执行,所以8031的P3.2口必须连接负脉冲/SP口。
B.软件编写:
⑴.键盘扫描的功能通过四个步骤实现。
1判别键盘上有无键闭合。
扫描PA口8个端口PA0—PA7,输出全0,读PC口状态,若PC0—PC3为全1,则键盘上没有闭合的键,跳到子程序KSI继续判断,否则说明有见怕闭合,执行下一步;
2去除抖动。
调用子程序DL6ms延迟一段时间再次调用子程序KSI判断键盘状态,如果仍然有键闭合则认为有键被按下,执行下一步,否则认为是键的抖动,回到上一步;
3判别闭合键的键号。
对键盘的列线进行逐行扫描,扫描口PA口的输出从0FEH开始依次左移直到8根列线全部扫描完毕,相应读出PC口的状态,处于低电平的行线就是有键按下的行,列号加上行首的键号得到的便是键号,将键号传递给寄存器B保存,执行下一步;
4判断闭合键是否被释放。
详细程序:
KEYI:
ACALLKS1;判断是否有键闭合
JNZLK1;有键闭合,判断是否因抖动引起
NI:
ACALLDIR;没有键闭合,在等待中显示
;ACALLDL6ms;延时
AJMPKEYI;跳回到上一步去,判断有无键被按下
LK1:
ACALLDL6ms;延时去抖动
ACALLDL6ms;延时去抖动
ACALLKS1;再次判断是否有键闭合
JNZLK2;确实有键闭合,执行下一步,判断键号
ACALLDL6ms;延时
AJMPKEYI;低电平由抖动引起,跳回上一步
LK2:
MOVR2,#0FEH;列选码0FEH送到R2
MOVR4,#00H;R4里保存列号
LK4:
MOVDPTR,#0FF21H;8155PA口
MOVA,R2
MOVX@DPTR,A;列选码送入到8155PA口
INCDPTR
INCDPTR;8155PC口
MOVXA,@DPTR;读8155PC口
JBAcc.0,LONE;判断0行线,如果0行没有键按下则转为判断1行
MOVA,#00H;0行有键按下,首键号送到A寄存器
AJMPLKP;计算键号
LONE:
JBAcc.1,LTW0;判断1行线,如果1行没有键按下则转为判断2行
MOVA,#08H;1行有键按下,首键号送到A寄存器
AJMPLKP;计算键号
LTW0:
JBAcc.2,LTHR;判断2行线,如果2行没有键按下则转为判断3行
MOVA,#10H;2行有键按下,首键号送到A寄存器
AJMPLKP;计算键号
LTHR:
JBAcc.3,NEXT;判断3行线,如果3行没有键按下则转为下一列扫描
MOVA,#18H;3行有键按下,首键号送到A寄存器
LKP:
ADDA,R4;计算键号,即行首号加上列号
PUSHAcc;键号进栈保护
MOVB,A;键号由寄存器B保存传递到下一步
LK3:
ACALLDL6ms;延时
ACALLKS1;判断键是否得到释放
JNZLK3;键没有释放,再次判断
POPAcc;键已经释放,键号出栈
RET;返回
NEXT:
INCR4;列号加1,进行下一列扫描
MOVA,R2;判断是否已经扫描到最后一列
JNBAcc.7,KND;已经扫描到最后一列,重新进行整个键盘扫描,判断是否有键按下
RLA;没有到最后一列,列选码左移一位
MOVR2,A;列选码送入到R2保存
AJMPLK4;继续下一列扫描,判断键号
KND:
AJMPKEYI
KS1:
MOVDPTR,#0FF21H;判断有无键按下子程序
MOVA,#00H
MOVX@DPTR,A;8155PA口置0,列线全为低电平
INCDPTR
INCDPTR;8155PC口
MOVXA,@DPTR;从PC口读出行线状态
CPLA;行线取反,如果没有键按下,则A为0
ANLA,#0FH;屏蔽无用的高四位
RET;返回
⑵在键盘扫描过程中我已经将得到的键号送至寄存器B保存,我用这一段程序将B寄存器中储存的键码换算成数字,送至显示缓冲区40H-45H保存。
实现的方法是将键码与0—9十个数字的键码一一对比,两者相等则将数字送到缓冲区去显示,不相等则进行下一步比较,如果获得的键码不是10个数字中的任何一个,那么重新返回扫描键盘。
详细的比较程序(其余9个数字的比较依此类推):
IN:
MOVR5,B;将扫描键盘获得的键码送到R5中
LA0:
CJNER5,#09H,LA1;判断键码与键盘上数字0的键码是否相等,不相等则转而判断是否与1的键码相等
MOVA,#00H;相等,将0送入寄存器A
AJMPNEA;由寄存器A将数字0送至显示缓冲区
比较得到的数字通过寄存器A送入到显示缓冲区,程序:
NEA:
MOV@R1,A;将寄存器A中的数字送入到显示缓冲区
ACALLDIR;显示
DECR1;R1指向下一个缓冲单元
LLL:
RET;返回
⑶在实时钟的设计中,时、分、秒一共有六个数据通过键盘输入,所以除了以上两段处理键盘的程序以外还要有一段程序来控制读取按键的次数,并将这六个数字依次保存到内存单元中去。
程序如下:
INTL:
ACALLDIR;显示
ACALLKEYI;调用键盘扫描
ACALLIN;将键码换算成数字
DJNZ21H,INTL;到六次否?
没有,继续;达到六次,中断返回
RETI
2.实时钟模块
在这个模块中我要实现的是实时钟以时、分、秒进行计时。
我用的是8031内部T0中断计时,定时100毫秒,然后进行溢出次数的累计,计满10次得到秒的计时。
其中100毫秒的计数初值计算(设初值为X):
(2E16-X)*2*10E-6=0.1
计算得初值X=3CBOH,所以TH0=3CH,TL0=B0H.
为了方便显示,我用了40H,41H,42H,43H,44H,45H六个内存单元存放时分秒三个数据。
具体程序如下:
IT0P:
PUSHPSW;保存现场
PUSHACC
MOVTH0,#3CH;装入初值
MOVTL0,#0B0H
DJNZ20H,RETURN;1秒未到,返回
MOV20H,#0AH;重置中断次数
MOVA,#01H
ADDA,40H
MOV40H,A;秒单元个位加1
CJNEA,#0AH,RETURN;是否到10,是则进位,否则返回
MOV40H,#00H;进位,秒的个位清0
MOVA,#01H
ADDA,41H
MOV41H,A;秒的十位加1
CJNEA,#6,RETURN;是否到60秒,是则进位,否则返回
MOV41H,#00H;进位,秒的十位清0
MOVA,#01H
ADDA,42H
MOV42H,A;分的个位加1
CJNEA,#0AH,RETURN;是否到10,是则进位,否则返回
MOV42H,#00H;进位,分的个位清0
MOVA,#01H
ADDA,43H
MOV43H,A;分的十位加1
CJNEA,#6,RETURN;是否到60分,是则进位,否则返回
MOV43H,#00H;进位,时的个位清0
MOVA,#01H
ADDA,44H;十的个位数字加1后传给寄存器A
PUSHACC;保存加1后的小时个位
MOVA,B
PUSHACC;保存寄存器B的内容
MOVB,45H
MOVA,#0AH
MULAB;计算小时的个数,传给内存单元22H,以便整点报时
ADDA,44H
MOV22H,A
INC22H
POPACC
MOVB,A;A,B寄存器复原
ACALLSOUND;调用整点报时子程序
MOVA,45H
CJNEA,#02H,L1;判断时的十位数字是否已经加到2
POPACC
MOV44H,A;将时的个位加1
CJNEA,#4,RETURN;判断是否已经到24小时,不是则返回
MOV44H,#00H
MOV45H,#00H;已经到24小时,时的两个内存单元清0
RETURN:
POPACC
POPPSW;恢复现场
RETI;中断返回
L1:
POPACC;时的个位没有到2的情况处理
MOV44H,A;时的个位加1
CJNEA,#0AH,RETURN;是否到10,是则进位,否则返回
MOV44H,#00H;进位,时的个位清0
MOVA,#01H;时的十位加1
ADDA,45H
MOV45H,A
RET
3.显示模块
A.硬件设置:
8031通过8155与LED显示器相连,8155的PA口低6位线控制经过反相器75452×3对6个LED显示器进行位选,PB口8线连接显示器8段发光二极管控制字型码;
B.软件编写:
这一段程序主要实现动态显示。
在8031内部RAM中设置6个单元40H—45H存放将要显示的6位数据,8155H的PA口的输出控制位码,选择由哪一个LED显示,PB口输出控制显示的字型,使每次只有一位显示某一指定单元的字符,然后依次改变PA口输出为高的位也就是改变点亮的LED显示器,这样显示器的6位就能动态地显示相应单元的字符。
具体程序如下:
DIR:
MOVR0,#40H;设置缓冲区指针初值40H
MOVR3,#01H;位选码的初值送R3
MOVA,R3
LD0:
MOVDPTR,#0FF21H;位选码送入8155的PA口
MOVX@DPTR,A
INCDPTR;8155PB口
MOVA,@R0;显示缓冲单元里的数据送入寄存器A
ADDA,#0DH;加偏移量,指向段码表
MOVCA,@A+PC;取段码
DIR1:
MOVX@DPTR,A;段码送入8155PB口
ACALLDL1ms;调用延时
INCR0;缓冲区指针指向下一个数据单元
MOVA,R3;位选码送入A中
JBAcc.5,LD1;判断是否六个LED显示器扫描完毕,是则返回
RLA;不是,点亮下一个LED显示器
MOVR3,A;位选码送入R3
AJMPLD0;循环显示
LD1:
RET
LABLE:
DB0C0H,0F9H,0A4H,0B0H,99H,92H;共阳极LED段码表
DB82H,0F8H,80H,90H,88H,83H
DB0C6H,0A1H,86H,8EH,8CH,0C1H
DB0CEH,91H,89H,0C7H,0FFH
4.整点报时模块
A.硬件设置:
8031的P1.7连接蜂鸣器
B.软件设计:
这段程序用于实现整点报时,在分的十位达到6也就是达到60分的时候就调用这个程序,并由22H单元传递鸣响的次数(比如说12点的时候就鸣响12下)。
输入一个高电平,一个低电平再在其中加如延时就可以使得蜂鸣器鸣响了。
程序段如下:
SOUND:
MOVR6,#0FH
LOOP:
MOVR7,#0FFH
SETBP1.7;P1.7输出高电平,蜂鸣器开始鸣叫
LOOP1:
DJNZR7,LOOP1;延时
CLRP1.7;P1.7输出高电平,蜂鸣器停止鸣叫
DJNZR6,LOOP;延时
LCALLDL4ms;调用延时子程序
LCALLDL4ms;调用延时子程序
DJNZ22H,SOUND;鸣响的次数是否与时间相等,是则返回,否则继续
RET
5.主程序模块
这一段程序主要是对内存单元进行初始化并开中断。
四.调试数据与运行结果分析
⒈连接,编译,调试,运行程序,最初显示器上显示000000,然后时间秒钟不断增加:
000001,000002,000003……;
⒉按下脉冲,显示器上显示的时间停止增加,可以从键盘上输入时间125958,两秒钟之后时间变成为130000,蜂鸣器鸣响13下。
五.程序说明
1.本设计用了两个中断,一个是内部定时/计数器T0中断,中断入口000BH,一个是跳沿触发外部中断INT0,中断入口0003H,因为同时中断时外部中断INT0的优先级比内部定时/计数T0中断要高,所以当外部负脉冲输入时内部时钟计时就被打断,执行键盘输入程序,键盘输入完成以后负脉冲中断被硬件自动清除,继续时钟计数;
2.本设计共有四个模块,分别是键盘模块,实时钟模块,显示模块以及整点报时模块。
这四个模块基本上是相对独立的,相互之间通过七个内存单元传递参数,六个单元40H—45H作为显示缓冲区传递显示数据,另外22H用于传递整点报时时候的时间。
3.本设计中有三个延时程序DL1ms,DL6ms,DL4ms,分别用于显示,键盘扫描以及蜂鸣三个程序段里面,因为这三段程序对延时的要求有所不同,显示程序里面每次点亮一个LED显示器都只占用1毫秒的时间,如果键盘扫描中延时也这么短的话按键输入的时候显示器就会闪个不停,而蜂鸣对延时的要求更苛刻一点,太短的话多次蜂鸣会合到一处去,人耳分不清响了几下,而且声音也会很小,所以这三段延时程序中蜂鸣所用的延时程序DL4ms是延时最长的。
4.这个程序用到的硬件主要是8031,8155,8759键盘,6位LED显示器,之间的连接方式在硬件图中有所描述。
六.软件程序框图
1.显示子程序流程图
是
否
2.键盘子程序流程图
否
是
是
否
否
是
3.整点报时子程序流程图
否
是
4.
实时钟子程序流程图
否
是
否
是
否
是否
是
否
否
否
是
是
七.附录
本设计中用到接口器件地址安排:
8155控制口:
FF20H8155A口(字位):
FF21H
8155B口(字型):
FF22H8155C口(键扫):
FF23H
八.参考文献
《单片机原理及应用》高等教育出版社,张毅刚主编,彭喜元,董继成副主编
九.附录源代码
ORG0000H;程序起始地址
AJMPMAIN;上电,跳向主程序
ORG0003H;外部中断INT0的中断入口
AJMPINTL;执行外部中断程序,键盘输入
ORG000BH;内部中断T0的中断入口
AJMPIT0P;执行内部中断,时钟计时
MAIN:
MOVSP,#60H;设堆栈指针
MOVTMOD,#01H;设T0为方式1
MOV20H,#0AH;装入中断次数到20H
MOVR1,#45H;键盘输入送入到缓冲区45H开始
MOV21H,#06H;每次键盘输入6个数据就结束依次输入
CLRA;寄存器A清0
MOV40H,A;把40H—45H六个显示单元清0
MOV41H,A
MOV42H,A
MOV43H,A
MOV44H,A
MOV45H,A
MOV22H,A;用于传递小时数目的内存单元22H清0
SETBET0;允许T0申请中断
SETBEX0;允许外部中断INT0申请中断
SETBIT0;外部中断INT0设置为跳沿触发
SETBEA;CPU开中断
MOVTH0,#3CH;给T0装入计数初值
MOVTL0,#0B0H
SETBTR0;启动T0
HERE:
ACALLDIR;等待中断的时候调用显示
SJMPHERE;等待中断
IT0P:
PUSHPSW;保存现场
PUSHACC
MOVTH0,#3CH;装入初值
MOVTL0,#0B0H
DJNZ20H,RETURN;1秒未到,返回
MOV20H,#0AH;重置中断次数
MOVA,#01H
ADDA,40H
MOV40H,A;秒单元个位加1
CJNEA,#0AH,RETURN;是否到10,是则进位,否则返回
MOV40H,#00H;进位,秒的个位清0
MOVA,#01H
ADDA,41H
MOV41H,A;秒的十位加1
CJNEA,#6,RETURN;是否到60秒,是则进位,否则返回
MOV41H,#00H;进位,秒的十位清0
MOVA,#01H
ADDA,42H
MOV42H,A;分的个位加1
CJNEA,#0AH,RETURN;是否到10,是则进位,否则返回
MOV42H,#00H;进位,分的个位清0
MOVA,#01H
ADDA,43H
MOV43H,A;分的十位加1
CJNEA,#6,RETURN;是否到60分,是则进位,否则返回
MOV43H,#00H;进位,时的个位清0
MOVA,#01H
ADDA,44H;十的个位数字加1后传给寄存器A
PUSHACC;保存加1后的小时个位
MOVA,B
PUSHACC;保存寄存器B的内容
MOVB,45H
MOVA,#0AH
MULAB;计算小时的个数,传给内存单元22H,以便整点报时
ADDA,44H
MOV22H,A
INC22H
POPACC
MOVB,A;A,B寄存器复原
ACALLSOUND;调用整点报时子程序
MOVA,45H
CJNEA,#02H,L1;判断时的十位数字是否已经加到2
POPACC
MOV44H,A;将时的个位加1
CJNEA,#4,RETURN;判断是否已经到24小时,不是则返回
MOV44H,#00H
MOV45H,#00H;已经到24小时,时的两个内存单元清0
RETURN:
POPACC
POPPSW;恢复现场
RETI;中断返回
L1:
POPACC;时的个位没有到2的情况处理
MOV44H,A;时的个位加1
CJNEA,#0AH,RETURN;是否到10,是则进位,否则返回
MOV44H,#00H;进位,时的个位清0
MOVA,#01H;时的十位加1
ADDA,45H
MOV45H,A
RET;返回
INTL:
ACALLDIR;显示
ACALLKEYI;调用键盘扫描
ACALLIN;将键码换算成数字
DJNZ21H,INTL;到六次否?
没有,继续;达到六次,中断返回
RETI
KEYI:
ACALLKS1;判断是否有键闭合
JNZLK1;有键闭合,判断是否因抖动引起
NI:
ACALLDIR;没有键闭合,在等待中显示
AJMPKEYI;跳回到上一步去,判断有无键被按下
LK1:
ACALLDL6ms;延时去抖动
ACALLDL6ms;延时去抖动
ACALLKS1;再次判断是否有键闭合
JNZLK2;确实有键闭合,执行下一步,判断键号
ACALLDL6ms;延时
AJMPKEYI;低电平由抖动引起,跳回上一步
LK2:
MOVR2,#0FEH;列选码0FEH送到R2
MOVR4,#00H;R4里保存列号
LK4:
MOVDPTR,#0FF21H;8155PA口
MOVA,R2
MOVX@DPTR,A;列选码送入到8155PA口
INCDPTR
INCDPTR;8155PC口
MOVXA,@DPTR;读8155