可编程并行接口芯片8255A

功能与结构

  • D0-D7:数据线。
  • A1-A0:地址线,用于选择4种端口。
    • 00:A口
    • 01:B口
    • 10:C口
    • 11:控制字
  • 时钟信号:没有,是异步的。
  • 3个8位I/O口
    • A口:PA0-PA7,常做数据端口。
    • B口:PB0-PB7,常做数据端口。
    • C口:PC0-PC7,可以作为数据端口、状态口、控制口。
  • 两组控制逻辑
    • A组:控制PA和PC_{7-4}
    • B组:控制PC_{3-0}和PB
  • 其他信号
    • RD*:读信号
    • WR*:写信号
    • RESET:复位信号
    • CS*:片选信号。

地址示意图

示意图

根据连线的芯片不同

  • 如果是8088这种8位数据线:地址是连续的。
  • 如果是8086这种16位数据线:
    • 数据线:用低8位。
    • 地址线:A0=0表示使用低8位。因为A0=1走的是数据线高8位。所以8255连接8086的时候,**A0必须是0**,这就导致了地址都是偶数。

控制字

什么是控制字

  • 控制字是一个八位数,要送到控制口里。
  • 在8255中,A1A0=11就表示送到控制口。

控制字的分类

  1. 方式控制字。
  2. C口置位/复位控制字

方式控制字

示意图:1入0出。

解释

  • D7=1:标志位,表示是方式控制字。
  • D6-D5:端口A口的工作方式,有00、01、10三种。
  • D4:端口A是输入还是输出。1表示输入。
  • D3:端口C高4位是输入还是输出。
  • D2:端口B的工作方式。有0和1两种。
  • D1:端口B是输入还是输出。1表示输入。
  • D0:端口C低4位是输入还是输出。1表示输入。

例1:要求A以方式1输入,C上半部分输出,C下半部分输入,B以方式0输出。

那么方式控制字:1011 0001 = B1H

初始化的程序段:

# 假设控制端口是FFFEH
MOV DX,FFFEH
MOV AL,0B1H
OUT DX,AL

C口置位/复位控制字

如果要占用C口,就需要对C

示意图

解释

  • D7=0:标志位,表示C口置位/复位控制字
  • D3-D1:位选择。分别选择PC0-PC7
  • D0:表示这是置位or复位

例子

  • 题目:从PC5输出一个正脉冲,假设8255的端口地址是60H-63H,写出汇编程序。
  • 分析:输入正脉冲,就是先设置1然后设置0。
MOV AL, 00001011 ; PC5=1的控制字
MOV DX,63H
OUT DX,AL
MOV AL, 00001010 ; PC5=0的控制字
OUT DX,AL

8255的工作方式

8255的工作方式有两种:

  • 方式0:基本的I/O方式。用于无条件传送查询方式的接口电路。
  • 方式1:选通的I/O方式。用于查询和中断方式的接口电路。
  • 方式2:双向选通传送方式。
    • 适用于双向传送数据的外设。
    • 适用于查询和中断方式的接口电路。

方式0:基本I/O方式

特点

  • 适用场景为无需应答联络的场合。
    过程
  • 处理器执行IN:产生读信号RD,控制8255A从端口读取外设数据。然后从D0-D7输入到CPU。
  • 处理器执行OUT:产生写信号WR,将CPU数据从D0-D7传送给8255,8255提供给外设。也就是说,输出的时候8255起到数据锁存的作用

例子

MOV AL,9AH
;1001 1010
;即设置方式控制字,A口为方式0,PA入,PC高入,B口方式0,B口入,C口低出
OUT 63H, AL

方式1:选通I/O方式

  • 场景:查询和中断方式。A、B口都可以工作到方式1,作为输入/输出。
  • 输入时,三种引脚
    • STB:数据选通信号。表示外设数据已经准备好了。
    • IBF:输入缓冲期满信号。表示端口已经接受数据。
    • INTR:中断请求信号,请求CPU接受数据。
    • INTE:中断允许触发器。
  • 输出时,三种引脚
    • ACK:外设响应信号,表示外设已经收到数据。
    • OBF:输出缓冲信号满信号,表示CPU已经输出了数据。
    • INTR:中断请求信号,请求CPU再次输出数据
    • INTE:中断允许触发器。
  • 特点
    • PA、PB口之一工作于方式1时,PC口就有3位需要配合。此时,另一个端口以及PC口其它数据位可以工作于方式0.
    • PA、PB口都工作于方式1时,PC口就有6位需要配合,其余2位仍可作I/O。

方式1又分为

  • 选通输入方式
  • 选通输出方式
  • 选通输入输出方式

例1:A口选通输入方式

解释

  • 根据控制字高4位可以知道,A口是选通输入
  • 外设的8位的数据从PA口进入,外设占用PC4口发送STB_A的负脉冲,表示要输入数据。
  • 8255向外设发送IBF_A表示输入缓冲区满,占用PC5口
  • 内部的中断使能和IBF_A都是1,则发出中断信号INTRA,告诉CPU将数据取走,占用PC3口。
  • CPU执行READ指令将数据读走,此时IBF变低。

例2:选通输出

一个道理,只不过输入输出反过来。

方式2:双线总线方式

特点

  • 只有A口能工作于此方式,既能输出又能输入,但不能同时。
  • A口工作于方式2,B口可工作于方式0或者方式1
  • PB方式0:PC2-0可以作I/O
  • PB方式1:PC2,1,0作B口的联络线。

例子:主机和软盘交换数据。

C口状态字

通过读取C口状态字,可以测试或者检查外设状态。

方式1状态字

方式2状态字

重点例题

例1:基本I/O

题目:检测开关K0-7的状态,并用LED0-7实时指示。

电路图

分析

  • 第一步:对芯片进行初始化,确定端口地址
    • 根据片选确定A4A3A0为100,A7=1才能开启74LS138,A5A6必须是11。
    • A2A1就是选端口
    • 这样就可以确定A口的地址:1111 0000=F0
    • 这样就可以确定B口的地址:1111 0100 = F2
    • C口:F4
    • D口:F6
  • 第二步:查询程序
    • 写控制字:
      • 方式控制字:标志位1、A口工作方式0、入、B口方式0,B出、C出=10010000=90H
    • 从A口读:IN
    • 从B口写:OUT
  • 第三步,写程序
MOV DX,0F6H # 控制口地址
# 标志位 A口方式2 D4-D0 根据输入输出
MOV AL,90H # 控制字:1|00|1|0000
OUT DX,AL # 写控制字
TEST1:
MOV DX,0F0H # A口地址
IN AL,DX # 从A读数据
MOV DX,0F2H # B口地址
OUT DX,AL # 将数据送到B
CALL DELAY # 调用等待
JMP TEST1

例2:用数码管实时显示K3-K0的16种组合状态

题目
假定四个端口的地址分别是60H-63H。编程用数码管实时显示K3-K0的16种状态。

电路图

数码管

分析

; 段码表
TAB:
DB 40H,79H,24H,30H,19H,12H,02H,78H;
DB 00H,18H,08H,03H,43H,21H,06H,0EH;
; 方式控制字
MOV AL,10010000B; 方式0 A入B出
MOV DX,63H
OUT DX,AL
; 从K3-K0输入
IN_PORTA:
MOV DX,60H
IN AL,DX
; 对输入进行处理
AND AL,0FH ; 看电路图,高4位不要
MOV BX, OFFSET TAB ; 段码表基地址
XLAT ; 查表,BX+偏移量=>AL
; 输出
MOV DX,61H
OUT DX,AL
CALL DELAY
JMP IN_PORTA

例3:键盘电路

独立式按键和矩阵按键

独立式按键:一个端口连接一个开关。

矩阵连接:行列交叉连接。起作用的是四根行线:PA0-PA3,四根列线:PB0-PB3

原理:行线全0,列线全1表示没有键被按下。

编程要点

  1. 确定是否有键按下——行线置0(OUT)读列线(IN)——重点
    1. 初始化:设置行线是输出,列线是输入方式。
    2. 发行码0:行线输出全0
    3. 读列码:判断列线是否全1,否说明有键被按下
    4. 例子:6号线被按下了,那么PB1=0——说明有键被按下了。
    5. 机器键盘需要延时去抖动再次判断
  2. 确定键的位置——逐行扫描法
    1. 发行码:每次仅一行输出0,从第0行开始。
    2. 读列码:判断列线,如果全1,则闭合键不在此行。如此逐行判断。
    3. 获得键码:从B口读取行列值编码,即键码-->AL,前四位为0的是行,后四位为0的是列。
  3. 确定键名:将键码预先排列成表,通过获得键码查表确定键名。

假定A的端口地址是:0FF9H

; 1. 端口地址
PORT_A EQU 0FF9H;
PORT_B EQU 0FFBH;
PORT_CTL EQU 0FFFH;
; 2. 键码表
; 9号键是1101 1011
DATA SEGMEMT
TABLE
DB 77H,7BH,7DH,7EH,0B7H,0BBH,0BDH,0BEH;
DB 0D7H,0DBH,0DDH,0DEH,0E7H,0EBH,0EDH,0EEH;
DATA ENDS
; 程序开始
START:
; 初始化8255控制字:A出B入
;1(标)00(A方式)0(A)0(C)0(B方式)1(B入)0(C)
MOV DX,PORT_CTL
MOV AL,82H
OUT DX,AL

; 确定是否有键按下
MOV AL,0
MOV DX,PORT_A
OUT DX,AL ; 输出行码00H

WAIT_PRES:
MOV DX,PORT_B ; 读列值:B低4位
IN AL,DX
AND AL,0FH
CMP AL,0FH
JE WAIT_PRES ; 列码全1就继续读B口
MOV CX,16EAH ; 延时去抖动
DLY:
LOOP DLY

; 过滤后再判断是否有键按下
IN AL, DX
AND AL,0FH
CMP AL,0FH
JE WAIT_PRES

; 有键按下
MOV AL,0FEH ;行线0设置0,逐行设置
MOV CL,AL;
NEXT_ROW: ; 接口输入输出和判断
MOV DX,PORT_A
OUT DX,AL
MOV DX,PORT_B
IN AL,DX
AND AL,0FH
CMP AL,0FH
JNE ENCODE ; 有键
ROL CL,1 ;有就右移1位
MOV AL,CL 
JMP NEXT_ROW

; 查表确定键值和键名
ENCODE:
MOV BX,000FH ;指针初始指向15,即F键
IN AL,DX ;从B口拿到行列码
NEXT_TRY:
CMP AL,TABLE[BX] ; 查表
JE DONE ; 查到
DEC BX ; 没有查到i--
JNS NEXT_TRY ; 未查完,继续
MOV AH,01H ; 设置错误标志位
JMP EXIT ; 退出
DONE: ;查到了
MOV AL,BL ; 将键盘码-->AL
MOV AH,00H ; 设置有效标志位

EXIT: ; 等待按键释放
MOV AL,0
MOV DX,PORT_A 
OUT DX,AL
MOV DX,PORT_B
WT_OPEN:
IN AL,DX
AND AL,0FH
CMP AL,0FH
JNE WT_OPEN ;发现有键按下继续等待,其实是等待案件释放

8255的应用

IBM PC

打印接口

  • 主机把数据送到DATA0-DATA7,同时送出数据选通信号STROBE*
  • 打印机:
    • BUSY信号线发出忙信号。
    • 处理好输入数据时,撤销忙信号,同时送出i个响应信号ACK*

方式0

方式0输出,C高输出,B方式0防止占用C低,B输出,A,C低输入10000 001

; 控制口地址
MOV DX,0FFFEH
; 方式控制字
MOV AL,1000 0001B
OUT DX,AL
; 让PC7=1
MOV AL, 0000 111 1B
MOV DX, AL

princ:
PROC
PUSH AX
PUSH DX
prn:
MOV DX,0FFFCH ;读取端口C
IN AL,DX ; 查询打印机状态
AND AL,04H ; PC2=BUSY=0?
MOV DX,0FFFF8H ; 打印机不忙,输出数据
MOV AL,AH
OUT DX,AL
MOV DX,0FFFEH; 从PC7送出低脉冲
MOV AL,00001110B; STROBE*=0
OUT DX,AL
NOP ; 产生一定宽度低电平
NOP 
MOV AL,00001111B ; 设置1
OUT DX,AL
; 最终,STROBE 产生低脉冲

方式1