您好,欢迎来到画鸵萌宠网。
搜索
您的当前位置:首页【微机原理课程设计】电子钟的设计

【微机原理课程设计】电子钟的设计

来源:画鸵萌宠网
摘要

数字闹钟

1、通过8253定时器产生秒脉冲定时中断。在中断服务程序中实现秒、分、小时的进位(24小时制)。

2、将当前时分秒在七段LED显示器上显示(如:091132)。

3、可设置闹钟的时间当前值(对准时间),设置闹铃时间,闹铃功能的关闭和开放.

关键词:数字闹钟,8253定时器,LED显示器,8255A并行口

目 录

1.实验线路 .................................................................................................................... 1 2.设计思想 .................................................................................................................... 2 3.功能流程图 ................................................................................................................ 4 4.结果讨论 .................................................................................................................... 8 5.源程序以及注释 ........................................................................................................ 9 参考文献 ...................................................................................................................... 26

- 1 -

1.实验线路

1

实验线路如图1所示。

2.设计思想

一、概述:

程序主体设计:本程序共有分端口设置模块,计数模块,显示模块等几个模块。

C--DISPLAY 12, 45, 37 ----将闹钟设置为12:45: 37; G--GO AHEAD----开中断,闹钟恢复走时 D--STOP TO DISPLAY-----关中断,闹钟停止走时 E--EXIT TO DOS----返回DOS

M--SET THE CLOCK -----设置闹铃时间 F--OPEN THE CLOCK-----设置闹钟功能为开 B--CLOSE THE CLOCK-----设置闹钟功能为关

P--POSITION THE BENINNING DATE------设置闹钟的时间 二、计时器软件的设计:

主程序中,要对各个用到的芯片进行初始化,目的是使其每20豪秒产生一次方波。8253A的定时器输出与8259A的IR2连接,计数器0工作在模式3(方波发生器),计数值采用二进制格式,输出作为计数器1的输入, 计数器1工作在模式2(分频器),计数值采用二进制格式,输出到总线IRQ2,向CPU发送时钟中断信号,根据两个计数器的设置,系统每隔20毫秒便由8253A产生一次中断请求,即每隔20豪秒执行一次中断处理程序。这个方法将与时间相关的两个模块即显示模块和计时模块放在中断处理程序中,这样,就保证了数字显示的稳定,中断处理程序完成计时功能要依靠两个方面,因为中断处理程序是每20豪秒执行一次,但计时并不是以20豪秒为单位进行的,而是以秒为单位进行的,所以,计时功能的实现一方面要利用20毫秒这个基准时间单位,另一方面借助一个计数单位。

图1 实验线路图

2

计数单位的初始值为50,每进行一次中断,便使计数单元的内容减1。每当计数单元从50减为0时,说明已经过了1秒时间。并判断是否有进位,如有则进行修改,实现进位。并在LED上显示。

显示部分:

本程序显示部分用了6个共阴极LED作为显示管,显示程序要做到每送一次段码就送一次位码,每送一次位码后,将位码中的0右移1位作为下次的位码,从而可以实现从左到右使6个LED依次显示出相应的数字。虽然CPU每隔一定时间便执行显示程序,但只要这个时间段不太长,由于人眼的视觉作用,就可以在6个LED上同时见到数字显示。

程序中,用8255A的PA口作为输出,输出扫描信号,PB口作为输入,读进列值。

本程序用行扫描法来识别键盘的闭合键。先使第0行接地,其余行为高电平,然后看第0行是否有键闭合,这是通过检查列线电位来实现的,即在第0行接地时看是否有哪条列线变成低电平。如果有某条列线变为低电平,则表示第0行和此列线位置上的键被按下如果没有,则说明第0行上没有键被按下。此后,再将第1行接地,然后检测列线中是否有变为低电平的线。如此往下逐行扫描,直到最后一行。为消除键的抖动,所以调用延迟程序,然后再判断具体按下的到底是哪个键,如果得到的是FFH,则程序在循环中等待。

计数部分:见流程图 时间设定模块

对于输入的检测,若超出范围,则对其置F------,

3

3.功能流程图

一、程序主流程控制图(如图2所示)

C键? N G键? N D键? N P键? N M键? N F键? N B键? N E键? Y 显示初始化时间 Y 开始计时 Y 停止计时 Y 设置时间 Y 设置闹铃 Y 开启闹铃 Y 关闭闹铃 Y 退出回到DOS N

图2 程序主流程控制图

4

二、中断服务子程序流程图(如图3所示)

中断进入 收到50次中断? 计数值减一(初值为50) Y 进位处理部分闹铃开? Y 闹铃时间到? Y 响铃 N N 退出中断服务

图3 中断服务子程序流程图

5

三、进位处理部分流程图(如图4所示)

6

开始 N 秒加1 秒钟是否到59(此部分的转换从略) Y 秒十位和各位赋值为0 0 N 分钟加1 分钟是否到59(此部分的转换从略) Y 分钟十位和各位赋值为0 0 N 小时加1 分钟是否到23(此部分的转换从略) Y 小时十位和各位赋值为0 0 闹铃判断响铃部分

图4进位处理部分流程图

7

4.结果讨论

本程序共有分端口设置模块,计数模块,显示模块等几个模块。经过调试,本程序可以实现题目的要求。时、分、秒都分两位。个位满十后就向前进一位。分秒的十位满六十后也向前进一位。显示小时两位在满二十四后重新计数。在置数时,使用者可置任意值,但如果有某位超过计数值,则在LED显示器上输出出错信息。程序中设置压C键为LED显示器清0,压E键为退出,压D键为计数暂停,压P键为设置LED显示器初始值。应该注意的是,程序中设定的键值为实验台上的小键盘的键值,并非计算机键盘。经测试,程序中设置的功能全都可以良好运行。

本程序参照实验室电脑中16BIT文件中的kl.asm编制 定时器/计数器8253计数初值的设定。

下面对几个重点部分的调试过程和遇到的问题作一定的讨论: 修改后的中断服务子程序(改变进位的条件)

(1)其中进位的条件判断以及后面的闹铃的程序段位置的设置都与程序结果有很大的关系.进位判断特别要注意仔细,编程实现前应该画个流程图,直接再源文件上改不但不能节省时间,反而更加浪费时间.

(2)此中断服务子程序的类型设置为FAR调用,这里要特别注意.因为相对于中断发生时的运行状态,此程序段与之不在同一代码段,所以应该定义为FAR类型.这样产生了另外一个问题,在此程序段中若想调用此CODE段中以他过程,则那个过程也应该被定义为FAR调用,当然可以简单的通过不使用过程调用解决.以解决此中断子程序过程和其他普通过程对对应过程的调用冲突.

8

5.源程序以及注释

;此程序实现数字闹钟的设定,闹铃时间得设定,闹铃功能的开关 ;试验硬件平台是TPC-1型试验培训系统 ;386以上微机适用 ;纯DOS下才能使用 ;TASM4.1或以上编译 ;*********************; ;* 键盘显示 8255LED *; ;*********************; IO_PLX_DEVICE_ID EQU 006H ;TPC卡设备ID IO_PLX_VENDOR_ID EQU 010B5H ;TPC卡厂商ID IO_PLX_SUB_ID EQU 09010B5H ;TPC卡子设备及厂商ID PA55 EQU 218H-200H ;8255端口地址 PB55 EQU 219H-200H P55CTL EQU 21BH-200H

PORTSEG EQU 211H-200H ;LED端口地址 PORTBIT EQU 210H-200H

TIM_CTL EQU 203H-200H ;8253端口地址 TIMER0 EQU 200H-200H TIMER1 EQU 201H-200H

MODE03 EQU 36H ;0011-0111 MODE12 EQU 74H ;0111-0101 DATA SEGMENT CSREG DW ?

IPREG DW ? ;旧中断向量保存空间 IO_90BASE_ADDRESS DB 4 DUP(0) ;TPC卡PCI接口芯片I/O基地址暂存空间 IO_BASE_ADDRESS DB 4 DUP(0) ;TPC卡I/O基地址暂存空间 INTERRUPT_LINE DB 2 DUP(0) ;TPC卡中断号暂存空间 PCICARDNOTFIND DB 0DH,0AH,'TPC PCI CARD NOT FIND OR ADDRESS/INTERRUPT ERROR !!!',0DH,0AH,'$'

IO90BASEADDRESS DB 0DH,0AH,'TPC PCI CARD 90 CHIP I/O BASE ADDRESS : ','$' IOBASEADDRESS DB 0DH,0AH,'TPC PCI CARD I/O BASE ADDRESS : ','$' INTNUMBER DB 0DH,0AH,'TPC PCI CARD INTERRUPT LINE : ','$' ENTER_RETURN DB 0DH,0AH,'$'

MESS DB '8253A TIMER0 IN MODE3! COUNT=0200H',0AH,0DH DB '8253A TIMER1 IN MODE2! COUNT=0AH',0AH,0DH,'$' MESS1 DB 'I AM RINGING',0AH,0DH,'$' IRQ_VECT DB 08H,09H,0AH,0BH,0CH,0DH,0EH,0FH,70H,71H,72H,73H,74H,75H,76H,77H ;新的中断向量,中断0-7的向量为:08H-0FH,中断8-15的向量为:70H-77H IRQ_MASK_0_7_TABLE DB 011111110B,011111101B,011111011B,011110111B DB 011101111B,011011111B,010111111B,001111111B DB 011111011B,011111011B,011111011B,011111011B

9

DB 011111011B,011111011B,011111011B,011111011B ;新的中断掩码,中断0-7时从低至高相应位为零,中断8-15时第2位为零 IRQ_MASK_8_15_TABLE DB 0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH,0FFH DB 011111110B,011111101B,011111011B,011110111B DB 011101111B,011011111B,010111111B,001111111B ;新的中断掩码,中断0-7时全一,中断8-15时从低至高相应位为零 COUNT DB 15

CTIME DB 00H,00H,00H,00H,00H,00H CLOCK DB 0AH,0AH,0AH,0AH,0AH,0AH BUF DB 00H,00H,00H,00H,00H,00H;***************** MYBELL DB 00H ;***********OFF***INITIALIZE MONTH3 DB 0 DAY3 DB 0 CHAR1 DB ? INTMASK DB ? CONST1 DW ?

LED DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,40H,79H,00H TABLE1 DW 0101H,0201H,0401H,0801H,1001H,2001H,4001H,8001H DW 0102H,0202H,0402H,0802H,1002H,2002H,4002H,8002H DW 0104H,0204H,0404H,0804H,1004H,2004H,4004H,8004H CHAR DB 'CDEFBA9845673210 RPMG'

;MAXDAY DB 00H,1FH,1CH,1FH,1EH,1FH,1EH,1FH,1FH,1EH,1FH,1EH,1FH MES DB 'IN SMALL KEYRORD',0AH,0DH

DB 'C--DISPLAY 12, 45, 37 ; G--GO AHEAD',0AH,0DH

DB 'D--STOP TO DISPLAY ; E--EXIT TO DOS',0AH,0DH

DB 'M--SET THE CLOCK ; F--OPEN THE CLOCK',0AH,0DH DB 'B--CLOSE THE CLOCK',0AH,0DH

DB 'P--POSITION THE BENINNING DATE',0AH,0DH,'$' DATA ENDS

STACKS SEGMENT DB 100 DUP (?)

STA DW 512 DUP (?) TOP EQU LENGTH STA STACKS ENDS CODE SEGMENT

;ASSUME CS:CODE,DS:DATA,SS:STACKS,ES:DATA START:

;ENABLE LOCAL INTERRUPT INPUT .386

CLI

MOV AX,DATA MOV DS,AX MOV ES,AX

MOV AX,STACKS

10

MOV SS,AX

CALL FINDTPC ;查找TPC卡资源并显示

MOV AH,0

INT 1AH ;时间中断,保存到DX中 MOV BX,DX T1: MOV AH,0 INT 1AH CMP BX,DX JZ T1

MOV BX,DX MOV SI,0 T2: MOV AH,0 INT 1AH

MOV AX,800H

T3: DEC AX ;循环800H次 JNZ T3 INC SI

CMP BX,DX JZ T2

MOV AX,30H MOV BX,SI MUL BX

MOV BX,56H DIV BX

MOV WORD PTR CONST1,AX

MOV DX,WORD PTR IO_BASE_ADDRESS ;初始化8253 ADD DX,TIM_CTL ;控制口

MOV AL,MODE03 ;36H==0011 0110 ;计数器0工作在模式3(方波发生器),计数值采用二进制格式

OUT DX,AL

MOV DX,WORD PTR IO_BASE_ADDRESS

ADD DX,TIMER0 ;计时器0 MOV AL,00H OUT DX,AL MOV AL,02H OUT DX,AL

MOV DX,WORD PTR IO_BASE_ADDRESS

ADD DX,TIM_CTL ;74H==0111 0100 ;设置计数器1工作在模式2(分频器),计数值采用二进制格式

MOV AL,MODE12 OUT DX,AL

MOV DX,WORD PTR IO_BASE_ADDRESS

11

ADD DX,TIMER1 MOV AL,0AH OUT DX,AL MOV AL,00 OUT DX,AL

MOV DX,OFFSET MES MOV AH,09 INT 21H

MOV DX,WORD PTR IO_90BASE_ADDRESS

ADD DX,68H ;设置 TPC 卡中90芯片IO口,使能中断 IN AX,DX OR AX,0900H OUT DX,AX

MOV BX,WORD PTR INTERRUPT_LINE ;保存原中断向量 MOV AL,BYTE PTR [IRQ_VECT+BX]

MOV AH,35H INT 21H MOV AX,ES MOV CSREG,AX MOV IPREG,BX

MOV BX,WORD PTR INTERRUPT_LINE ;设置新中断向量 MOV AL,BYTE PTR [IRQ_VECT+BX] MOV CX,CS MOV DS,CX

MOV DX,OFFSET INT_PROC MOV AH,25H INT 21H

MOV AX,DATA MOV DS,AX MOV ES,AX

IN AL, 21H ;设置中断掩码 MOV BX,WORD PTR INTERRUPT_LINE

MOV AH,BYTE PTR [IRQ_MASK_0_7_TABLE+BX] AND AL,AH OUT 21H, AL IN AL, 0A1H

MOV BX,WORD PTR INTERRUPT_LINE

MOV AH,BYTE PTR [IRQ_MASK_8_15_TABLE+BX] AND AL,AH

OUT 0A1H, AL

12

STI ;开中断

;********************************************************* ;********************小键盘的查询过程********************* LKEY: CALL KEY ;获得TPC键盘输入值 MOV DL,[CHAR1] ;C--DISPLAY 12, 45, 37 CMP DL,'C' JNZ LGY CALL CPRO JMP LKEY

LGY: CMP DL,'G' ; G--GO AHEAD' JNZ LDY CALL GPRO JMP LKEY

LDY: CMP DL,'D' ; D--STOP TO DISPLAY JNZ LPY CALL DPRO JMP LKEY LPY: CMP DL,'P' ; 'P--POSITION THE BENINNING JNZ LMY CALL PPRO JMP LKEY

LMY: CMP DL,'M' ;SET THE CLOCK TIME JNZ LFY CALL MPRO JMP LKEY

LFY: CMP DL,'F' ;BELLING ON/OFF JNZ LBY

MOV MYBELL,01H ;ON JMP LKEY

LBY: CMP DL,'B' ;B--CLOSE THE CLOCK JNZ LEY

MOV MYBELL,00H ;OFF JMP LKEY

LEY: CMP DL,'E' ; EXIT TO DOS' JNZ LKEY

;**********************非规定的按键时继续等待************* ;********************************************************* EXIT: CLI

MOV BX,WORD PTR INTERRUPT_LINE ;恢复中断掩码 MOV AH,BYTE PTR [IRQ_MASK_0_7_TABLE+BX] NOT AH IN AL, 21H OR AL, AH

13

OUT 21H, AL

MOV BX,WORD PTR INTERRUPT_LINE

MOV AH,BYTE PTR [IRQ_MASK_8_15_TABLE+BX] NOT AH

IN AL, 0A1H OR AL, AH OUT 0A1H, AL

MOV BX,WORD PTR INTERRUPT_LINE ;恢复原中断向量 MOV AL,BYTE PTR [IRQ_VECT+BX] MOV DX,IPREG MOV CX,CSREG MOV DS,CX MOV AH,25H INT 21H

MOV AX,DATA ;设置 TPC 卡中90芯片IO口,关闭中断 MOV DS,AX

MOV DX,WORD PTR IO_90BASE_ADDRESS ADD DX,68H IN AX,DX

AND AX,0F7FFH OUT DX,AX

MOV AX,4C00H INT 21H ;退出

;------------------------------------------------------------------

INT_PROC PROC FAR ;修改后的中断服务子程序(改变进位的条件)

;此中断服务子程序的类型设置为FAR调用,这里要特别注意.因为相对于中断发生时的运行 ;状态,此程序段与之不在同一代码段,所以应该定义为FAR类型.这样产生了另外一个问题, ;在此程序段中若想调用此CODE段中以他过程,则那个过程也应该被定义为FAR调用,当然 ;可以简单的通过不使用过程调用解决.以解决此中断子程序过程和其他普通过程对对应过程 ;的调用冲突 CLI

PUSH AX PUSH BX PUSH CX PUSH DX PUSH SI PUSH DI PUSH DS

MOV AX,DATA ;INTERRUPT TO DO MOV DS,AX DEC [COUNT]

14

JNZ DDD

MOV [COUNT],20

MOV DI,OFFSET CTIME MOV AL,[DI+4] MOV AH,0AH MUL AH

ADD AL,[DI+5]

CMP AX,59 ;先判断秒钟是否等于59秒,是则判断分钟,否则加1 JZ FENZHONG

INC BYTE PTR [DI+5]

CMP BYTE PTR [DI+5],0AH JNZ DDD

MOV BYTE PTR [DI+5],00H INC BYTE PTR [DI+4] JMP DDD FENZHONG:

MOV WORD PTR [DI+4],0000H ;先将秒钟置为0,再转换分钟为十进制形式 MOV AL,[DI+2] MOV AH,0AH MUL AH

ADD AL,[DI+3]

CMP AX,59 ;判断是否应该向时钟进位 JZ SHIZHONG

INC BYTE PTR [DI+3]

CMP BYTE PTR [DI+3],0AH JNZ DDD

MOV BYTE PTR [DI+3],00H INC BYTE PTR [DI+2] JMP DDD

SHIZHONG: MOV WORD PTR [DI+2],0000 MOV AL,[DI] MOV AH,0AH MUL AH

ADD AL,[DI+1]

CMP AH,23 ;判断时钟该不该循环了 JNZ QQQ

MOV WORD PTR [DI],0000H JMP DDD

QQQ: INC BYTE PTR [DI+1]

CMP BYTE PTR [DI+1],0AH JNZ DDD

MOV BYTE PTR [DI+1],00H INC BYTE PTR [DI]

15

DDD: ;将闹铃功能键与闹铃条件的判断放在20次中断计数条件满足后的执行代码中 ;有效缩短延迟时间以及误差时间

CMP BYTE PTR MYBELL,00H ;检测闹铃有没有开, JZ ZZZ

LEA DI,CTIME LEA SI,CLOCK MOV CX,5

CHECK: ;检测门铃时间是否到了 MOV AL,[DI] MOV BL,[SI] CMP AL,BL JNZ ZZZ INC DI INC SI

LOOP CHECK

;************** 闹铃时的检测输出 MOV DL,07H MOV AH,02H INT 21H

LEA DX,MESS1 MOV AH,09H INT 21H MOV BYTE PTR MYBELL,00H ZZZ:

MOV AL,20H ;SEND EOI OUT 0A0H,AL OUT 20H,AL

MOV CX,0FFFFH LOOPX:

NOP

LOOP LOOPX ;延时 POP DS POP DI

POP SI POP DX POP CX POP BX POP AX STI IRET INT_PROC ENDP

;------------------------------------------------------------------

KEY PROC NEAR ;AB口端口读取的控制,是对小键盘的控制 PUSH CX

16

KST: MOV AL,82H

MOV DX,WORD PTR IO_BASE_ADDRESS ADD DX,P55CTL OUT DX,AL MOV AL,00H

MOV DX,WORD PTR IO_BASE_ADDRESS ADD DX,PA55 OUT DX,AL

MOV DX,WORD PTR IO_BASE_ADDRESS DLY: DLY1: SCAN1:

KEYN: RELEA:

ADD DX,PB55 IN AL,DX OR AL,0F8H CMP AL,0FFH JZ DELAY PUSH AX

MOV CX,0A00H ;两重循环 MOV AX,WORD PTR CONST1 DEC AX JNZ DLY1 DEC CX JNZ DLY POP AX MOV CL,08H MOV AH,0FEH MOV DX,WORD PTR IO_BASE_ADDRESS;行列扫描,得到小键盘输入 ADD DX,PA55 MOV AL,AH OUT DX,AL

MOV DX,WORD PTR IO_BASE_ADDRESS ADD DX,PB55 IN AL,DX OR AL,0F8H CMP AL,0FFH JNZ KEYN ROL AH,1 DEC CL JNZ SCAN1 JMP KST PUSH AX

MOV DX,WORD PTR IO_BASE_ADDRESS ADD DX,PB55 IN AL,DX OR AL,0F8H

17

CMP AL,0FFH JNZ RELEA POP AX NOT AX

MOV SI,OFFSET TABLE1 MOV DI,OFFSET CHAR MOV CX,24 TT: CMP AX,[SI] JZ NN DEC CX JZ KST ADD SI,02 INC DI JMP TT

NN: MOV DL,[DI]

MOV [CHAR1],DL MOV AH,02H INT 21H POP CX JMP YANG DELAY: CALL DISPLY JMP KST YANG: RET KEY ENDP

;---------------------------------------------------------------

DISPLY PROC NEAR PUSH CX

MOV BX,OFFSET LED MOV CX,0006

MOV SI,OFFSET CTIME MOV AH,01H DISPLY1: CLD LODSB XLAT

MOV DX,WORD PTR IO_BASE_ADDRESS ADD DX,PORTSEG OUT DX,AL MOV AL,AH

MOV DX,WORD PTR IO_BASE_ADDRESS ADD DX,PORTBIT OUT DX,AL SHL AH,1 MOV AL,00 OUT DX,AL

18

;LED的显示部分 LOOP DISPLY1 POP CX RET DISPLY ENDP

;---------------------------------------------------------------

CPRO PROC NEAR ;C键按下时执行的过程,显示预设时间 CLI

MOV WORD PTR [CTIME],0201H MOV WORD PTR [CTIME+2],0504H MOV WORD PTR [CTIME+4],0703H RET CPRO ENDP

;---------------------------------------------------------------

GPRO PROC NEAR ;G键按下时执行的过程,开中断,计时开始 STI RET GPRO ENDP

;----------------------------------------------------------------

DPRO PROC NEAR ;D键按下时执行的过程,关中断,计时停止 CLI RET DPRO ENDP

;---------------------------------------------------------------

PPRO PROC NEAR ;时间设置的过程 CLI

PUSH AX PUSH BX

MOV WORD PTR [CTIME],0C0CH MOV WORD PTR [CTIME+2],0C0CH MOV WORD PTR [CTIME+4],0C0CH CALL DISPLY CALL KEY

MOV DL,[CHAR1]

CMP DL,'2' ;首位判断是否小于2 JNG NEXT1 JMP ERR1 NEXT1:

CMP DL,'2' ;第一位是否为1,是则判断第二位是否小于3 JNZ NORMAL SUB DL,30H

MOV [CTIME],DL CALL KEY

MOV DL,[CHAR1]

19

CMP DL,'3' JNG NEXT2 JMP ERR1

NORMAL: SUB DL,30H MOV [CTIME],DL CALL DISPLY CALL KEY

MOV DL,[CHAR1]

CMP DL,'9' ;第三位的判断,如此直到第六位 NEXT2: NEXT3: NEXT4: NEXT5:

JNG NEXT2 JMP ERR1 SUB DL,30H

MOV [CTIME+1],DL CALL DISPLY CALL KEY

MOV DL,[CHAR1] CMP DL,'5' JNG NEXT3 JMP ERR1 SUB DL,30H

MOV [CTIME+2],DL CALL DISPLY CALL KEY

MOV DL,[CHAR1] CMP DL,'9' JNG NEXT4 JMP ERR1

SUB DL,30H MOV [CTIME+3],DL CALL DISPLY CALL KEY

MOV DL,[CHAR1] CMP DL,'5' JNG NEXT5 JMP ERR1 SUB DL,30H

MOV [CTIME+4],DL CALL DISPLY CALL KEY

MOV DL,[CHAR1] CMP DL,'9' JNG NEXT6 JMP ERR1

20

NEXT6:

SUB DL,30H

MOV [CTIME+5],DL CALL DISPLY

JMP WW

ERR1: MOV WORD PTR [CTIME],0A0BH ;输入不全规范时输出,E------- MOV WORD PTR [CTIME+2],0A0AH MOV WORD PTR [CTIME+4],0A0AH CALL DISPLY WW: POP BX POP AX RET PPRO ENDP

;---------------------------------------------------------------

MPRO PROC NEAR ;闹铃设置,总体是先保存时间值,再调用P过程,再还原时间 CLI

PUSH DI PUSH SI LEA DI,BUF LEA SI,CTIME MOV CX,6

BAOCUN: ;保存时间 MOV AL,[SI] MOV [DI],AL INC DI INC SI

LOOP BAOCUN

CALL PPRO LEA SI,CTIME LEA DI,CLOCK MOV CX,6

ZHUAN: ;把设置时间转换到闹铃中 MOV AL,[SI] MOV [DI],AL INC DI INC SI LOOP ZHUAN LEA SI,BUF LEA DI,CTIME MOV CX,6 HUAN: ;BUF->CTIME MOV AL,[SI]

21

MOV [DI],AL INC SI INC DI LOOP HUAN LEA SI,CTIME LEA DI,CLOCK MOV CX,6

TEST0: MOV DL,[SI] ;测试输入的正确性,可以删除 ADD DL,30H MOV AH,02H INT 21H INC SI

LOOP TEST0 MOV CX,6 TEST1:

MOV DL,[DI] ADD DL,30H MOV AH,02H INT 21H INC DI

LOOP TEST1

POP SI POP DI

RET MPRO ENDP

;--------------------------------------------------------------- FINDTPC PROC NEAR ;查找TPC卡资源并显示 PUSHAD PUSHFD

MOV AX,0B101H INT 1AH

JC FINDTPC_NOTFIND ;检查PCI BIOS是否存在

MOV AX,0B102H

MOV CX,IO_PLX_DEVICE_ID MOV DX,IO_PLX_VENDOR_ID MOV SI,0 INT 1AH

JC FINDTPC_NOTFIND ;检查TPC卡是否安装,设备号、厂商号

MOV AX,0B10AH MOV DI,02CH INT 1AH

22

JC FINDTPC_NOTFIND CMP ECX,IO_PLX_SUB_ID JNZ FINDTPC_NOTFIND ;检查TPC卡是否安装,子设备号、厂商号

MOV AX,0B10AH MOV DI,14H INT 1AH

JC FINDTPC_NOTFIND ;读TPC卡90芯片I/O基址信息 MOV DWORD PTR IO_90BASE_ADDRESS,ECX AND ECX,1

JZ FINDTPC_NOTFIND ;检查是否为I/O基址信息 MOV ECX,DWORD PTR IO_90BASE_ADDRESS AND ECX,0FFFFFFFEH

MOV DWORD PTR IO_90BASE_ADDRESS,ECX ;去除I/O指示位并保存

MOV AX,0B10AH MOV DI,18H INT 1AH

JC FINDTPC_NOTFIND ;读TPC卡I/O基址信息 MOV DWORD PTR IO_BASE_ADDRESS,ECX AND ECX,1

JZ FINDTPC_NOTFIND ;检查是否为I/O基址信息 MOV ECX,DWORD PTR IO_BASE_ADDRESS AND ECX,0FFFFFFFEH

MOV DWORD PTR IO_BASE_ADDRESS,ECX ;去除I/O指示位并保存

MOV AX,0B10AH MOV DI,3CH INT 1AH

JC FINDTPC_NOTFIND ;读TPC卡中断信息 AND CX,0FFH

MOV WORD PTR INTERRUPT_LINE,CX ;去除INTERRUPT其它指示位并保存

MOV DX,OFFSET IO90BASEADDRESS ;显示I/O提示信息 MOV AH,09H INT 21H

MOV AX,WORD PTR IO_90BASE_ADDRESS CALL DISPWORD ;显示I/O基地址

MOV DX,OFFSET IOBASEADDRESS ;显示I/O提示信息 MOV AH,09H INT 21H

MOV AX,WORD PTR IO_BASE_ADDRESS CALL DISPWORD ;显示I/O基地址

23

MOV DX,OFFSET INTNUMBER ;显示INTERRUPT提示信息 MOV AH,09H INT 21H

MOV AX,WORD PTR INTERRUPT_LINE CALL DISPWORD ;显示中断号

MOV DX,OFFSET ENTER_RETURN ;加回车符,换行符 MOV AH,09H INT 21H POPFD POPAD RET

FINDTPC_NOTFIND:

MOV DX,OFFSET PCICARDNOTFIND ;显示未找到TPC卡提示信息 MOV AH,09H INT 21H

MOV AX,4C00H INT 21H ;退出 FINDTPC ENDP

DISPWORD PROC NEAR ;显示子程序 PUSH DX PUSH CX PUSH BX MOV CX,4 MOV BX,16

DISPWORD_LOOP1: PUSH AX PUSH CX SUB BX,4 MOV CX,BX SHR AX,CL

AND AL,0FH ;首先取低四位 MOV DL,AL

CMP DL,9 ;判断是否<=9 JLE DISPWORD_NUM ;若是则为'0'-'9',ASCII码加30H ADD DL,7 ;否则为'A'-'F',ASCII码加37H DISPWORD_NUM: ADD DL,30H

MOV AH,02H ;显示 INT 21H POP CX POP AX

24

LOOP DISPWORD_LOOP1 POP BX POP CX POP DX RET ;子程序返回 DISPWORD ENDP CODE ENDS END START

25

参考文献

[1]微机原理与接口技术(复习与考试指导)

[2]戴梅萼等. 微型计算机技术及应用.北京:清华大学出版社,2003 [3]王成耀等. 汇编语言程序设计.北京:机械工业出版社,2004

26

心 得 体 会 通过对数字闹钟的汇编实现,对硬件特别是8253A,8255并行口的原理和实现都有了很深的了解。更加深了对汇编语言的使用. 可以说整个文件中最麻烦的就是进位条件的判断,编程中经常犯想当然的错误。另外对于中断服务子程序的类型设置问题,由于以前对这个概念的理解留于表面,编程中出现了不少奇怪的错误。再调试中尝试使用了分割法,对错误模块进行定位,再进行排查. 在算法实现上要有一定的思路要更能体现设计的目的。同时上机调试也是十分重要的,在调试的过程中能够不断的发现在编写算法时应该注意的一些细节和算法语句的非法使用,在调试过程中通过对算法的不断测试、更正、扩充功能、修饰细节,使算法程序不断的得到完善。 通过这次的课程设计使我认识到要将微机原理这门计算机专业的课学好不仅仅是要把书上的基本知识学好而且还要不断进行实践,将所学的跟实践操作结合起来才能更好地巩固所学,才能提高自己实践能力.通过这次的设计使我认识到只停留在表面理解问题是很难使问题得到很好的解决的,实践能力与理论知识同样重要。可以说此课程设计的理论难度并不大,但是若要深入发掘其中的东西,并且实际去编程实现,就遇到了相当大的难度。因为与之涉及的很多方面并没有学过,需要自己去自学和实践检验。 所以在以后的学习中一方面我要不断的巩固自己所学的理论知识,一方面还要多参加实际操作工作以便提高自己的实际操作能力。 2008年 6月 日 教 师 评 语 年 月 日 成 绩 及 签 名 年 月 日

27

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo8.com 版权所有 湘ICP备2023022238号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务