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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/182648.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WS2812灯条基于WLED开源项目无门槛使用简介

WS2812灯条基于WLED开源项目无门槛使用简介 &#x1f4cc;项目github地址&#xff1a;https://github.com/Aircoookie/WLED&#x1f4cd;WLED详情地址&#xff1a;https://kno.wled.ge/&#x1f388;网页在线烧录固件地址&#xff1a;https://install.wled.me/ ✨ 仅作为使用的…

安全技术与防火墙

目录 一、安全技术 1、安全技术 2、防火墙的分类 二、netfilter 1、netfilter简述 2、防火墙工具 1.iptables工具 2.netfilter的四表五链 3.内核中数据包的传输过程 4.三种报文流向 5.实操 总结&#xff1a;本章主要介绍了安全技术与防火墙 一、安全技术 1、安全技…

解决Unable to preventDefault inside passive event listener invocation.报错

报错信息&#xff1a; 这个报错大致说的是&#xff1a;无法在被动事件侦听器调用中防止Default 查了其他博主的解决办法&#xff1a;比如&#xff1a; 1、声明事件监听的时候设置为主动事件监听&#xff1a; window.addEventListener(‘touchmove’, handler, { passive: fal…

【软件测试学习】—软件测试模型(二)

【软件测试学习】—软件测试模型&#xff08;二&#xff09; 我 | 在这里 &#x1f469;‍&#x1f9b0;&#x1f469;‍&#x1f9b0; 读书 | 长沙 ⭐计算机科学与技术 ⭐ 本科 【2024届】 &#x1f383;&#x1f383; 爱好 | 旅游、跑步、网易云、美食、摄影 &#x1f396;️…

VR特警野外武装仿真虚拟训练实操教学保证训练效果

特警VR模拟仿真训练软件的优势主要体现在以下几个方面&#xff1a; 真实感和沉浸感&#xff1a;通过VR技术&#xff0c;特警可以在虚拟环境中体验真实的训练场景&#xff0c;如人质解救、反恐行动等。这种真实感和沉浸感可以帮助特警更好地理解和适应实际情况&#xff0c;提高训…

GoLang切片

一、切片基础 1、切片的定义 切片&#xff08;Slice&#xff09;是一个拥有相同类型元素的可变长度的序列它是基于数组类型做的一层封装它非常灵活&#xff0c;支持自动扩容切片是一个引用类型&#xff0c;它的内部结构包含地址、长度和容量声明切片类型的基本语法如下&#…

阿里巴巴矢量图标库的使用

iconfont-阿里巴巴矢量图标库iconfont-国内功能很强大且图标内容很丰富的矢量图标库&#xff0c;提供矢量图标下载、在线存储、格式转换等功能。阿里巴巴体验团队倾力打造&#xff0c;设计和前端开发的便捷工具https://www.iconfont.cn/ 今天来介绍一下阿里巴巴矢量图标库的使用…

【人工智能Ⅰ】实验2:遗传算法

实验2 遗传算法实验 一、实验目的 熟悉和掌握遗传算法的原理、流程和编码策略&#xff0c;理解求解TSP问题的流程并测试主要参数对结果的影响&#xff0c;掌握遗传算法的基本实现方法。 二、实验原理 旅行商问题&#xff0c;即TSP问题&#xff08;Traveling Salesman Proble…

2023最新的软件测试热点面试题(答案+解析)

&#x1f4e2;专注于分享软件测试干货内容&#xff0c;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01;&#x1f4e2;交流讨论&#xff1a;欢迎加入我们一起学习&#xff01;&#x1f4e2;资源分享&#xff1a;耗时200小时精选的「软件测试」资…

基于Qt QChart和QChartView实现正弦、余弦、正切图表

# 源码地址 https://gitcode.com/m0_45463480/QChartView/tree/main# .pro QT += charts​​HEADERS += \ chart.h \ chartview.h​​SOURCES += \ main.cpp \ chart.cpp \ chartview.cpp​​target.path = $$[QT_INSTALL_EXAMPLES]/charts/zoomlinechartINSTAL…

借助 DPM 代码扫描的力量解锁医疗设备的可追溯性

在当今的医疗保健系统中&#xff0c;医疗设备的可追溯性变得比以往任何时候都更加重要。为了增强现代医疗保健领域的可追溯性和安全性&#xff0c;UDI 条形码充当唯一设备标识的标准&#xff0c;为医疗设备提供唯一标识符。 DataMatrix 代码&#xff08;或直接零件标记代码&am…

初识向量数据库

背景 现在的数据分为20%的传统结构化数据&#xff0c;80%的非结构化数据 结构化数据&#xff1a;主要单元是数值与符号&#xff0c;数据类型高度抽象且易于组织。基于数值运算与关系代数&#xff0c;可以轻松地对结构化数据进行分析。 非结构化数据&#xff1a;常见的类型包括…

函数保留凸性的一些运算,限制为一条线

凸优化在学术研究中非常重要&#xff0c;经常遇到的问题是证明凸性。常规证明凸性的方式是二阶导数的黑塞矩阵为半正定&#xff0c;或者在一维函数时二阶导数大于等于零。但很多时候的数学模型并不那么常规、容易求导的&#xff0c;若能够知道一些保留凸性的运算&#xff0c;将…

linux 账号管理实例一,stdin,passwd复习

需求 账号名称全名次要用户组是否可登录主机密码 myuser1 1st usermygroup1yespasswordmyuser22st usermygroup1yespasswordmyuser33st user无nopassword 第一&#xff1a;用户&#xff0c;和用户组创建&#xff0c;并分配有效用户组&#xff08;初始用户组是passwd里…

97.STL-查找算法 find

目录 STL-查找算法find 1.基本用法&#xff1a; 2.查找自定义类型&#xff1a; 3.查找范围&#xff1a; STL-查找算法find 在C的STL&#xff08;标准模板库&#xff09;中&#xff0c;find 算法用于在指定范围内查找指定值的元素。 功能描述&#xff1a; 查找指定元素&…

YOLOV8解读及推理代码

YOLOV8解读及推理代码 YOLOV8前言性能对比新的骨干网络新的 Ancher-Free 检测头新的损失函数环境配置训练基于python脚本基于命令行 推理pt模型推理onnx模型推理 YOLOV8 前言 YOLOv8并非一个全新的目标检测网络&#xff0c;而是在YOLOv5的基础上进行了升级。其主要升级包括&am…

c++之STL

首先我们来仔细研究string 首先我们需要实现string的构造函数和析构函数。有new就有delete. 然后我们实现size()和c_str()&#xff0c;其中c_str就是可以将string类型转换为char*类型返回。 通过运算符重载&#xff0c;我们就可以实现string的[]访问。 然后我们实现和append。 …

超声波水表的量程比是多少?

超声波水表是现代智能水表中的一种重要类型&#xff0c;它采用超声波技术来测量水流速度和体积。量程比作为超声波水表的一个重要指标&#xff0c;决定着其在不同流量范围内的测量性能和准确度。那么&#xff0c;超声波水表的量程比是多少呢&#xff1f; 量程比是指超声波水表最…

2.安装docker

目录 1 安装依赖 2 安装docker 3 测试 目前docker分为三类 Docker-CE(社区版),Docker-EE(企业版)和Moby。Moby是docker社区用户自己写的&#xff0c;所以Moby我们一般用不上 每一类的每一个版本中都有Edge与Stable版&#xff0c;Stable维护4个月&#xff0c;Edge维护1个…