微机原理课程设计8253定时中断时钟Word文档格式.docx
《微机原理课程设计8253定时中断时钟Word文档格式.docx》由会员分享,可在线阅读,更多相关《微机原理课程设计8253定时中断时钟Word文档格式.docx(14页珍藏版)》请在冰豆网上搜索。
年-月-日时:
分:
秒。
要求采用8253定时器中断方式实现定时及显示刷新。
2.课程设计的要求
通过对微机系统分析和具体设计,使学生对所学课程的理解。
培养分析能问题,解决问题的能力。
要求学生掌握汇编语言程序设计的基本方法,学会典型接口的基本设计方法
二、设计正文
1.基本原理
获取系统时间与日期的方式有两种,比较简单的途径是直接用DOS时间与日期功能调。
比如:
向量号为21,功能号为2A,可以调出系统的时间,分别存放在DX和CX之中;
向量号为21,功能号为2C可以调出系统的日期,年月日信息存储在DX和CX中;
向量号为1A,功能号为02,也可以调用系统时间,同样存放在DX和CX中,不过是以压缩BCD码的形式存放的;
向量号为1A,功能号为04可以调出系统的日期,以BCD码的形式存放在DX和CX中。
编程的时候就会发现,后者比前者使用起来方便很多,因为显示的时候要用到ASC码,压缩BCD码可以通过与30H相加,便可以得到相应的ASC码。
而前者存储方式十六进制的,所以必须先转换成BCD码,在转换成ASC码,而十六进制与BCD码之间的转换比较复杂。
2.代码示例
用1A向量实现,程序代码如下:
MOVAH,02H
INT1AH
PUSHDX
PUSHCX
MOVAH,04H
PUSHCX
这段代码执行后,查看堆栈得:
1420020117170752,时间为:
2014年1月2日17点17分52秒
用21号向量实现,程序代码如下:
MOVAH,2CH
INT21H
MOVAH,2AH
代码执行后,查看堆栈得:
DE07020117114016,当前系统时间用16进制表示的,换算之后,可以得到:
2014年1月2日17点23分22秒
另一种方式就是题目所要求的,利用8253的55MS中断产生定时,不过仍然需要读一次系统的时间,作为计时开始的基准。
8253每过50MS,就会申请一次中断,向量号为1C。
通过修改这个中断向量,使其指向自己编写的中断服务程序入口。
通过计算中断的次数,便可以得到从计时开始到当前时刻的时间。
程序的数据段定义如下:
DATASSEGMENT
COUNTDB0
TEMPDB3DUP(0)
TIMEDW0,'
:
'
0,'
$'
DATEDW0,0,'
-'
INT_SEGDW?
INT_OFFDW?
DATASENDS
每次进入中断服务程序,COUNT加一,加到18的时候,便可以计为一秒。
TEMP用来存放当前时刻的压缩BCD码,比如:
18:
37:
50,则TEMP中存放18H,37H,50H。
由于显示的时候,必须用ASC码,所以TEMP中的数据不能直接用于显示,需通过下面的TRANSPROC进行转换:
TRANSPROC;
BCD-ASC码转化,入口AL,出口AX
MOVBL,AL
MOVBH,AL
MOVCL,4
SHRBL,CL
ADDBL,30H
ANDBH,0FH
ADDBH,30H
MOVAX,BX
POPDX
POPCX
RET
TRANSENDP
此过程的入口参数为AL,用来存放时刻的压缩BCD码,出口为AX,存放的是转化后的ASC码形式。
压缩BCD码18H,转换之后为3138H,就可以直接用来显示。
转换思想为:
取前四位=01H,加上30H,得到31H,同样取出后四位=08H,加上30H,得到38H。
转化之后的结果存入TIME中,用来显示,转换过程的代码如下:
MOVSI,OFFSETTEMP
MOVDI,OFFSETTIME
MOVAL,[SI]
CALLTRANS
MOV[DI],AX
MOVAL,[SI+1]
MOV[DI+4],AX
MOVAL,[SI+2]
MOV[DI+8],AX;
将时间的ASC码送入TIME
中断向量的修改通过下面代码实现:
MOVAX,351CH
MOVAX,ES
MOVINT_SEG,AX
MOVINT_OFF,BX;
保存原中断向量
CLI
MOVAX,251CH
MOVDX,SEGINT_PRO
MOVDS,DX
MOVDX,OFFSETINT_PRO
INT21H;
设置新中断向量
STI
在修改之前需把原本的中断向量保存起来,以便程序运行结束后进行还原。
下面是中断服务程序:
INT_PROPROCFAR;
时间产生程序
PUSHAX
PUSHSI
CLI
MOVAX,DATAS
MOVDS,AX
MOVSI,OFFSETTEMP
INCCOUNT
CMPCOUNT,12H
JNZKK
MOVAL,0
MOVCOUNT,AL
MOVAL,[SI+2]
ADDAL,1
DAA
MOV[SI+2],AL;
修改秒
CMPAL,60H
JNZKK
MOV[SI+2],AL
MOVAL,[SI+1]
ADDAL,1
MOV[SI+1],AL;
修改分
CMPAX,60H
MOV[SI+1],AL
MOV[SI],AL;
修改小时
CMPAX,24H
MOVAX,0
MOV[SI],AL
KK:
POPSI
POPAX
STI
IRET
INT_PROENDP
中断服务程序最开始对COUNT加一,当加到18时清零并且秒加一,如果秒数变为60,清零并且分加一,当分计满60的时候,时加一,时满24时,清零。
最后用IRET返回。
程序的退出通过检测键盘是否输入ESC键,代码如下:
MOVAH,0BH
CMPAL,00
JNEAA;
看一看是否有按键输入
JMPGO
AA:
MOVAH,08H
CMPAL,1BH
JEQUIT;
如果有按键按下,检查是不是ESC,是的话就退出
JMPGO;
不是的话,继续执行
三、课程设计总结
通过3天的奋战,完成了课设,最大的感觉:
好幸福!
这些程序是我一步一步的查课本,查资料,还有不断的实验调试得出来的,当显示出稳定并且正确的时刻时,前所未有的成就感涌上心头!
最初,为了将16位的二进制表示的年份转换成BCD码,头疼了一天,一步一步的执行,一个一个的查看寄存器、查堆栈,最终惊奇的发现另一个中断向量1AH竟然可以调用出BCD码形式的日期,别提多兴奋!
以及,在之后建立过程的时候,由于忘了在末尾加上RET,发现程序总是莫名其妙的跳来跳去。
感慨:
有些东西想起来简单,做起来的时候很多细节是能够决定成败的!
后来呢,程序有了雏形,可以正确显示,却发现画面异常不稳,闪来闪去,于是有绞尽脑汁,想起来之前自己在编液晶显示驱动的时候,由于不停地刷屏导致闪屏的状况,发现这个程序的显示部分也有相同的状况,改变了一下GO的位置,画面终于稳定了!
所有的奋战凝结成一句话:
我爱微机!
四、参考文献
《新编16/32位微型计算机原理及应用(第四版)》,清华大学出版社,李继灿主编
附录
1.程序源码
DATASENDS
STACKSSEGMENT
FDDB50DUP(0)
STACKSENDS
CODESSEGMENT
ASSUMECS:
CODES,DS:
DATAS,SS:
STACKS
START:
CALLCLEAR
MOVAX,351CH
CALLMAIN;
进入主函数main
MOVAH,4CH
MAINPROC;
主函数
PUSHAX
PUSHSI
PUSHBX
PUSHDS
MOVDS,AX
INT1AH;
读取系统时间
MOVSI,OFFSETTEMP
MOV[SI],CH
MOV[SI+1],CL
MOV[SI+2],DH
MOVAH,04H
读取系统日期
MOVSI,OFFSETDATE
MOVAL,CH
MOV[SI],AX
MOVAL,CL
MOV[SI+2],AX
MOVAL,DH
MOV[SI+6],AX
MOVAL,DL
MOV[SI+10],AX
MOVAH,0
MOVAL,2
INT10H;
屏幕设置成80X25黑白文本方式
MOVCX,2000H
MOVAH,01H
隐藏光标
GO:
MOVBH,00H
MOVDL,50
MOVDH,1
INT10H
MOVAH,09H
MOVDX,OFFSETDATE
显示日期
MOVDL,69
移动光标到屏幕右上角
MOVAL,