实验一设计数码管电子表.docx
- 文档编号:9837246
- 上传时间:2023-05-21
- 格式:DOCX
- 页数:40
- 大小:197.82KB
实验一设计数码管电子表.docx
《实验一设计数码管电子表.docx》由会员分享,可在线阅读,更多相关《实验一设计数码管电子表.docx(40页珍藏版)》请在冰点文库上搜索。
实验一设计数码管电子表
实验一设计数码管电子表
一.实验要求:
使用8253的两个计数器串连,作为微机系统的外扩定时源,以数码管电路作为外扩输出设备,采用中断方式编程,实现数码管电子表“具体要求如下:
1.六位数码管分别显示时,分,秒。
2.初始时间由主机键盘输入。
3.主机按任意键停止计时返回DOS。
二:
实验电路
+5v
与计算机数据线相连
208H-20FH接B4端子
a(+5v)
A1q2b(8Mhz)
A0
IOR
IOW
8253
CS200H-207H
(*注意:
A1,a0用来选择8253内部三个计数器中的一个,它们分别与计算机地址线的低两位相连。
RD,WR用来控制8253的读写,它们分别与计算机的IOR,IOW相连)
电路分析:
从Q2出来的时钟频率为1MHz,为实现一秒钟调用一次中断,必须要每1000000次时钟调用一次中断。
我们同时将计数器0和计数器1的初值都设为1000,并将计数器0的输出OUT0作为计数器1的时钟,并将计数器1的输出OUT1连到B4端子上,这样就实现了每1000×1000=1000000次时钟调用一次中断。
三.8253控制字格式
d7d6d5d4d3d2d1d0
sc1
sc2
rl1
rl0
m2
m1
m0
bcd
四.程序清单:
TITLEDISPTIME
DSEGSEGMENT
INPUT_TIMDB'Pleaseinputthecurrenttime.',13,10,'$'
SHOW_TIMDB'Timeisasthefollow.PressCtr-Ctoexit.',13,10,'$'
BAD_DATADB'Digitsmushbebetween0and9',13,10,'$'
BAD_HRSDB'Hourmustbebetween0and23',13,10,'$'
BAD_MINSDB'Minutesmushbebetween0and59',13,10,'$'
BAD_SECSDB'Secondsmushbebetween0and59',13,10,'$'
CRLFDB13,10,'$'
ASK_HRSDB'Hour(0-23):
$'
ASK_MINSDB'Minute(0-59):
$'
ASK_SECSDB'Second(0-59):
$'
USERDB3,3DUP(?
)
TIMEDB3DUP(?
)
COUNTDW1
OLD0ADD?
TABLEDB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,39H,5EH,79H,71H
DSEGENDS
SSEGSEGMENTSTACK'STACK'
DB256DUP(?
)
SSEGENDS
CSEGSEGMENT
ASSUMECS:
CSEG,SS:
SSEG,DS:
DSEG,ES:
DSEG
STARTPROCFAR
MOVAX,DSEG
MOVDS,AX
CALLGET_TIME
CLI
CALLI8253(初始化8253)
CALLI8259(初始化8259)
CALLRD0A
(读入原0A中断向量)
CALLWR0A(写入新中断向量)
ROTATE:
CALLDISPLAY(只要不按键,就不断调用DISPLAY显示TIME变量中的时间)
MOVAH,1
INT16H
JZROTATE
(按键输入后退出。
)
CALLRESET
MOVAH,4CH
INT21H
RET
STARTENDP
;************************************
(SERVICE为新的中断程序)
SERVICEPROCNEAR
PUSHAX
PUSHDS
MOVAX,DSEG
MOVDS,AX
CALLCHANGE_TIME
(函数CHANGE_TIME用以将时间增加一秒)
MOVAL,20H
OUT20H,AL(送应答信号)
POPDS
POPAX
IRET
SERVICEENDP
;************************************
(此函数将保存在TIME变量中的时间显示在数码管上。
)
DISPLAYPROCNEAR
PUSHAX
PUSHBX
PUSHCX
PUSHDX
PUSHSI
MOVSI,OFFSETTIME
MOVBX,OFFSETTABLE
MOVCL,4
MOVAL,[SI]
MOVAH,AL
SARAL,CL
ANDAH,00001111B
XLAT
MOVDX,201H
OUTDX,AL
MOVDX,200H
MOVAL,01H
OUTDX,AL
MOVAL,0
OUTDX,AL
MOVAL,AH
XLAT
MOVDX,201H
OUTDX,AL
MOVDX,200H
MOVAL,02H
OUTDX,AL
MOVAL,0
OUTDX,AL
MOVAL,[SI+1]
MOVAH,AL
SARAL,CL
ANDAH,00001111B
XLAT
MOVDX,201H
OUTDX,AL
MOVDX,200H
MOVAL,04H
OUTDX,AL
MOVAL,0
OUTDX,AL
MOVAL,AH
XLAT
MOVDX,201H
OUTDX,AL
MOVDX,200H
MOVAL,08H
OUTDX,AL
MOVAL,0
OUTDX,AL
MOVAL,[SI+2]
MOVAH,AL
SARAL,CL
ANDAH,00001111B
XLAT
MOVDX,201H
OUTDX,AL
MOVDX,200H
MOVAL,10H
OUTDX,AL
MOVAL,0
OUTDX,AL
MOVAL,AH
XLAT
MOVDX,201H
OUTDX,AL
MOVDX,200H
MOVAL,20H
OUTDX,AL
MOVAL,0
OUTDX,AL
POPSI
POPDX
POPCX
POPBX
POPAX
RET
DISPLAYENDP
;************************************
I8253PROCNEAR
MOVAL,00110100B
MOVDX,20BH
OUTDX,AL
(设定8253的计算器0,写入时先低字节后高字节,方式2,二进制计数)
MOVAX,1000
MOVDX,208H
OUTDX,AL
MOVAL,AH
OUTDX,AL
(计数器0的初值设为1000。
)
MOVAL,01110100B
MOVDX,20BH
OUTDX,AL
(设定8253的计算器1,入时先低字节后高字节,方式2,二进制计数)
MOVAX,1000
MOVDX,209H
OUTDX,AL
MOVAL,AH
OUTDX,AL
(计数器1初值设为1000。
)
RET
I8253ENDP
;**********************************
I8259PROCNEAR
INAL,21H
ANDAL,11111011B
OUT21H,AL
INAL,0A1H
ANDAL,11111101B
OUT0A1H,AL
RET
I8259ENDP
;********************************
RD0APROCNEAR
MOVAX,350AH
INT21H
MOVWORDPTROLD0A,BX
MOVWORDPTROLD0A+2,ES
RET
RD0AENDP
WR0APROCNEAR
PUSHDS
MOVAX,CSEG
MOVDS,AX
MOVDX,OFFSETSERVICE
MOVAX,250AH
INT21H
POPDS
RET
WR0AENDP
;********************************
RESETPROCNEAR
MOVDX,WORDPTROLD0A
MOVDS,WORDPTROLD0A+2
MOVAX,250AH
INT21H(恢复原来的中断向量)
INAL,0A1H
ORAL,00000010B
OUT0A1H,AL(屏蔽用户中断)
RET
RESETENDP
;***********************************
(函数GET_TIME的作用是接受用户输入的时间,并把它保存在6字节变量TIME中。
为了保证程序的严谨,如果输入的时间非法,则显示出错信息并要求重输。
)
GET_TIMEPROCNEAR
LEADX,INPUT_TIM
MOVAH,9
INT21H(提示输入时间)
HOUR:
LEADX,ASK_HRS
MOVAH,9
INT21H(提示输入小时)
CALLINPUT_TIME
(函数INPUT_TIME的功能是把用户输入的字符转化为时间值并存放在BL中如果输入的不是数字,那么让标志寄存器CF=1)
JCHOUR(输入不是数字,重输)
CMPBL,23H
JNAHRS2
(如果输入的数字比24小,那么跳到HRS2去执行下面的内容;如果输入的数字大于等于24,那么要求重输。
对于分,秒的输入也按照此法处理。
)
LEADX,BAD_HRS
MOVAH,9
INT21H
JMPHOUR
HRS2:
PUSHBX
MIN:
LEADX,ASK_MINS
MOVAH,9
INT21H
CALLINPUT_TIME
JCMIN
CMPBL,59H
JNAMIN2
LEADX,BAD_MINS
MOVAH,9
INT21H
JMPMIN
MIN2:
PUSHBX
SEC:
LEADX,ASK_SECS
MOVAH,9
INT21H
CALLINPUT_TIME
JCSEC
CMPBL,59H
JNASEC2
LEADX,BAD_SECS
MOVAH,9
INT21H
JMPSEC
(以下程序段将输入的的时间保存在TIME变量中)
SEC2:
MOVSI,OFFSETTIME
MOV[SI+2],BL
POPBX
MOV[SI+1],BL
POPBX
MOV[SI],BL
RET
GET_TIMEENDP
;************************************
(函数INPUT_TIME的功能是把用户输入的字符转化为时间值并存放在BL中;如果输入的不是数字,那么让标志寄存器CF=1)
INPUT_TIMEPROCNEAR
LEADX,USER
MOVAH,0AH
INT21H
LEADX,CRLF
MOVAH,9
INT21H
CMPUSER+1,1
JAECONVERT
MOVBL,0
RET
CONVERT:
MOVCL,4
MOVAL,USER+2
CALLCHECK
JCLEAVE
ANDAL,0FH
MOVBL,AL
CMPUSER+1,2
JBCLR_CF
SHLBL,CL
MOVAL,USER+3
CALLCHECK
JCLEAVE
ANDAL,0FH
ORBL,AL
CLR_CF:
CLC
LEAVE:
RET
INPUT_TIMEENDP
;***********************************
CHECKPROCNEAR
CMPAL,'0'
JBERROR
CMPAL,'9'
JAERROR
CLC
RET
ERROR:
LEADX,BAD_DATA
MOVAH,9
INT21H
STC
RET
CHECKENDP
;***********************************
(此函数将保存在TIME变量中的时间增加一秒)
CHANGE_TIMEPROCNEAR
PUSHAX
PUSHCX
PUSHDX
PUSHSI
MOVSI,OFFSETTIME
MOVAL,[SI]
MOVCH,AL
MOVAL,[SI+1]
MOVCL,AL
MOVAL,[SI+2]
MOVDH,AL
(CH:
CL:
DH=时:
分:
秒)
MOVAL,DH
ADDAL,1
DAA
MOVDH,AL
CMPDH,60H
JNEEXITCHG
MOVDH,0
MOVAL,CL
ADDAL,1
DAA
MOVCL,AL
CMPCL,60H
JNEEXITCHG
MOVCL,0
MOVAL,CH
ADDAL,1
DAA
MOVCH,AL
CMPCH,24H
JNEEXITCHG
MOVCH,0
EXITCHG:
MOVSI,OFFSETTIME
MOV[SI],CH
MOV[SI+1],CL
MOV[SI+2],DH
POPSI
POPDX
POPCX
POPAX
RET
CHANGE_TIMEENDP
CSEGENDS
ENDSTART
五.实验总结:
1.由于与本实验相关的程序上学期编过(在屏幕上显示时间),所以这次实验我的程序中的主要部分是用的以前的,添加了将时间显示在数码管上的程序。
上学期编的那个程序中,我用三个字节来存储时分秒,这次仍然沿用这个习惯。
但这个习惯使我在编将时间显示在数码管上的子程序(DISPLAY)的时候遇到了困难,因为一个字节代表的是数码管上的两个位置,所以编查表程序时必须把那个字节的信息拆分为两个字节再进行查表,这使程序繁琐,可读性降低。
如果用六个字节分别存储时的十位,时的个位,分的十位,分的个位,秒的十位,秒的个位,那么在编显示程序时确实方便了许多,但是在编改变时间的程序时却会更复杂一些。
因此这两种方法各有利弊。
2.在程序的结束RESET函数中一定要屏蔽用户中断,否则下一次调用程序时就不会响应中断,这个问题让我耗费了很多时间。
实验二:
小键盘按键识别
一.实验要求:
本次实验的要求与前一实验类似,但仅要求识别小键盘0~9数字键,将小键盘键入的任意长的0~9数字串,采用左移位动态显示的方法显示在数码管电路上,当小键盘按下”R”时停止演示.
二.程序框图:
Y无键闭合
N:
AH为闭合键“列值”
Y
三.实验电路图:
四.8255方式选择控制字
1
D6
D5
D4
D3
D2
D1
D0
五.源程序:
TITLELITTLEKEYBOARD
SSEGSEGMENTPARASTACK'STACK'
DB256DUP(0)
SSEGENDS
DSEGSEGMENT
A_8255EQU210H
B_8255EQU211H
CON_8255EQU213H
BUFFERDB6DUP(0)
HANGDB?
LIEDB?
NEWHANGDB?
NEWLIEDB?
TABLEDB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,
DSEGENDS
CSEGSEGMENT
ASSUMECS:
CSEG,DS:
DSEG,SS:
SSEG
STARTPROCNEAR
MOVAX,DSEG
MOVDS,AX
CALLCLOSEALL
(关掉数码管,防止因为最初数码管有显示而使程序执行不正常。
)
CMPAGAIN:
CALLDISPLAY
(DISPLAY函数用来将BUFFER中的键值显示在数码管上。
)
MOVDX,CON_8255
MOVAL,10000010B
OUTDX,AL
(设定A口方式0输出,B口方式0输入)
AGAIN:
CALLDISPLAY
MOVDX,A_8255
MOVAL,0
OUTDX,AL(0->PA7---PA0)
MOVDX,B_8255
INAL,DX
ANDAL,00000111B(取出PB0-PB2
CMPAL,00000111B
JEAGAIN
MOVLIE,AL(将列值保存)
CALLDELAY1(延时20ms)
MOVDX,CON_8255
MOVAL,10010000B
OUTDX,AL
(预置A口方式0输入,B口方式0输入)
MOVDX,A_8255
INAL,DX
MOVHANG,AL(将行值保存)
CALLGETINPUT
(GETINPUT函数通过行值和列值查出输入的键值,并将它保存在AL中,如果输入是R,则AL赋值为FFH;如果输入非法字符,则AL赋值为0AH。
)
CMPAL,0AH
JECMPAGAIN
(如果是非法字符则跳回)
CMPAL,0FFH
JNECONTINUE
(如果是R则退出程序.)
CALLCLOSEALL
MOVAH,4CH
INT21H
CONTINUE:
CALLCHANGE
(CHANGE函数用来改变BUFFER中保存的键值)
MOVDX,CON_8255
MOVAL,10000010B
OUTDX,AL
(设定A口方式0输出,B口方式0输入)
LLL:
CALLDISPLAY
MOVDX,B_8255
INAL,DX
ANDAL,00000111B
(取出PB0-PB2)
CMPAL,00000111B
JNELLL
JMPCMPAGAIN
(不断扫描,如果不松开按键,那么就循环等待;直到按键松开就跳回。
)
RET
STARTENDP
;*********************************
(此函数用以延时20MS)
DELAY1PROCNEAR
PUSHAX
PUSHCX
PUSHDX
MOVAH,86H
MOVCX,0
MOVDX,20000
INT15H
POPDX
POPCX
POPAX
RET
DELAY1ENDP
;********************************
(GETINPUT函数通过行值和列值查出输入的键值,并将它保存在AL中,如果输入是R,则AL赋值为FFH;如果输入非法字符,则AL赋值为0AH。
)
GETINPUTPROCNEAR
CMPLIE,00000110B
JELIE0
CMPLIE,00000101B
JELIE1
CMPLIE,00000011B
JELIE2
MOVAL,0AH
RET
LIE2:
CMPHANG,00010000B
JENEXT
MOVAL,0AH
RET
NEXT:
MOVAL,0FFH
RET
LIE0:
CMPHANG,01111111B
JEKEY8
CMPHANG,10111111B
JEKEY9
MOVAL,0AH
RET
KEY8:
MOVAL,8
RET
KEY9:
MOVAL,9
RET
LIE1:
CMPHANG,01111111B
JEKEY0
CMPHANG,10111111B
JEKEY1
CMPHANG,11011111B
JEKEY2
CMPHANG,11101111B
JEKEY3
CMPHANG,11110111B
JEKEY4
CMPHANG,11111011B
JEKEY5
CMPHANG,11111101B
JEKEY6
CMPHANG,11111110B
JEKEY7
MOVAL,0AH
RET
KEY0:
MOVAL,0
RET
KEY1:
MOVAL,1
RET
KEY2:
MOVAL,2
RET
KEY3:
MOVAL,3
RET
KEY4:
MOVAL,4
RET
KEY5:
MOVAL,5
RET
KEY6:
MOVAL,6
RET
KEY7:
MOVAL,7
RET
GETINPUTENDP
;**********************************
(CHANGE函数用来改变BUFFER中保存的键值,将BUFFER中的键值移位,最后一位加入AL中的新键值。
)
CHANGEPROCNEAR
PUSHAX
PUSHSI
MOVSI,OFFSETBUFFER
MOVAH,[SI+1]
MOV[SI],AH
MOVAH,[SI+2]
MOV[SI+1],AH
MOVAH,[SI+3]
MOV[SI+2],AH
MOVAH,[SI+4]
MOV[SI+3],AH
MOVAH,[SI+5]
MOV[SI+4],AH
MOV[SI+5],AL
POPSI
POPAX
RET
CHANGEENDP
;**********************************
(DISPLAY函数用来将BUFFER中的键值显示在数码管上。
)
DISPLAYPROCNEAR
PUSHAX
PUSHBX
PUSHCX
PUSHDX
PUSHSI
MOVBX,OFFSETTABLE
MOVSI,OFFSETBUFFER
MOVCL,1
XUNHUAN:
MOVAL,[SI
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 实验 设计 数码管 电子表