
定时与计数的本质 定时:本质上是对时间基准的计数,将固定周期作为标准进行累积 计数器:对非周期性脉冲信号累计,通过加1或减1实现 定时器:对周期性时钟信号计数,按输入周期产生定时输出
实现方式对比
|------------|------|--------------|
| 硬件电路 | 专用电路 | 通用性、灵活性差 |
| 软件方式 | 程序实现 | 占用CPU时间 |
| 可编程定时器/计数器 | 程序控制 | 灵活,可与CPU并行工作 |

8253主要功能 3个独立的16位计数器, 每个计数器有 6种工作方式(通过程序设置)、可按二进制或BCD码计数 计数速率高达 2MHz 所有引脚电平与TTL兼容(单电源+5V)

引脚
GATE:硬件输入引脚,不能通过软件指令直接触发,没有对应的寄存器位,CPU 无法执行一条指令(如 OUT 或 MOV)来直接改变 GATE 引脚的电平。
只有在系统电路中通过额外硬件桥接(如通过 OUT 指令控制 8255 输出低电平或高电平),才能用软件操作间接改变 GATE 状态。所以下文暂且将GATE上升沿归于硬件。
| CLK0~CLK2 | 计数器0~2的时钟输入 |
|---|---|
| GATE0~GATE2 | 计数器0~2的门控信号 |
| OUT0~OUT2 | 计数器0~2的输出 |
| CS | 片选信号 |
| RD/WR | 读/写控制 |
| A1, A0 | 地址线,选择寄存器 |
控制线
| CS | RD | WR | A1 | A0 | 操作 |
|---|---|---|---|---|---|
| 0 | 1 | 0 | 0 | 0 | 写入计数器#0 |
| 0 | 1 | 0 | 0 | 1 | 写入计数器#1 |
| 0 | 1 | 0 | 1 | 0 | 写入计数器#2 |
| 0 | 1 | 0 | 1 | 1 | 写入控制寄存器 |
| 0 | 0 | 1 | 0 | 0 | 读计数器#0 |
| 0 | 0 | 1 | 0 | 1 | 读计数器#1 |
| 0 | 0 | 1 | 1 | 0 | 读计数器#2 |
| 0 | 0 | 1 | 1 | 1 | 无操作(三态) |
| 1 | × | × | × | × | 禁止(三态) |
控制字(CW,Control Word)
当控制线为CS=0, WR=0, RD=1, A1=1, A0=1,数据总线上的 8 位数值才会被解释为控制字 写入控制寄存器。

选择计数器(SC1 SC0):指定该控制字配置哪个计数器
读写操作 (RL1 RL0):定义如何读写16位的计数器初值
工作方式(M2 M1 M0):选择6种工作方式之一
计数制式(BCD):选择计数值是二进制(0)还是BCD码(1)
| SC1 SC0 (D7 D6) | 00 | 选择计数器0 |
|---|---|---|
| 01 | 选择计数器1 | |
| 10 | 选择计数器2 | |
| 11 | 无意义 | |
| RL1 RL0 (D5D4) | 00 | 锁存命令(用于读操作) |
| 01 | 只读/写低8位 | |
| 10 | 只读/写高8位 | |
| 11 | 先读/写低8位,后读/写高8位 | |
| M2 M1 M0 (D3D2D1) | 000 | 方式0 |
| 001 | 方式1 | |
| ×10 | 方式2 | |
| ×11 | 方式3 | |
| 100 | 方式4 | |
| 101 | 方式5 | |
| BCD (D0) | 0 | 二进制计数 |
| 1 | BCD码计数 |
Operating Mode
下文缩写含义:
CR, Count Register,计数初值寄存器。
CE, Counting Element,即减1计数器。
0:事件计数(软件触发)

8253内部没有中断控制电路,可以用OUT信号作为中断请求信号(OUT上升沿)。
| 启动方式 | 写入计数初值(软件触发) |
|---|---|
| OUT | 计数期间输出低电平,计数结束变高电平并保持 |
| GATE | GATE=0暂停计数,GATE=1恢复计数 |
| 计数过程中传入新的初值 | 立即有效。重新开始计数(8位,另外8位置0)写第1个字节暂停,写第二个字节后有效(16位) |
| 计数值使用 | 只计一遍,无重装. 只有在写入另一个计数值时,OUT变低,才开始新的计数 |
时序特点:
写入控制字CW后,OUT变低
写入初值后,经过一个CLK脉冲,初值装入CE开始减1计数,即计数初值若为N,在N+1个CLK脉冲后输出信号OUT变为高电平
CE=0时,OUT变高并保持

例:计数器1,方式0,只写低8位,二进制,计数值128
MOV AL, 50H ; 控制字:01 01 000 0B
OUT 07H, AL ; 写入控制寄存器
MOV AL, 80H ; 计数值128
OUT 05H, AL ; 写入计数器1
1:可编程单稳态触发(硬件触发)

| 启动方式 | GATE上升沿触发(硬件) |
|---|---|
| 输出波形 | 若初值N,输出宽度为 N个CLK周期的负脉冲 |
| GATE | 上升沿可重新触发,重新开始计数 |
| 新初值 | 下一轮有效(需新的GATE上升沿,即当原来计数还没结束,就终止原来的计数过程,开始新的一轮计数) |
| 计数值使用 | 有条件重装(需GATE触发) |
写入控制字CW后OUT为高
写入初值后不立即计数,等GATE上升沿后的第一个CLK下降沿才开始
计数期间OUT为低电平, CE=0时结束变高电平

0和1的主要区别就是1多了一个用GATE上升沿驱动的重装初值,1可以有条件复活(多命,可以被Gate上升沿拉起),0血量没了就out了(一命)。
2:频率发生器(分频器),软硬兼施
既可软件启动,又可硬件启动(软硬兼施)

占空比:高低电平的比例(高电平:低电平)。
| 启动方式 | 写入初值(软件)/GATE上升沿(硬件) |
|---|---|
| 输出波形 | 若初值N,周期性输出,占空比 (N-1):1 的矩形波 |
| GATE | GATE=0停止,GATE=1恢复,恢复时(即GATE上升沿)重新从初值开始 |
| 新初值 | 等当前计数结束,下一轮有效 |
| 计数值使用 | 自动重装,连续输出 |
写入控制字CW后OUT为高,下一个𝑾𝑹信号的上升沿写入计数初值,若GATE为高电平则在该𝑾𝑹信号之后的第一个时钟下降沿开始减1计数
CR内容自动重复装入CE,OUT端上就能连续地输出周期性分频信号(1/N),负脉冲宽度为1个CLK周期
改变计数初值,即可获得不同速率的OUT输出信号

在血量没了的情况下(CE=0),1是有条件复活,到2就变成自动复活(跟王者一样,不过2复活时间固定为1个CLK负脉冲)。
3:方波发生器,软硬兼施

| 启动方式 | 写入初值(软件)/GATE上升沿(硬件) |
|---|---|
| 输出波形 | 初值N,占空比约 N/2 : N/2(分奇偶)的方波 |
| GATE作用 | 同方式2 |
| 新初值 | 同方式2 |
| 计数值使用 | 同方式2 |
N为偶数时,高低电平各N/2个CLK
N为奇数时,高电平(N+1)/2,低电平(N-1)/2
主要应用:方波发生器、波特率发生器

2、3类似,不同就是OUT波形的占空比不同。
4:软件触发选通

| 启动方式 | 写入计数初值(软件触发) |
|---|---|
| 输出波形 | 计数期间高电平,结束时输出1个CLK宽度的负脉冲 |
| GATE作用 | GATE=0停止计数 |
| 新初值 | 同方式0 |
| 计数值使用 | 同方式0 |
与方式0的区别在于OUT波形:
0:OUT计数期间低电平,结束变高并保持
4:OUT计数期间高电平,结束输出一个负脉冲后恢复高

5:硬件触发选通

| 启动方式 | GATE上升沿触发 |
|---|---|
| 输出波形 | 计数期间高电平,结束时输出一个CLK宽度的负脉冲 |
| GATE作用 | 上升沿随时触发新计数 |
| 新初值 | 下一轮有效(需新的GATE上升沿) |
| 计数值使用 | 自动重装(需GATE触发) |
与方式1的区别:
1:计数期间输出宽负脉冲(N个CLK)
5:计数期间高电平,结束输出窄负脉冲(1个CLK)

To sum up:
| 方式0 | 方式1 | 方式2 | 方式3 | 方式4 | 方式5 | |
|---|---|---|---|---|---|---|
| 功能 | 事件计数 | 单脉冲 | 频率发生器 | 方波发生器 | 软件触发 | 硬件触发 |
| 启动方式 | 写入初值 | GATE上升沿 | 写入初值或GATE↑ | 写入初值或GATE↑ | 写入初值 | GATE上升沿 |
| 中止计数 | GATE=0 | - | GATE=0 | GATE=0 | GATE=0 | - |
| 写入新初值 | 立即有效 | 下一轮 | 下一轮 | 下一轮 | 立即有效 | 下一轮 |
| 计数值使用 | 一次有效 | 自动重装 | 自动重装 | 自动重装 | 一次有效 | 自动重装 |
分组
|------|-------|---------------------|
| 软件触发 | 0 和 4 | 无自动重装;区别在OUT波形 |
| 硬件触发 | 1 和 5 | GATE上升沿启动;区别在输出脉冲宽度 |
| 自动重装 | 2 和 3 | 软硬兼可,持续输出;区别在占空比 |
8253初始化编程
① 写入计数器控制字 → 控制寄存器
② 写入计数值 → 对应计数器端口
-
三个通道控制字端口地址相同,由SC1、SC0区分
-
BCD计数时,指令中仍写十六进制表示的BCD数
-
例:计数初值50,BCD计数 → 写 50H
例1:计数器0,方式1,BCD计数,计数值5080H,端口F8H~FBH
; 控制字:0011 0011B = 33H
; SC=00(计数器0), RL=11(先低后高), M=001(方式1), BCD=1
MOV AL, 33H
OUT 0FBH, AL ; 写控制字
MOV AL, 80H ; 低8位
OUT 0F8H, AL
MOV AL, 50H ; 高8位
OUT 0F8H, AL
例2:计数器0,方式3,输出2kHz方波,CLK=2.5MHz,BCD计数,端口80H~83H
计算计数值:
控制字:0011 0111B = 37H
-
SC=00, RL=11(先低后高), M=011(方式3), BCD=1
MOV AL, 37H ; 控制字
OUT 83H, AL
MOV AL, 50H ; 低8位 (50H = BCD的50)
OUT 80H, AL
MOV AL, 12H ; 高8位 (12H = BCD的12)
OUT 80H, AL ; 计数值 = 1250 (BCD)
为什么要锁存?
CPU读取16位计数值时,若计数器正在工作,高8位和低8位可能不属于同一个值,导致读取错误。
锁存方法
-
利用GATE信号使计数暂停
-
利用锁存控制字:RL1RL0 = 00