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

2023-11-30 01:36

本文主要是介绍【接口技术】实验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个数码管,并通过段码片选进行数字图案的显示。段码的控制如下图所示。

这篇关于【接口技术】实验3:可编程并行接口8255的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/435101

相关文章

STM32(十一):ADC数模转换器实验

AD单通道: 1.RCC开启GPIO和ADC时钟。配置ADCCLK分频器。 2.配置GPIO,把GPIO配置成模拟输入的模式。 3.配置多路开关,把左面通道接入到右面规则组列表里。 4.配置ADC转换器, 包括AD转换器和AD数据寄存器。单次转换,连续转换;扫描、非扫描;有几个通道,触发源是什么,数据对齐是左对齐还是右对齐。 5.ADC_CMD 开启ADC。 void RCC_AD

HNU-2023电路与电子学-实验3

写在前面: 一、实验目的 1.了解简易模型机的内部结构和工作原理。 2.分析模型机的功能,设计 8 重 3-1 多路复用器。 3.分析模型机的功能,设计 8 重 2-1 多路复用器。 4.分析模型机的工作原理,设计模型机控制信号产生逻辑。 二、实验内容 1.用 VERILOG 语言设计模型机的 8 重 3-1 多路复用器; 2.用 VERILOG 语言设计模型机的 8 重 2-1 多

61.以太网数据回环实验(4)以太网数据收发器发送模块

(1)状态转移图: (2)IP数据包格式: (3)UDP数据包格式: (4)以太网发送模块代码: module udp_tx(input wire gmii_txc ,input wire reset_n ,input wire tx_start_en , //以太网开始发送信

LTspice模拟CCM和DCM模式的BUCK电路实验及参数计算

关于BUCK电路的原理可以参考硬件工程师炼成之路写的《 手撕Buck!Buck公式推导过程》.实验内容是将12V~5V的Buck电路仿真,要求纹波电压小于15mv. CCM和DCM的区别: CCM:在一个开关周期内,电感电流从不会到0. DCM:在开关周期内,电感电流总会到0. CCM模式Buck电路仿真: 在用LTspice模拟CCM电路时,MOS管驱动信号频率为100Khz,负载为10R(可自

HCIA--实验十:路由的递归特性

递归路由的理解 一、实验内容 1.需求/要求: 使用4台路由器,在AR1和AR4上分别配置一个LOOPBACK接口,根据路由的递归特性,写一系列的静态路由实现让1.1.1.1和4.4.4.4的双向通信。 二、实验过程 1.拓扑图: 2.步骤: (下列命令行可以直接复制在ensp) 1.如拓扑图所示,配置各路由器的基本信息: 各接口的ip地址及子网掩码,给AR1和AR4分别配置

OpenGL/GLUT实践:流体模拟——数值解法求解Navier-Stokes方程模拟二维流体(电子科技大学信软图形与动画Ⅱ实验)

源码见GitHub:A-UESTCer-s-Code 文章目录 1 实现效果2 实现过程2.1 流体模拟实现2.1.1 网格结构2.1.2 数据结构2.1.3 程序结构1) 更新速度场2) 更新密度值 2.1.4 实现效果 2.2 颜色设置2.2.1 颜色绘制2.2.2 颜色交互2.2.3 实现效果 2.3 障碍设置2.3.1 障碍定义2.3.2 障碍边界条件判定2.3.3 障碍实现2.3.

pta-2024年秋面向对象程序设计实验一-java

文章申明:作者也为初学者,解答仅供参考,不一定是最优解; 一:7-1 sdut-sel-2 汽车超速罚款(选择结构) 答案: import java.util.Scanner;         public class Main { public static void main(String[] arg){         Scanner sc=new Scanner(System

如何校准实验中振镜频率的漂移

在实验过程中,使用共振扫描振镜(如Cambridge Technology的8kHz振镜)时,频率漂移是一个常见问题,尤其是在温度变化或长期运行的情况下。为了确保实验的准确性和稳定性,我们需要采取有效的校准措施。本文将介绍如何监测、调节和校准振镜频率,以减少漂移对实验结果的影响。 1. 温度管理和稳定性控制 振镜的频率变化与温度密切相关,温度的升高会导致机械结构的变化,进而影响振镜的共

实验C语言“union”的最基础语法

目标 最近在看Rust的“菜鸟教程”,看到 Rust 枚举类 时我发现它所定义的“枚举类”虽然也能像C语言枚举类那样使用,但是多了些功能:对于某个枚举的成员,还可以附带独特的数据,这让我想起了C语言中的union。 而我事实上对union没有使用经验,我自己写程序的时候不用它,看其他的项目的程序时印象里也没见过它。所以我对union的设计意图理解不深(可能只是为了节省内存?)。本篇的目标是对其

Oracle高级压缩和透明数据加密组合实验

本文参考了实验DB Security - Advanced Compression with Transparent Data Encryption(TDE),其申请地址在这里。 本文只使用了实验中关于高级压缩和在线重定义的部分。并对要点进行说明及对实验进行了简化。 准备:环境设置 原文中的实验环境实际上是改自Oracle示例Sample Schema,其实唯一的改动就是去掉了SALES表中