现代微机中,定时与计数控制一般采用8253(如IBM-PC)或8254(286及其后的微机),8254是8253的改进型,它们的内部结构和工作原理相同。在386以后的微机中,与8254完全兼容的可编程计数/定时器已经被集成到I/O控制逻辑芯片或总线转换逻辑芯片中。
Intel 8254采用24引脚双列直插式封装,其主要特性如下。
· 有3个独立的16位定时/计数通道。
· 每个通道有6种工作方式,既可实现精确定时,又可对外部脉冲进行计数。
· 最高计数频率为10MHz(8253最高计数频率为2MHz)。
· 可以使用二进制或BCD码两种方式计数。
· 定时时间长短可用软件设置,可由软件或硬件控制开始计数或停止计数。
· 可以同时锁存1~3个计数器的计数值和状态值,供CPU读取(8253每次只能锁存和读取一个通道的计数器的值)。
8254的内部结构和外部引脚如图8-1所示。
(1)数据总线缓冲器。
数据总线缓冲器为8位、双向、三态的缓冲器,通过8条数据线D7~D0接收CPU向控制寄存器写入的控制字以及向计数器写入的计数初值,也可把计数器的当前计数值读入CPU。
(2)读/写控制逻辑。
读/写控制逻辑从系统总线接收地址及控制信号,经过译码产生对8254各部分的控制。
图8-1 8254的内部结构和外部引脚
(3)计数通道。
8254有3个相互独立的、同样的计数电路,分别称为计数器0、计数器1和计数器2。每个计数器包括:一个8位的控制寄存器,存放计数器的工作模式;一个16位的初值寄存器(CR),8254工作之前要对它设置初值;一个16位计数执行单元(CE),接收计数初值寄存器(CR)送来的内容,并对该内容执行减1操作;一个16位输出锁存器(OL),锁存CE的内容,使CPU能从输出锁存器读出一个稳定的计数值。计数器的结构如图8-2所示。
图8-2 计数器的结构
(1)与CPU相连的引脚。
①D7~D0:数据线,双向、三态。用于将8254与系统数据总线相连,是8254与CPU接口数据线,供CPU向8254读/写数据、命令和状态信息。
②RD:读信号,输入、低电平有效。当RD为低电平时,表示CPU正在对8254的一个计数器进行读操作。
③WR:写信号,输入、低电平有效。当WR为低电平时,其控制把CPU输出的数据或命令信号写到8254的寄存器中。
④CS:片选信号,输入、低电平有效。当CS为低电平时,CPU选中8254,可以对8254进行读/写操作,CS为高电平时未选中。
⑤A1、A0:地址线,输出。这两条线连接到地址总线的A1、A0上,以选中8254内部的寄存器,对它们进行读/写操作。A1、A0与8254内部寄存器的关系如表8-1所示。
表8-1 8254内部寄存器在PC中的相应地址
CS |
RD |
WR |
A1 |
A0 |
操 作 |
PC端口地址 |
| |||
0 0 0 0 |
1 1 1 1 |
0 0 0 0 |
0 0 1 1 |
0 1 0 1 |
计数初值装入计数器0 计数初值装入计数器1 计数初值装入计数器2 控制字写入控制寄存器 |
40H 41H 42H 43H |
| |||
0 0 0 0 |
0 0 0 0 |
1 1 1 1 |
0 0 1 1 |
0 1 0 1 |
读计数器0当前计数值 读计数器1当前计数值 读计数器2当前计数值 无操作,三态 |
40H 41H 42H × | ||||
1 0 |
× 1 |
× 1 |
× × |
× × |
禁止,三态 无操作,三态 |
× × | ||||
(2)与外设相连的引脚。
①CLK:计数时钟,输入。用于输入定时脉冲或计数脉冲信号。在计数过程中,此引脚每输入一个时钟信号,计数器的计数值减1,所以计数器是记录脉冲个数的计数器,并且计数通道受门控信号的控制。
②GATE:门控信号,输入。由外部信号通过GATE端控制计数器的启动计数和停止计数的操作,有效电平可分成电平控制和上升沿控制两种类型。
③OUT:计数结束信号,输出。当计数器计数到0时,在OUT引脚必定有输出。在不同的模式下可输出不同电平的信号。
8253/8254可编程定时/计数器有6种工作方式,工作方式不同,其OUT端的输出波形就不同,启动计数开始的触发方式也不同,GATE端对计数过程的控制和影响也不同。
当某计数通道被设置成工作方式0时,该通道输出端OUT即变为低电平。在装入预置的计数值后,计数器就自动启动,输出端仍保持为低电平。每输入一个脉冲,当前计数值就减1,待减到0时输出变为高电平,计数停止,这个高电平输出将一直维持到重新装入计数值或者重新设置工作方式为止。
GATE端电平可以控制计数过程。只有当GATE为高电平时,才允许计数。当GATE变为低电平时暂停计数。当GATE重新恢复成高电平时,将接着暂停时的计数值继续减1计数,如图8-3所示。
图8-3 8253/8254方式0输出波形
如果在计数过程中,给计数器装入新的计数值,若计数值是16位字长,需要分两次写入,这个通道将出现以下两种情况:
(1)写入第一个字节后将停止当前的计数过程。
(2)写入第二个字节后计数器开始在新装入数的基础上递减计数。该方式的输出信号可以用作中断请求信号。
在该方式中,写入方式命令字和装入计数初值到计数寄存器后,计数器输出端OUT为高电平。在GATE输入端出现一个上升沿后,计数器使输出端OUT降为低电平,开始计数;当计数值减到0,输出端恢复为高电平,完成一个单脉冲输出过程。显然输出端负脉冲的宽度与计数值的大小有关,设预置计数值为N,计数时钟周期为TCLK,那么输出负脉冲宽度就是N×TCLK。所以这是一个可编程控制的单稳态发生器,如图8-4所示。
图8-4 8253/8254方式1输出波形
在方式1下工作的计数器,启动计数的条件必须是GATE端出现一个上升沿,在触发开始计数后,GATE端即使变为低电平也不会停止计数过程,直到这次计数结束。当计数结束时,不管GATE为高电平还是低电平,OUT输出端都将恢复为高电平。如在计数尚未结束时,GATE端又出现一个上升沿,将使预置的计数值重新加入到递减计数器中,计数将重新开始。一次计数结束后,要重新开始下一次计数就必须用GATE端的上升沿再一次启动。
在计数过程中,可以由CPU给这个计数器置入新值,此新值不影响当前的计数值和计数过程,它只能在下一次触发启动后起作用。
该方式写入方式命令之后OUT端输出高电平,此时若门控信号GATE为高电平,则在装入计数初值寄存器后的一个CLK脉冲的下降沿将计数初值置入递减计数器并开始减1计数,OUT端输出为高电平,当计数到当前计数值为1时,输出一个时钟周期宽的负脉冲,同时自动将计数初值送至计数器继续进行减1计数,形成循环计数过程。这样在OUT端输出一系列周期为N个CLK时钟周期的负脉冲,负脉冲宽度为1个CLK时钟周期,如图8-5所示。
图8-5 8253/8254方式2输出波形
方式2是以计数初值N为分频因子的分频器,常用来产生实时的时钟。
门控信号GATE为高电平时允许计数,为低电平时禁止计数并使输出成为高电平。若门控信号GATE由低电平变为高电平,则将初值置入计数器中重新开始计数。因此,可利用门控GATE作为系列负脉冲的同步信号,GATE作用相当于负脉冲发生器的复位信号(RESET)。
这种方式的工作过程与方式2很相似,门控的作用和自动重复加载计数都是一样的,仅OUT引脚输出波形不同,它在计数过程中输出一系列方波,其占空比接近50%,与计数值有关,故常用作波特率发生器。方式3的输出波形如图8-6所示。
当计数开始后,每一个计数脉冲都使计数器减2。当设定计数值为偶数时输出对称的方波,每当递减计数到0时都会使输出状态翻转,并同时将计数值重新装入。如果计数值是奇数,当输出是高电平时则第一个时钟脉冲将计数值减1,后续的时钟脉冲则对计数值减2,减为0时,输出变为低电平,并重新装入计数值,第一个时钟脉冲对计数器减3,后续的时钟脉冲对计数器减2,一直到减为0,然后重复上述计数过程。因此,在方式3如果计数初值是奇数,输出高电平比输出低电平多一个CLK周期。
图8-6 8253/8254方式3输出波形
设定为方式4后,计数器的输出就变成高电平,在装入计数值后下一个CLK的下降沿开始计数。计数结束后输出端OUT出现一个时钟周期宽的负脉冲,也就是在第(N+1)个CLK周期上输出一个负脉冲,其宽度为一个CLK。方式4的输出波形如图8-7所示。
图8-7 8253/8254方式4输出波形
在计数进行的过程中给计数器写入新的计数值不会影响本次计数,而要在触发开始下一次计数过程中才起作用。
GATE端信号为低电平禁止计数。当GATE端变为高电平时,计数器将重新装入计数初值,从头开始计数。
这种方式不能自动重复工作,而要以软件装入计数值作为触发信号,使计数器开始新一轮的计数过程。
在该方式中写入方式控制字、加载计数初值后输出为高电平。由GATE的上升沿触发,在GATE上升沿的下一个时钟CLK的下降沿开始减1计数。当计数值减为0后,OUT端输出一个CLK周期宽的负脉冲,计数结束。方式5的输出波形如图8-8所示。
图8-8 8253/8254方式5输出波形
在计数过程中,GATE端又出现上升沿触发,计数器将重新装入计数值,从头开始计数。GATE信号在各种工作方式中的控制作用如表8-2所示。
表8-2 GATE端信号的作用
方 式 |
低电平或变低电平 |
上升沿 |
高电平 |
方式0 |
禁止计数 |
|
允许计数 |
方式1 |
|
开始计数 计数的第一个时钟后,使输出变低 |
|
方式2 |
① 禁止计数 ② 立即使输出为高电平 |
开始计数 |
允许计数 |
方式3 |
① 禁止计数 ② 立即使输出为高电平 |
开始计数 |
允许计数 |
方式4 |
禁止计数 |
|
允许计数 |
方式5 |
|
开始计数 |
|
各种工作方式的特点及异同的比较如表8-3所示。
表8-3 各种工作方式的比较
工作方式 |
共同点 |
不同点 |
方式0(计数结束中断)和方式4(软件触发选通) |
由软件触发启动计数,向计数值寄存器写入计数初值之后,下一个CLK的下降沿装入减1计数器开始计数。减至0,计数过程结束,无自动重装能力,GATE为0停止计数 |
OUT端输出信号不同。方式0的OUT端在方式设置后及计数过程中输出为低电平,计数结束立即变为高电平,此输出可作为计数结束的中断请求信号;方式4的OUT端信号在计数过程中输出高电平,计数结束时输出一个负脉冲,宽度为一个时钟周期GATE恢复高电平后,方式0继续计数,方式4重新计数 |
续上表 | ||
工作方式 |
共同点 |
不同点 |
方式1(可编程单脉冲发生器)和方式5(硬件触发选通) |
由硬件触发启动计数,计数初值写入计数值寄存器后并不马上开始计数,而由门控信号GATE端的上升沿触发预置计数值,开始减1计数 |
OUT输出信号不同。方式1在计数过程中OUT端为低电平,持续时间为N个CLK宽度;方式5是在计数结束后输出一个CLK宽度的负脉冲 |
方式4和方式5 |
计数值减为0时OUT输出一个CLK周期的负脉冲重新计数都是从头开始 |
触发方式不同。方式4由软件(装入计数初值)触发,方式5由硬件(GATE上升沿)触发 |
方式0和方式1 |
OUT输出计数过程为低电平,计数结束为高电平 |
触发方式不同。方式0由软件(装入计数初值)触发,方式1由硬件(GATE上升沿)触发方式0暂停计数后继续减1计数,方式1由GATE上升沿触发后重新计数 |
方式2(分频脉冲发生器)方式3(方波发生器) |
计数结束自动装入计数初值,即减1至0时计数初值寄存器的内容又被自动装入计数单元,OUT端输出连续的波形GATE门控作用对计数的影响相同 |
OUT端输出的信号不同。方式2在减1至0时OUT端输出一个CLK宽度的负脉冲;方式3在计数过程中,OUT端输出的信号是方波(或近似方波) |
8254是可编程接口芯片,使用前必须先对它进行初始化编程。8254的初始化编程有以下两个步骤。
(1)向8254写入控制字,用于确定所选通道的工作方式和计数格式,写入控制字同时起到复位作用。
(2)向8254的通道写入计数初值,每个通道都有一个独立的端口地址。每个通道在写入控制字和计数初值之后开始工作。
8254方式控制字的格式如图8-9所示。
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
SC1 |
SC0 |
RW1 |
RW0 |
M2 |
M1 |
M0 |
BCD |
00:选择计数器0 01:选择计数器l 10:选择计数器2 11:读出控制字 |
00:数据锁存命令 01:只读/写低位字节 10:只读/写高位字节 11:先读/写低位字节,后读/写高位字节 |
000~101:选择方式0~5 110:选择方式2 111:选择方式3 |
0:二进制计数 1:BCD计数 |
图8-9 8254方式控制字的格式
(1)D7、D6为计数器/读出控制字选择位。
8254的3个计数通道的方式控制字和读出控制字都共用同一个端口地址,即A1A0=11。因此,必须用控制字本身来区分写入的是哪一个计数器的命令。控制字的D7D6两位为00、01、10时分别选择3个计数通道,为11时选择控制寄存器,用于读出控制寄存器内容。D7D6=11时,后续各位的格式如图8-9所示(对于8253,D7D6=11为无效命令)。
(2)D5、D4为读/写方式选择位。
①D5D4=00:表示锁存计数器的当前计数值,以便读出。
②D5D4=01:表示写入时,只写入计数初值低8位,高8位置0;读出时,只读出低8位的当前计数值。
③D5D4=10:表示写入时,只写入计数初值高8位,低8位置0;读出时,只读出高8位的当前计数值。
④D5D4=11:计数初值为16位,分两次写入计数初值寄存器或读出当前计数值,先读/写低8位,后读/写高8位。
(3)D3、D2、D1为工作方式选择位。
D3、D2、D1取值000~101分别代表方式0~5。
(4)D0为计数格式选择位。
D0=0,按二进制格式计数;D0=1,按BCD码格式计数。
读出控制字的格式如图8-10所示。
11 |
D5 |
D4 |
D3 |
D2 |
D1 |
0 |
标志 |
0:锁存计数值 |
0:锁存状态 |
1:选中计数器2 |
1:选中计数器1 |
1:选中计数器0 |
|
图8-10 8254读出控制字的格式
读出控制字D7D6必须为11,D0必须为0,这3位合起来构成8254的读出控制字的标志。D5=0锁存计数值,以便CPU读取;D4=0将状态信息锁存进状态寄存器;D3~D1用来选择计数器0~2。无论是锁存计数值还是锁存状态信息,都不影响计数。
读出命令可以同时锁存3个计数器的计数值/状态信息,CPU读取其中一个计数器的计数值/状态信息时,该计数器自动解锁,其他计数器不受影响。
注意:写入读出控制字之后,状态值/计数值被锁存在这个通道的输出锁存器中。如果同时锁存了状态值/计数值,第一次读这个通道的输出锁存器,得到的是状态值(格式如图8-10所示),第二次读到的是被锁存的计数器当前值。
8254状态字的格式如图8-11所示。
D7表示输出OUT引脚的输出状态,D7=1表示OUT端当前输出高电平,D7=0表示OUT端当前输出低电平;D6表示是否已经装入计数初值,D6=0代表已装入初值,读取的计数值有效;D5~D0各位是由方式控制字确定的,与方式控制字的对应位相同。
D7 |
D6 |
D5 |
D4 |
D3 |
D2 |
D1 |
D0 |
OUTPUT |
NULL COUNT |
RW1 |
RW0 |
M2 |
M1 |
M0 |
BCD |
1:本计数器OUT引脚为1 0:本计数器OUT引脚为0 |
1:无效计数 0:计数值有效 |
由控制字设定的计数器工作方式 |
图8-11 8254状态字的格式
8254是可编程定时芯片,在使用之前要初始化。第1步向控制寄存器写入方式控制字,确定所要的工作方式。第2步,向使用的计数器写入计数初值。
如PC系统中8254端口地址为40H~43H,要求计数器0工作在方式0,计数初值为DEH,以二进制方式计数;计数器1工作在方式2,计数初值为1000D,按BCD码计数。写出初始化程序。
根据要求,计数器0、1的控制字分别如图8-12所示。
D7=0 |
D6=0 |
D5=0 |
D4=1 |
D3=0 |
D2=0 |
D1=0 |
D0=0 | |
计数器0 |
只写低8位 |
选择工作方式0 |
二进制计数 | |||||
D7=0 |
D6=0 |
D5=0 |
D4=1 |
D3=0 |
D2=0 |
D1=0 |
D0=0 | |
计数器1 |
只写低8位 |
选择工作方式2 |
BCD码计数 | |||||
图8-12 8254初始化编程
初始化程序如下:
MOV AL,10H ; 写通道0控制字
OUT 43H,AL
MOV AL,0DEH ; 写通道0计数初值
OUT 40H,AL
MOV AL,65H ; 写通道1控制字
0UT 43H,AL
MOV AL,10H ; 写通道1计数初值
0UT 41H,AL
例如,设8254端口地址为3FF0H~3FF3H,要求计数器2工作在方式5,二进制计数,初值为2F30H,如图8-13所示。试按上述要求完成8254的初始化。
D7=1 |
D6=0 |
D5=1 |
D4=1 |
D3=1 |
D2=0 |
D1=1 |
D0=l |
计数器2 |
先写低8位,后写高8位 |
工作方式5 |
二进制计数 |
图8-13 8254端口示例
初始化程序如下:
MOV DX,3FF3H ; DX指向控制端口
MOV AL,0BAH ; 控制字
0UT DX,AL
MOV DX,3FF2H ; DX指向通道2
MOV AL,30H ; 写初值低8位
0UT DX,AL
MOV AL,2FH ; 写初值高8位
OUT DX,AL
在PC中,以8254定时/计数器构成的定时逻辑结构如图8-14所示。3个定时/计数器分别构成定时系统的3个通道。PC系统分配了4个I/O端口地址用于定时系统。0040H~0042H分别对应8254的3个计数器。8254的控制寄存器和状态寄存器共用端口地址0043H。3个通道的时钟输入CLK端的频率均为1.19318MHz,3个通道在PC中的作用如下。
图8-14 PC中的8254
(1)通道0。
通道0是一个系统计时器。为了保证系统定时的准确性,使之不受系统运行中出现的各种中断的影响,通道0输出接到了IRQ0上,中断0每隔55ms产生一次中断,它是系统定义的最高级可屏蔽中断,系统利用这个计数器完成日历时钟计数、控制软盘驱动器读/写操作后的电动机自动延时停机以及为用户提供INT 1CH定时中断调用。其初始化程序如下:
MOV AL,6H
OUT 43H,AL
MOV AL,0
OUT 40H,AL
OUT 40H,AL
(2)通道1。
定时器通道1是专门为系统的动态存储器刷新设置的。动态存储器芯片要求在规定的时间内对各行进行读取刷新。由于各类PC使用不同的存储芯片,刷新的时间间隔也各不相同,使用可编程的定时器可以方便地修改刷新时间间隔,以满足对不同容量的芯片进行刷新的要求。假设刷新时间约为15ms,则其初始化程序如下:
MOV AL,54H
MOV 43H,AL
MOV AL,12H ; 18/1.19318MHz=15.12us
OUT 41H,AL
(3)通道2。
这个定时通道的功能是驱动系统机箱内的扬声器。在ROM-BIOS中有一个声响子程序BEEF,它将计数器2编程为方式3,作为方波发生器输出约为1kHz的方波,经滤波驱动后推动扬声器发声。从图8-9中可以看出,发声程序还受并口61H的D1D0(即PB1 PB0)控制。其初始化程序如下:
Beef PROC
MOV AL,086H
OUT 43H,AL
MOV AX,0533H ; 1.19318MHz/1331=896Hz
MOV 42H,AL
MOV AL,AH
OUT 42H,AL
IN AL,61H
MOV AH,AL
OR AL,03H
OUT 61H,AL
SUB CX,CX
GO: LOOP GO ; 延迟片段
DEC BL ; 入口参数BL=6发长声,BL=1发短声
JNZ GO
MOV AL,AH ; 关闭发声
OUT 61H,AL
RET
Beef ENDP