一、实验目的
- 掌握定时/计数器8254的基本工作原理和编程方法
- 利用TPC-ZK-II实验板上的 8254向中断源发出中断申请,其中断请求用IRQ3(系统总线区的IRQ)
- 了解七段数码管显示原理,掌握其显示接口技术,了解数字时钟原理,掌握实现数字时钟技术
- 掌握中断控制器8259A的应用编程
二、实验原理
本实验的硬件中断只有可屏蔽中断,由 8259中断控制器管理。
1.8259内部结构
8259A是专为控制优先级中断而设计的芯片。它将中断源按优先级排队、辨认中断源、提供中断向量的电路集成于一体,只要用软件对它进行编程,就可以管理8 级中断。
它由中断请求寄存器(IRR)、优先级分析器、 中断服务寄存器(ISR)、中断屏蔽寄存器(IMR)、数据总线缓冲器、读写控制电路和级联缓冲器、比较器组成。
中断请求寄存器:寄存所有要求服务的请求IR0~IR7。
中断服务寄存器:寄存正在被服务的中断请求。
中断屏蔽寄存器:存放被屏蔽的中断请求,该寄存器的每一位表示一个中断号, 该位为1,屏蔽该号中断,否则开放该号中断。
数据总线缓冲器:是双向三态的,用以连接系统总线和8259A内部总线, 通过它可以由CPU对8259A写入状态字和控制字。
读写控制电路:用来接受I/O命令,对初始化命令和操作命令字寄存器进行写入,以确定8259A的工作方式和控制方式。
级联缓冲器/比较器:用于多片8259A的连接,能构成多达64级的矢量中断系统。
2.中断源与类型
中断源 | 中断类型号 | 中断功能 |
IRQ0 | 08H | 时钟 |
IRQ1 | 09H | 键盘 |
IRQ2 | 0AH | 保留 |
IRQ3 | OBH | 串行口2 |
IRQ4 | 0CH | 串行口1 |
IRQ5 | 0DH | 硬盘 |
IRQ6 | 0EH | 软盘 |
IRQ7 | 0FH | 并行打印机 |
表2-1 中断类型号
8个中断源的中断请求信号线IRQ0~IRQ7在主机的62线ISA总线插座中可以引出,系统已设定中断请求信号为“边沿触发”,普通结束方式。对于微机内又扩展了一片8259中断控制,IRQ2用于两片8259之间级连,对外可以提供16个中断源,如表2-2所示。
中断源 | 中断类型号 | 中断功能 |
IRQ8 | 070H | 实时时钟 |
IRQ9 | 071H | 用户中断 |
IRQ10 | 072H | 保留 |
IRQ11 | O73H | 保留 |
IRQ12 | 074H | 保留 |
IRQ13 | 075H | 协处理器 |
IRQ14 | 076H | 硬盘 |
IRQ15 | 077H | 保留 |
表2-2 扩展中断类型号
TPC-ZK-II实验板上,固定的接到了3号中断IRQ3上,即进行中断实验时,所用中断类型号为0BH。
中断控制器 8259可利用系统初始化设定,如不进行新的初始化,只需对 8259中断控制器的屏蔽寄存器设定 IRQ3为中断允许,其他原有中断允许保持不变。
3.8254设置
将实验板上的 8254的通道,设定为10ms周期信号发生器,该芯片的通道1设定为计数器,其输入来自定时器通道 0的输出,利用通道 1的计数器输出作为IRQ3中断请求信号。
4.8254连接图
图2-3 8254定时器连线
8254定时器的CLK0由实验板上的1MHZ振荡器来提供。8254定时器的CLK0由实验板上的1MHZ振荡器来提供。
5.数码管连接图与段码表
数码管显示接口电路如图2-4所示。实验台上的七段数码管为共阴型,段码采用同相驱动,输入端加高电平,选中的数码管亮,位码加反相驱动器,位码输入端高电平选中。
图2-4数码管显示电路
本实验需要 PB7-PB0/8255接dp-a /LED数码管,PC3-PC0/8255接 S3-S0/LED数码管。七段数码管的字型代码表如表2-5所示。
表2-5 七段数码管的字型代码表
三、实验框图与流程图
图3-1 实验程序设计流程图
四、实验程序清单
data segment
p8259 equ 21h ;端口首地址
p8255 equ 288h ;端口首地址
p8253 equ 280h ;IO Y1
led db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh
sec1 db 2
sec2 db 5
min1 db 8
min2 db 5
mes db 42h
Old_0A DW 0,0
Old_8259 DB 0
data ends
stacks segment
db 64 dup (0)
stacks ends
code segment
assume cs:code,ds:data,es:data
start:
mov ax,data
mov ds,ax
cli
mov al,00110110b
mov dx,p8253+3
out dx,al
mov ax,10000
mov dx,p8253
out dx,al
mov al,ah
out dx,al
mov al,01110110b
mov dx,p8253+3
out dx,al
mov ax,100
mov dx,p8253+1
out dx,al
mov al,ah
out dx,al
PUSH ES
PUSH BX
MOV Al,0BH
mov ah,35h
INT 21H
MOV Old_0A+2,ES
MOV Old_0A,BX
POP BX
POP ES
PUSH DS
MOV AL,0BH
MOV AH,25H
MOV DX,SEG INT_0A
MOV DS,DX
MOV DX,OFFSET INT_0A
INT 21H
POP DS
MOV AL,10000000B
MOV DX,P8255+3
OUT DX,AL
IN AL,P8259
MOV OLD_8259,AL
AND AL,11110111B
OUT P8259,AL
STI
PLAY:
LEA BX,LED
MOV DL,SEC1
MOV DH,0
MOV SI,DX
MOV AL,[BX][SI]
MOV DX,P8255+1
OUT DX,AL
MOV AH,00001110B
MOV AL,AH
MOV DX,P8255+2
OUT DX,AL
PUSH CX
MOV CX,9fffH
DELAY1:
nop
nop
LOOP DELAY1
POP CX
MOV AH,00001111B
MOV AL,AH
MOV DX,P8255+2
OUT DX,AL
MOV DL,SEC2
MOV DH,0
MOV SI,DX
MOV AL,[BX][SI]
MOV DX,P8255+1
OUT DX,AL
MOV AH,00001101B
MOV AL,AH
MOV DX,P8255+2
OUT DX,AL
PUSH CX
MOV CX,9fffH
DELAY2:
nop
nop
LOOP DELAY2
POP CX
MOV AH,00001111B
MOV AL,AH
MOV DX,P8255+2
OUT DX,AL
MOV DL,MIN1
MOV DH,0
MOV SI,DX
MOV AL,[BX][SI]
MOV DX,P8255+1
OUT DX,AL
MOV AH,00001011B
MOV AL,AH
MOV DX,P8255+2
OUT DX,AL
PUSH CX
MOV CX,9fffH
DELAY3:
nop
nop
LOOP DELAY3
POP CX
MOV AH,00001111B
MOV AL,AH
MOV DX,P8255+2
OUT DX,AL
MOV DL,MIN2
MOV DH,0
MOV SI,DX
MOV AL,[BX][SI]
MOV DX,P8255+1
OUT DX,AL
MOV AH,00000111B
MOV AL,AH
MOV DX,P8255+2
OUT DX,AL
PUSH CX
MOV CX,9fffH
DELAY4:
nop
nop
LOOP DELAY4
POP CX
MOV AH,00001111B
MOV AL,AH
MOV DX,P8255+2
OUT DX,AL
JMP PLAY
MOV AH,4CH
INT 21H
INT_0A PROC NEAR
CMP SEC1,9
JZ INT1
INC SEC1
JMP EXIT
INT1:
MOV SEC1,0
INC SEC2
CMP SEC2,6
JNZ EXIT
MOV SEC2,0
INC MIN1
CMP MIN1,10
JNZ EXIT
MOV MIN1,0
INC MIN2
CMP MIN2,6
JNZ EXIT
MOV MIN2,0
EXIT:
MOV AL,20H
OUT 20H,AL
IRET
INT_0A ENDP
CODE ENDS
END START
五、实验结果与分析
1.本次实验共用了三个芯片,分别是8254,8259,8255。
8254使用方式3,设定为以10ms为周期的方波发生器,通道0的输入时钟CLK0由实验板上的1MHz振荡器来提供。通道1设定为计数器,输入来自定时器通道0的输出OUT0,利用通道1的计数器输出OUT1作为IRQ3中断请求信号。
8259用于中断控制器管理。将8254产生的方波连接在IRQ3上,作为中断源。利用DOS系统功能,将IRQ3的终端类型号(0BH)对应的中断向量修改为分、秒计数逻辑函数的段地址和偏移地址,在使用之前打开IRQ3的中断,这样8259每隔一秒便会给CPU发来一个中断并让CPU响应,即跳转到中断程序,修改内存中的分、秒数据。
8255用来控制LED灯。B口作为LED段选,C口作为LED位选,每次只让一个位置的LED灯亮对应的数字,很短的时间间隔后再让下一位的LED灯亮,循环往复,以较高的频率扫频,通过人眼的视觉暂留来达到LED“同时”亮的效果。
CPU在8259发来中断时响应中断,改变内存中的分、秒数据。四者联合工作,8254产生方波,8259每隔一秒中给CPU发送一个中断,而8255是由CPU控制的,将CPU内存中的数据在LED灯上显示出来。
2.代码分析
首先,代码定义了一些数据和设备地址的变量:led 数组是用于存储每个数字对应的LED显示代码的。sec1, sec2, min1, min2 是用于存储秒和分钟的变量,每个变量都存储一位数字。Old_0A 和 Old_8259 是用于存储老的中断向量表和8259中断控制器的值。p8259, p8255, p8253 分别是8259中断控制器,8255并口和8253计时器的IO端口地址。
代码中的主程序首先初始化数据段,并且将8253计时器和8255并口进行配置。在配置完成后,程序替换了原本的时钟中断处理程序(向量号0Ah),并打开了8259的IRQ0中断。主程序的主循环PLAY中,将秒和分钟的每一位取出,通过查找led数组得到对应的LED代码,然后通过8255并口将这个代码输出到LED显示屏。在每个数字输出之后,程序会暂停一段时间,这段时间通过循环来实现。INT_0A 是自定义的时钟中断处理程序。每次时钟中断,秒的个位数字加一,当秒的个位数字等于9时,秒的十位数字加一,以此类推,当分钟的十位数字等于6时,分钟清零。每次中断处理完成后,发送一个EOI(End Of Interrupt)给8259,然后返回。程序的结束部分,重新加载了原本的时钟中断处理程序,然后使用INT 21H的4CH功能来结束程序。
3.实验细节探究:
nop 是一个汇编指令,全称 "No Operation"。这个指令在执行的时候什么都不做,CPU会直接跳到下一条指令。nop 通常用于产生微小的延迟或者作为占位符使用。在DELAY1这个标签下的代码中,nop 指令用来创建一个简单的延迟循环。程序会执行 9fffh 次的 nop 指令,每次 nop 都会消耗一点处理器时间,这样一来,9fffh 次 nop 就能创建出一段微小的延迟。这种方式在一些实时性要求比较高的硬件控制程序中比较常见。至于为什么需要延迟,这主要是由于硬件的限制。对于硬件设备来说,它们不能立即响应CPU的指令,需要一定的时间去处理。如果CPU连续发送指令给硬件,而硬件还没来得及处理前一条指令,就可能会导致错误。所以,在操作硬件设备的时候,通常需要插入一些延迟,给硬件设备一些处理时间。在这个程序中,延迟循环是在更新每个LED显示位后进行的,这是为了保证8255并口有足够的时间处理数据的输出,也让LED显示器有足够的时间显示每个数字。如果没有这个延迟,那么LED显示器可能会出现闪烁或者显示错误的问题。
在这个应用中使用动态扫描显示的方式。动态扫描显示的基本思想是,同时只点亮一个显示单元(在此程序中的一个LED灯),但是由于点亮的速度足够快,人眼无法分辨每个单元是分别点亮的,所以看上去就像所有显示单元都同时亮起。那么,为什么在选中一片 LED 之后,还要再执行一次以下代码:
MOV AH,00001111B
MOV AL,AH
MOV DX,P8255+2
OUT DX,AL
这是因为这个命令实际上是关闭(或者说,取消选中)了当前的 LED 灯。这是为了保证在下一个循环开始时,所有的 LED 灯都是处于关闭状态,从而可以重新选择一个 LED 灯进行点亮。既然每次循环都会选择一个 LED 灯进行点亮,为什么还需要显式地关闭所有的 LED 灯呢?这是因为在实际的硬件中,如果不显式地关闭 LED 灯,它可能会由于一些因素(例如,电源噪声或者硬件的电容效应)而继续保持亮起。通过显式地关闭所有的 LED 灯,可以保证显示的正确性。