欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

关于 Intel 8253/8254

程序员文章站 2022-03-15 15:14:31
...

Intel 8253/8254是一个可编程定时/计数器(PIT-Programmable Interval Timer)芯片,用于处理计算机中的精确时间延迟。该芯片提供了 3个独立的16位计数器通道。每个通道可工作在不同的工作方式下, 并且这些工作方式均可以使用软件来设置。

对于PC/AT及其兼容微机系统采用的是8254芯片。Linux 0.11操作系统只对通道0进行了重新设置,使得该计数器工作在方式3下,并且每间隔10毫秒发出一个信号以产生中断请求信号(IRQ0)。这个间隔定时产生的中断请求就是Linux 0.11内核工作的脉搏,它用于定时切换当前执行的任务和统计每个任务使用的系统资源量(时间)。

1、Intel 8253 (8254)芯片功能

Intel 8253 (或 8254)是一个可编程定时/计数器(PIT-Programmable Interval Timer)芯片,用于解决计算机中通常碰到的时间控制问题,即在软件的控制下产生精确的时间延迟。该芯片提供了3个独立的16位计数器通道。每个通道可工作在不同的工作方式下,并且这些工作方式均可以使用软件来设置。

8254是8253的更新产品,主要功能基本一样,只是8254芯片増加了回读命令。在下面描述中我们用8253来代称8253和8254两种芯片,仅在它们功能有区别处再特别加以指出。

2、端口说明

对于PC/AT及其兼容微机系统,采用的是8254芯片。3个计数器的输入时钟频率都是 1.193180MHz。PC/AT微机中8254芯片连接示意图如下。

关于 Intel 8253/8254

其中A1、A0管脚被连接到系统地址线A1、A0上。并且当系统地址线A9–A2信号是0b00100 00时会选择8254芯片,因此PC/AT系统中8254芯片的IO端口地址范围是0x40—0x43。其中0x40~0x42分别对应计数器通道0~2,0x43对应控制字寄存器写端口。

3、编程方法

当系统刚上电时,8253的状态是未知的。通过向8253写入一个控制字和一个初始计数值,我们就可以对想要使用的一个计数器进行编程。对于不使用的计数器我们可以不必对其编程。

在CPU执行写操作时,若A1,A0线为11 (此时在PC微机上对应端口 0x43),那么控制字会被写入控制字寄存器中。而控制字的内容会指定正在编程的计数器通道。

通道0、1、2分别对应PC机端口 0x40、0x41和0x42,当控制字写完后,就可以向某个通道写入初始计数值。

注意:在写入操作时,必须首先写入控制字,然后再写入初始计数值。初始计数值必须根据控制字中设定的格式写入(二进制或BCD码格式)。在计数器开始工作时,我们仍然能随时向指定计数器重新写入新的初始值,这并不会影响已设置的计数器的工作方式。

1、控制字的格式

控制字的格式如下图所示。

关于 Intel 8253/8254

    movb $0x36, %al
    movl $0x43, %edx
    outb %al, %dx

以上代码用于向端口0x43写入控制字0x36,对照上图,得知选中通道0,先读写低字节再读写高字节,工作方式3,采用二进制计数。

2、工作方式三——方波发生器方式

工作方式一共有6种,这里仅说明方式3,因为Linux-0.11用的就是这种方式。

方式3:方波发生器方式(Square Wave Mode)
该方式输出的是方波。如果初始计数值是N, 那么方波的频率是输入时钟的N分之一。该方式的特点是方波占空比约为1比1 (当N为奇数时略有差异),并且在计数器递减过程中若重新设置新的初始值,这个初始值要到前一个计数完成后才起作用。

在工作方式3下,方波的频率是输入时钟频率的N分之一,又因为计数器的输入时钟频率是 1.193180MHz=1193180Hz,所以

         1193180/N = 方波的频率(Hz)

如果想让计数器每10ms(=100Hz)发出一个方波上升沿用以产生中断请求信号的话,那么N=1193180/100.

Linux 0.11操作系统只对8254的计数器通道0进行了重新设置,使得该计数器工作在方式3下,计数初始值采用二进制,并且初始计数值被设置为LATCH (1193180/100)。即让计数器0每间隔10毫秒发出一个方波上升沿以产生中断请求信号(IRQ0)。

    movl $11931, %eax        # timer frequency 100 HZ 
    movl $0x40, %edx
    outb %al, %dx            # 先写低字节
    movb %ah, %al
    outb %al, %dx            # 再写高字节

继续上文的代码,在写入控制字后,要写入初始计数值。因为控制字选择了0通道,所以写初始计数值的端口是0x40. 如果要产生100Hz的方波,那么写入的初始值是1193180/100 ,约等于 11931。