微机接口课程设计电子钟实验 网络专业文档格式.docx
《微机接口课程设计电子钟实验 网络专业文档格式.docx》由会员分享,可在线阅读,更多相关《微机接口课程设计电子钟实验 网络专业文档格式.docx(21页珍藏版)》请在冰豆网上搜索。
![微机接口课程设计电子钟实验 网络专业文档格式.docx](https://file1.bdocx.com/fileroot1/2022-12/11/28e9c820-9539-4fd0-bcd9-15bc3bf217c7/28e9c820-9539-4fd0-bcd9-15bc3bf217c71.gif)
第11脚CLK是时钟输入脚,当该端输入一个上升沿,74HC273就会把数据输入端D0--D7的数据锁存住并输出,直到下一个上升沿的到来才会改变。
二、实验原理
1、通用并口模块原理图:
图
(1)由一片74HC245作为键盘的行扫描电路(键盘的列扫描信号由一片74HC273提供,如图2所示),74HC245的P0--P3已经分别接到4*3的小键盘的4行。
另外,这片74HC245的引脚和4*3小键盘行、列都有引出相应的接插口,所以也能另作它用,例如用74HC245来驱动发光二极管,或者与适当的输入输出器件(例如8255)相配合就可以进行键盘扫描实验。
该片74HC245的/G端引了出来(KEYCS0)作为它的片选信号端。
图
(1)
图
(2)中左边的74HC273实现数码管的段码驱动,右边的74HC273除了与图
(1)中的74HC245配合,作为键盘的行列扫描信号,来确定那个键被按下,还作为6个共阴数码管的位驱动。
该模块的6个共阴数码管的段引脚(分别是KEY模块的的a、b、c、d、e、f、g、dp)和位引脚(分别是KEY模块上的DS1、DS2、DS3、DS4、DS5、DS6)都引出来,如果用其它的驱动模块也可以控制数码管的显示。
因为这两片74HC273都只作为输出用,所以用一片74HC32对IOW和它们各自的片选信号进行逻辑与运算,仅当是写操作时才会选中它们,以此避免不该它们工作时它们却工作的情况发生:
在KEYCS1和IOW有效(低电平)的前提下,74HC32的输出第6脚有效,对应的就是控制位选的74HC273被选通。
在KEYCS2和IOW有效(低电平)的前提下,74HC32的输出第8脚有效,对应的就是控制段选的74HC273被选通。
图
(2)
2、数码管字型编码表:
从上面的原理图可以看出,本模块显示部分由6个共阴极数码管组成,并由两片74HC273分别对位选和段选进行控制,位选的选通端子为KEYCS1,段选的选通端子为KEYCS2,相应的数码管字型编码如表1所示。
三、实验示例:
(可参考随机的演示程序key.asm)
该示例程序不停的扫描键盘,当扫描到有键按下时就把该键的键值(即12个按键的排列顺序)送到数码管上显示。
硬件线路连接示例:
①数码管的6根位控制信号线DS1~DS6分别接至位选74HC273的输出Q0~Q5;
②译码地址输出端CS3接至KEYCS0;
③译码地址输出端CS4接至KEYCS1;
④译码地址输出端CS5接至KEYCS2;
GAL的输出(译码电路可看前面的地址译码电路部分):
x:
表示可以取任意值,这里取“0”
按照如上的硬件连线示例可得:
74HC245的地址340H;
段选锁存器的地址360H;
位选锁存器的地址380H;
下面是一个只有显示功能没有键盘扫描的小程序,可以参考一下:
.486
DATASEGMENTAT0USE16
ORG1000H
COUNTDB?
DATAENDS
CODESEGMENTUSE16
ASSUMECS:
CODE
ORG3000H
BEG:
JMPSTART
TABDB3FH,06H,5BH,4FH,66H,6DH,7DH,07H
DB7FH,6FH
DPORT1EQU380H
DPORT2EQU360H
START:
MOVAX,DATA
MOVDS,AX
MOVCL,6
KK:
MOVAL,CL
MOVBX,OFFSETTAB
XLATTAB
MOVDX,DPORT1
OUTDX,AL
NOP
MOVDX,DPORT2
MOVAL,0FFH
JMPKK
CODEENDS
ENDBEG
三、程序流程图
主程序
初始化各段寄存器及相关变量
初始化8255、8254、8259芯片
设置中断向量,开放8259中断屏蔽
开放处理器中断
中断服务程序
保护现场
判断时间是否不小于59分55秒
报时
扫描键盘
G键?
调用启停子程序
S键?
调用设置时间子程序
COUNT加1
COUNT=40?
修改时间,调用ADDONE子程序
COUNT清0
显示时间,调用显示时间子程序
结束中断(发EOI命令)
恢复现场
中断返回
四、实验源代码
.486p
DATASEGMENTAT0USE16
ORG1000H
HOURDW?
MINDW?
SECDW?
STDB?
COUNTDB?
DATAENDS
CODESEGMENTUSE16
ASSUMECS:
CODE,DS:
DATA
ORG1500H
BEG:
JMPSTART
TABDB3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH,00H;
0~F的共阴极七段译码表00H表示不显示任何东西
KEYCODDB0EEH,0DEH,0BEH,0EDH,0DDH,0BDH,0EBH,0DBH,0BBH,0E7H,0D7H,0B7H;
行列编码值
KEYVALDB0,1,2,3,4,5,6,7,8,9,0AH,0BH;
所有键的键面值
PORT1EQU340H;
数码管段选端口
PORT2EQU360H;
数码管位选端口,键盘矩阵的行列端口
START:
MOVEAX,60000000H
MOVCR0,EAX
MOVAX,DATA
MOVDS,AX
MOVHOUR,0203H;
小时分钟以及秒的初始化
MOVMIN,0509H
MOVSEC,0502H
LEABX,TAB
MOVST,0;
开始暂停标志位置0
MOVCOUNT,0;
中断次数计数初始值为0
;
8255初始化,用于产生报时的脉冲
MOVDX,20FH;
利用左四的8255,控制口为20FH
MOVAL,10000000B;
C口输出
OUTDX,AL
MOVDX,20BHL;
C0输出1,蜂鸣器不响
MOVAL,0FFH
OUTDX,AL
8254初始化,用于产生周期为25ms的中断
MOVAL,00110110B;
计数器0,先低后高,方式三,二进制
MOVDX,32cH;
写往控制口
MOVDX,320H;
计数器0写初值:
47KHz*25ms
MOVAX,1175
MOVAL,AH
8259初始化
CLI:
关中断
MOVDX,300H;
ICW1
MOVAL,00010011B
MOVDX,308H;
ICW2
MOVAL,08H;
IR0中断类型号为08H
OUTDX,AL
MOVAL,00000001B;
ICW4
MOVAL,0FEH;
IR0开屏蔽
OUTDX,AL
XORAX,AX;
装载中断向量
MOVES,AX
MOVDI,08H*4
MOVAX,OFFSETINTSR
MOVES:
[DI],AX
MOVAX,SEGINTSR
[DI+2],AX
STI;
开中断
JMP$
INTSRPROC;
CMPMIN,0509H;
比较当前时间是否在59分55秒~00分00秒之间
JLNEXT1
CMPSEC,0505H
MOVDX,20BH
MOVAL,00H;
蜂鸣器低有效,报时
JMPNEXT2
NEXT1:
CMPMIN,0
JNENEXT3
CMPSEC,0
MOVDX,20BH
MOVAL,00H;
JMPNEXT2
NEXT3:
MOVDX,20BH
MOVAL,0FFH
NEXT2:
CMPCOUNT,20;
用8255产生0.5ms的蜂鸣
JLENEXT4
NEXT4:
CALLKEYCHECK;
检测有无键按下
CMPAL,0AH;
启停键按下,调用启停程序
JNZNEXT5
CALLTSTART
JMPNEXT6
NEXT5:
CMPAL,0BH;
设置键按下,调用设置时间程序
JNZNEXT6
CALLSETTIME
NEXT6:
INCCOUNT;
当COUNT直为40时,加一秒,之后置0
CMPCOUNT,40;
25ms*40=1s
JBNEXT7
CALLADDONE
MOVCOUNT,0
NEXT7:
CALLSHOW;
显示时间
MOVAL,20H;
发EOI命令,结束中断
MOVDX,300H
OUTDX,AL
IRET
INTSRENDP
TSTARTPROC;
控制暂停和开始
CMPST,00H
JNEL1
DECST
JMPL2
L1:
INCST
L0:
CALLKEYCHECK
CMPAL,0AH
JZL2
CALLSHOW
JMPL0
L2:
RET
TSTARTENDP
ADDONEPROC;
加1秒子程序
MOVAX,SEC;
当前秒个位为9,加1后变0,十位加1
CMPAL,9
JEN1
INCAL
MOVSEC,AX
JMPN6
N1:
INCAH
MOVAL,0
CMPAH,6;
十位加1后为6,则秒变为00,分钟个位加1
JEN2
MOVSEC,AX
JMPN6
N2:
MOVAX,0
MOVAX,MIN;
当前分钟个位为9,加1后变0,十位加1
CMPAL,9
JEN3
MOVMIN,AX
N3:
MOVAL,0
十位加1后为6,则分钟变为00,小时个位加1
JEN4
N4:
MOVAX,HOUR
CMPAX,0204H;
小时加1后与24比,相等,则变为0
JEN5
MOVHOUR,AX
JMPN6
N5:
N6:
ADDONEENDP
SETTIMEPROC;
设置时间子程序
MOVHOUR,0
MOVMIN,0
MOVSEC,0
NOP
L1:
调用KEYCHECK,无键按下时,AL中值为0CH
CALLDELAY
CMPAL,0CH
JNZL2
JMPL1
L2:
CMPAL,02H
JGL1;
设置小时十位时,将其他各位数码管灭掉及对应的七段译码表0CH
MOVAH,AL
MOVBYTEPTR[HOUR+1],AL
MOVBYTEPTR[HOUR],0CH
MOVMIN,0C0CH
MOVSEC,0C0CH
L3:
CALLSHOW
设置小时的个位
JZL3
MOVAH,BYTEPTR[HOUR+1]
L4:
CMPAX,0204H
JGEL1
L5:
CALLSHOW
设置分钟的十位
JZL5
L6:
CMPAL,06H
JGEL1
MOVBYTEPTR[MIN+1],AL
L7:
设置分钟的个位
JZL7
MOVAH,BYTEPTR[MIN+1]
L8:
CMPAX,0509H
JGL1
L9:
设置秒的十位
JZL9
L10:
CMPAL,06H
MOVBYTEPTR[SEC+1],AL
L11:
设置秒的个位
JZL11
MOVAH,BYTEPTR[SEC+1]
L12:
CMPAX,0509H
MOVSEC,AX
L13:
CALLSHOW
CALLKEYCHECK;
再次按键,启动计时
JZL13
RET
SETTIMEENDP
KEYCHECKPROC;
判断有无键按下子程序
PUSHBX
CALLCLEAR
MOVDX,PORT2
INAL,DX
ANDAL,0FH
CMPAL,0FH
JZEXIT;
有按键按下,延时消抖
NOP
NOP
再次确认是否有键按下
INAL,DX
CMPAL,0FH
JZEXIT
;
开始对每一列进行逐行扫描
MOVCX,3
MOVBL,0FEH
NEXT:
MOVAL,BL
MOVDX,PORT2
INAL,DX
ANDAL,0FH
JNZKEY
ROLBL,1
LOOPNEXT
JMPEXIT
KEY:
SHLBL,4
ORAL,BL;
形成一个字节的键码信息存入AL,高4位为列信息低4位为行信息
LEASI,KEYCOD
LEADI,KEYVAL
MOVCX,12
NEXT11:
CMPAL,[SI]
JZFIND
INCSI
INCDI
LOOPNEXT11
JMPEXIT
FIND:
MOVAL,[DI];
AL中内容为所按键的键面值
PUSHAX
WAIT1:
INAL,DX;
判断按键是否已释放,若无则等待
CMPAL,0FH
JNZWAIT1
POPAX
JMPEXIT2
EXIT:
MOVAL,0CH
EXIT2:
NOP
POPBX
KEYCHECKENDP
SHOWPROC;
XLAT
MOVDX,PORT1;
段选输出数据
MOVDX,PORT2;
位选输出小时的个位
MOVAL,0C2H
CALLCLEAR
MOVAL,AH
位选输出小时的十位
MOVAL,0C1H
CALLDELAY
MOVAX,MIN
位选输出分钟的个位
MOVAL,0C8H
MOVAL,AH
位选输出分钟的十位
MOVAL,0C4H
MOVAX,SEC
位选输出秒的个位
MOVAL,0E0h
XLAT
位选输出秒的十位
MOVAL,0D0H
SHOWENDP
CODEENDS
ENDBEG
DELAYPROC;
延时子程序
PUSHCX
MOVCX,1000
LOOP$
POPCX
DELAYENDP
CLEARPROC;
使七段译码管全灭子程序
MOVAL,00H
MOVDX,PORT1
MOVDX,PORT2
CLEARENDP
五、总结
为期不到一周的微机接口课程设计结束了,在这几天中,经过自身的努力,可以算得上是比较成功的完成了实验,但仍有不足之处。
首先先谈谈这几天的收获。
第一天定下了课设的题目,紧接着理清思路,明白实验大概的流程,并根据流程着手写相关的代码。
第二天基本任务还是完善代码,并上机编译修改错误,由于当天时间较紧,虽然硬件已经连接,但是仍有错误,无法正常运行,主要是因为中断服务程序无法进入,导致不能正常计时。
第三天根据前一天的错误,找到问题所在:
8259的一排端口无法正常使用,换了一排,就有结果,但是还是有许多问题。
首先就是在设置时间时,数码管会变暗,因此,我增加了DELAY延时,结果正确,然而又出现了新的问题,也是在设置时间时,当我设置小时的十位的时候,个位也会出现数据,不过是乱码,经过老师的指导,才发现在SETTIME时,并没有清掉端口的值导致错误,经过修正后,结果正确。
剩下的就是程序上有些小错误,比如说分钟以及秒的设置上,十位均要小于6,在这点上出现了问题等。
这次课程设计,虽说时间不是很长,但我仍感觉到收获颇丰。
首我的先编程能力得到了很大的提高,因为在之前的上机实验中,并没有像此次课设那样,要将多个芯片联合使用,这次的课设,使我懂得了设计程序的全局观念,并增强自身的纠错能力。
这次课设将我平时所学的理论知识与实践充分结合的,让我更加深刻的了解了各芯片的工作原理,总之,这次的课设让我获益匪浅。