【接口技术】实验3:可编程并行接口8255

实验3 可编程并行接口8255实验

一、实验目的

1:了解8255芯片结构及编程方法。

2:了解8255输入/输出实验方法。

3:掌握8255控制键盘及显示电路的基本功能及编程方法。

4:掌握一般键盘和显示电路的工作原理。

二、实验内容

1:8255并行I/O输入/输出实验

8255是Intel公司生产的可编程外围接口电路,简称PPI。它有A、B、C三个八位端口寄存器,通过24位端口线与外部设备相连,其中C口可分为上半部和下半部。这24根端口线全部为双向三态。三个端口可分二组来使用,可分别工作于三种不同的工作方式。

(1)将实验的线路连接好后进行编程,将8255的C口作为输入,输入信号由8个逻辑电平开关提供,A口作为输出,其内容由发光二极管来显示。

(2)编程从8255C口输入数据,再从A口输出。

(3)接线,如下表所示。

待接线接口1

待接线接口2

8255的CS端

I/O地址译码的Y1端

8255的JP6端(PA7——PA0),A口

LED显示的JP2端(L7——L0)

8255的JP8端(PC7——PC0),C口

逻辑开关的JP1端(K7——K0)

(4)程序的流程图,如下图所示。

2:4*4键盘键号显示实验

(1)编程程序

设置8255C口键盘输入、A口为数码管段码输出,使得在小键盘上每按一个键,8位数码管上显示出相应字符。即,8255控制寄存器端口地址28BH、A口的地址288H、C口的地址28AH。

(2)接线,如下表所示。

待接线接口1

待接线接口2

8255的CS端

I/O地址译码的Y1端

8255的JP6端(PA7——PA0)

数码管的JP3端(DP——A)

8255的JP8端(PC7——PC0)

4*4键盘的JP13端(行3——列0)

数码管的S0端

+5V

(3)程序的流程图,如下图所示。

三、源程序(含注释)

实验内容1:

P8255A    EQU  288H     ;a port

P8255C    EQU  28AH     ;c port

P8255reg  EQU  28BH     ;register port, CS

code segment

    assume cs:code

start:                  ;写方式控制字

    mov bx,200          ; BX <- 200

L1:

    mov cx,0            ; CX <- 0

L2:

    loop L2             ; CX == 0,跳出循环,所以相当于 NOP

    dec bx              ; BX--

    jne L1              ; if BX != 0 goto L1

    ; delay

    mov dx,P8255reg     ;move cs to dx,便于写入控制命令

    mov al,10001001b    ;方式0输出,A口输出且PC输入,所以是10001001

    out dx,al           ;output to leds

next:

    mov dx,P8255C       ;move c-port to dx

    in al,dx            ;input to al

    mov dx,P8255A       ;move a-port to dx

    out dx,al           ;output al

    mov ah,1            ;use function-1

    int 16h

    je next             ;if zf==1, jump to next

exit:

    mov ah,4ch          ;return dos

    int 21h

code ends

end start

实验内容2:

a8255 equ 288H    ;8255 A  

c8255 equ 28aH    ;8255 C

k8255 equ 28bH    ;8255 CS

data segment

table1 dw 0770h,0B70h,0D70h,0E70h,07B0h,0BB0h,0DB0h,0EB0h        ;键盘行列码表

       dw 07D0h,0BD0h,0DD0h,0ED0h,07E0h,0BE0h,0DE0h,0EE0h

LED    DB 3FH,06H,5BH,4FH,66H,6DH,7DH,07H,7FH,6FH,77H,7CH        ;LED段码表,分别代表0~F

       DB 39h,5EH,79h,71h,0ffh

char  db '0123456789ABCDEF'                                      ;字符表

mes   db 0ah,0dh,'PLAY ANY KEY IN THE SMALL KEYBOARD! ',0ah,0dh  ;提示信息

      db 'IT WILL BE ON THE SCREEN! END WITH E ',0ah,0dh,'$'

key_in db 0h

data ends

stacks segment stack

     db 100 dup (?)

stacks ends

code segment

        assume cs:code,ds:data,ss:stacks,es:data

start:

        cli                       ;禁止中断发生

        mov ax,data               ;data放入ax

        mov ds,ax                 ;data进入ds

        mov es,ax                 ;data进入es

        mov ax,stacks             ;堆栈stacks放入ax

        mov ss,ax                 ;堆栈进入ss

        mov dx,offset mes         ;输出mes提示信息

        mov ah,09                 ;use function-9

        int 21h                   ;在屏幕上显示字符串

        ;need to add          

        mov dx,k8255              ;move cs to dx,便于写入控制命令

        mov al,10000001b          ;方式0输出,A口输出且C口高四位输出,低四位输入

        out dx,al                 ;控制字写入dx

main_key:

        call key                  ;调用key子程序

        call display              ;调用display子程序

        cmp byte ptr key_in,'E'   ;比较是否按下“E”

        jnz main_key              ;zf==0 jump to main-key

        mov ax,4c00h              ;返回dos4cH

        int 21h                  

key proc near                    

key_loop:                        

        mov ah,1                  ;use function-1

        int 16h                   ;按下任何键,将其对应字符的ASCII码送入AL中,并在屏幕上显示该字符

        jnz exit                  ;zf==0 jump to exit

        ;need to add

        mov dx,c8255            ;选定c

        in al,dx                ;c口输入

        and al,0FH              ;0000 1111作与运算,消除高位保留低位

        cmp al,0FH              ;0FH进行比较,如果没有按键按下,则相等

        jz key_loop             ;zf==1 jump to key_loop

        call delay              ;调用延时

        ;need to add

        mov ah,al               ;al移动到ah,即行码存入ah

        mov dx,k8255            ;选定控制口

        mov al,10001000b        ;方式0输出,A口输出且C口高四位输入,低四位输出

        out dx,al               ;控制字写入dx

        mov dx,c8255            ;选定c

        in al,dx                ;c口输入

        and al,0F0H             ;1111 0000作与运算,消除低位保留高位

        cmp al,0F0H             ;F0H进行比较,如果没有按键按下,则相等

        jz key_loop             ;zf==1 jump to key_loop

        mov si,offset table1    ;si保存行列码表的首地址

        mov di,offset char      ;di保存字符表的首地址

        mov cx,16               ;待查字符个数为16,即0-9A-F

key_tonext:

        cmp ax,[si]             ;比较ax和行列码表

        jz key_findkey          ;zf==1,则跳转到key-findkey(即找到对应码了)

        dec cx                  ;cx--(没找到,则待查找个数减1

        jz key_loop             ;zf==1,则跳转到key-loop(如果移动出了字符表,则继续主循环)

        add si,2                ;si+=2(没找到,则码表移动)

        inc di                  ;di++(没找到,则字符表移动)

        jmp key_tonext          ;无条件跳转到key-tonext,继续查找

key_findkey:

        mov dl,[di]             ;比较dl和字符表

        mov ah,02               ;use function-2

        int 21h                 ;屏幕显示一个字符

        mov byte ptr key_in,dl  ;字符存入key-in,便于比较是否为E

key_waitup:

        mov dx,k8255            ;控制字端口调用

        mov al,81h              ;1000 0001写入al

        out dx,al               ;写入控制字

        mov dx,c8255            ;调用c

        mov al,0fh              ;0000 1111写入al

        out dx,al               ;写入控制字

        in al,dx                ;读行扫描

        and al,0fh              ;作与运算,消除高位

        cmp al,0fh              ;比较低位是否有按下

        jnz key_waitup          ;zf==0 继续扫码

        call delay              ;调用延时

        ret                     ;使用堆栈

exit:

        mov byte ptr key_in,'E' ;E送入key-in

        ret                     ;使用堆栈

key endp

delay proc near

        push ax                 ;堆栈塞入数据

        mov ah,0                ;use function-0

        int 1ah                 ;等待输入

        mov bx,dx               ;dx送入bx

delay1:

        mov ah,0                ;use function-0

        int 1ah                 ;等待输入

        cmp bx,dx               ;比较dxbx

        jz delay1               ;zf==1 继续等待输入

        mov bx,dx               ;dx送入bx

delay2:

        mov ah,0                ;use function-0

        int 1ah                 ;等待输入

        cmp bx,dx               ;比较dxbx

        jz delay2               ;zf==1 继续等待输入

        pop ax                  ;堆栈弹出数据

        ret                     ;使用堆栈

delay endp

display PROC near

        push ax

        mov bx,offset LED       ;led首地址送入bx

        mov al,byte ptr key_in  ;key-in送入al

        sub al,30h              ;al减去30H,因为0-9ASCII30H-39H,因此减去之后得到数字本身

        cmp al,09h              ;比较是哪一个数字

        jng DIS2                ;if not greater, jump to dis2(即是数字就跳转到dis2

        sub al,07h              ;al减去07H,因为A-FASCII97H-102H,因此减去之后得到字母本身

DIS2:  

        xlat

        mov dx,a8255            ;选定a

        out dx,al               ;a口输出

        pop ax                  ;弹出数据

        ret

display endp                      

code ends

end start

四、遇到的问题和解决过程

问题1:在实验2中,一开始按下键盘后所输出的数是沿键盘主对角线对称的那个数。

解决1:经过线路检查发现,实验箱上的接口是A——DP,而实验指导书上的内容是DP——A,因此需要将并口接线旋转并口接线180°再插入到数码管的接口。

问题2:在实验2中,发现数码管在遇到字母按键输入时,无法正常显示。

解决2:对程序进行断点测试,发现在下面代码段中的【jng DIS2】无法成功编译。后续改成jle指令(小于等于)之后,程序可以正常运行。我们怀疑可能存在的问题是实验室电脑上的编译器无法兼容jng指令(不大于)。(后续重启程序,修改为jng后也可以正常运行,因此我们也不太确定这个问题所引发的原因。)

问题3:在实验2中,实验指导书令S0接地(GND),此时无论键盘输入什么内容,数码管都不会显示。

解决3:实验指导书编写错误(如下图所示),应该是令S0接VCC(+5V)。只有将S0赋高电平使得位选成功后,才会在右边第一个数码管显示。

问题4:在实验2中,实验指导书上的图标注键盘的行是C口的高4位,如果不仔细甄别会写错代码的方式控制字。

解决4:实验指导书编写错误(如下图所示)。经过分析后得出,键盘的行应该是C口的低4位,因此需要在对键盘的行进行输入的时候,应该对pc低位进行输入设置,并写出对应的方式控制字。同理,对键盘的列进行相应的控制字编写。

五、实验结果

实验内容1:

(1)拨码开关输入,LED灯输出

如下图所示,当设置低5位拨码开关为1、高3位拨码开关为0时,LED会进行对应的显示,即低5位处于亮起状态、高3位处于熄灭状态。

(2)完整操作过程

完整操作过程如视频附件3-1.mp4所示。在视频中,我们依次测试了拨码开关先设置为1和再设置为0的结果。

实验内容2:

(1)键盘输入非E字母

如下图所示,当按下按键【A】时,数码管显示A,且PC屏幕上显示A。

(2)键盘输入数字

如下图所示,当按下按键【2】时,数码管显示2,且PC屏幕上显示2。

(3)键盘输入E字母

如下图所示,当按下按键【E】时,数码管显示E,且PC屏幕上显示E。同时,可以看到程序检测到用户输入【E】并执行终止,并输出【done!】字符串。

 (4)完整操作过程

完整操作过程如视频附件3-2.mp4所示。在视频中,我们依次测试了数字、非E字母和E字母。

六、体会与总结

1:进一步巩固了8255方式控制字的使用。在实验2中,如果需要对8255的输入/输出端口进行修改,需要进行以下两个步骤。第一,在开头对端口进行重定义,并注意A口到C口的地址是依次分布的,例如在本实验中A口是288H、B口是289H、C口是28AH。第二,对方式控制字进行修改,但是有可能修改后的控制字仍然保持不变。例如,如果在键盘的列输入时,将输出从A口变为B口,则需要把控制字从【10001001】变成【10001001】,虽然二者在码字内容上相同,但是编写的思路是不同的。编写思路如下表所示,其中橘色部分为二者思路不同的地方。

D7

D6

D5

D4

D3

D2

D1

D0

输出是A口

特征位1

A组采用方式0,置为00

A口输出,置为0

PC高位输入,置为1

B组默认为0

B口默认为0

PC低位输入,置为1

输出是B口

特征位1

A组默认为00

A口默认为0

PC高位输入,置为1

B组采用方式0,置为0

B口输出,置为0

PC低位输入,置为1

2:学习了一般键盘和显示电路的工作原理。一般的矩阵键盘是通过行和列的输入判断按键是否按下的,例如在本实验中,行由低4位进行控制,列由高4位进行控制,且初始时行码和列码均为1,当有按键按下后,对应的位置会变为0。一般的显示电路是采用段码和位码对数码管进行显示控制,例如在本实验中,通过VCC片选S0,即选中第0个数码管,并通过段码片选进行数字图案的显示。段码的控制如下图所示。

  • 20
    点赞
  • 39
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

MorleyOlsen

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值