8255键盘C语言实验,实验二 8253+8255实验

害,不赞同你们单纯的抄袭行为嗷,希望能帮你们解决一些实际问题,但不希望你们的实验报告完全照搬嗷,还是要看懂原理,自己试着写写,不然考试咋搞啊,唉😔,头要秃了...

关于这些代码,其实可以把网址存在txt文本里,然后就可找到这个专题啦,接着搬搬代码就可以啦(啊,我什么都没说,要自己肝代码!💪),也不用每次都提前搞代码,或者手机看网页,手动抄代码,电脑大屏 + ctrl c/v 香香甜甜😏!

e39b6385f2ad

大佬带带我.gif

一、实验题目:

1.8253定时实验,利用8253完成1秒的延时。(参考书上233页控制LED的点亮或熄灭)

2.利用8253硬件延时控制跑马灯运行。(参考实验一中的跑马灯 [实验1-2] 和 实验二中的 [实验2-1] 或者 书上233页控制LED的点亮或熄灭)

3.选做8255键盘显示实验。(键盘一定要做,考试有不低的概率会抽到相关题目)(参考书上217页键盘接口)

二、实验目的:

熟悉汇编语言编程环境,掌握8253芯片工作原理、电路设计及利用汇编语言编写接口软件。

三、实验电路图

I/O译码地址选择接口:

8253芯片:片选信号为Y7

Y7:2B8H-2BFH

2B8H -> 通道0

2B9H -> 通道1

2BAH -> 通道2

2BBH -> 控制口

实验中我们选择:通道0作为第1级,通道2作为第2级

8255芯片:片选信号为Y0

Y0:280H-287H

280H -> A口

281H -> B口

282H -> C口

283H -> 控制口

实验中我们选择:A口、B口作为输入,C口作为输出

实验2-1:8253定时实验,利用8253完成1秒的延时

按照电路图红色的地方接线就可,LED随便选个灯,其余线不用接

e39b6385f2ad

实验2-1.png

e39b6385f2ad

实验2-1实物图.jpg

实验2-2:利用8253硬件延时控制跑马灯运行

按照电路图红色的地方接线就可,PA0在8255芯片下面密密麻麻的那3排孔里(要仔细看!)

蓝色的圈圈注意看描述部分

没有实物图,忘拍了...😭🙃

e39b6385f2ad

实验2-2电路图.png

P图1小时的成果...太艰难了,可能下图这样的才是对的电路图?

e39b6385f2ad

实验2-2电路图(修改版).png

实验2-3:8255键盘显示实验

憨憨没做出来这个实验,没电路图(电路图应该和书上217页图6.20差不多叭),也没有实物图...

要是你们有图了,喊我一下,我去收图,把伤心的表情包和我本人从这里捡走...😭

e39b6385f2ad

伤心总是难免的.jpg

捡走憨憨+表情包😏

书上217页的图6.20!✊

e39b6385f2ad

实验2-3电路图.png

实物图拍了3张,希望你能从图里看清所有接口的位置和名称,嗷,图里有1根线是反着接的!!!

e39b6385f2ad

实验2-3实物图细致看.png

e39b6385f2ad

实验2-3实物图1.jpg

e39b6385f2ad

实验2-3实物图2.jpg

e39b6385f2ad

实验2-3实物图3.jpg

四、软件设计程序流程图

实验2-1:8253定时实验,利用8253完成1秒的延时

e39b6385f2ad

实验2-1程序流程图.jpg

实验2-2:利用8253硬件延时控制跑马灯运行

e39b6385f2ad

实验2-2程序流程图.jpg

实验2-3:8255键盘显示实验

e39b6385f2ad

实验2-3程序流程图.jpg

五、实验软件代码(加注释)

实验2-1:8253定时实验,利用8253完成1秒的延时

⭐对8253编程,使OUT0输出周期为2s,占空比为1:1的方波就能使LED交替点亮和熄灭1s。

⭐若将频率为2MHz(周期为0.5μs)的时钟直接加到CLK0端,则OUT0输出的脉冲周期最大只有0.5μs×65536=32768μs=3.768ms,达不到2s的要求,需用两个通道级联的方案来解决这个问题。

⭐若选择计数初值N0=2000,则从OUT0端可得到序列负脉冲,其频率为2MHz/2000=1000Hz,周期为1ms。再把该信号连到CLK2输入端,并使通道2工作于方式3。为了使OUT2输出周期为2s(频率为1/2=0.5Hz)的方波,应取时间常数N1=1000Hz/0.5Hz=2000。

CODE SEGMENT;代码段定义语句

ASSUME CS:CODE;段分配语句

START: MOV AL,00110101B;书上225页图7.2,前两位选择通道0,工作于方式2,先写低字节,后写高字节,采用BCD计数方式

MOV DX,2BBH;指向控制口

OUT DX,AL;写入控制字

MOV AL,00H;计数器初值为2000,周期为2s,先写低字节,后写高字节

MOV DX,2B8H

OUT DX,AL

MOV AL,20H

OUT DX,AL

MOV AL,10110111B;书上225页图7.2,前两位选择通道2,工作于方式3,先写低字节,后写高字节,采用BCD计数方式

MOV DX,2BBH;指向控制口

OUT DX,AL;写入控制字

MOV AL,00H;时间常数N1=2000,周期为2s,先写低字节,后写高字节

MOV DX,2BAH

OUT DX,AL

MOV AL,20H

OUT DX,AL

CODE ENDS;代码段定义语句

END START

实验2-2:利用8253硬件延时控制跑马灯运行(用到了实验2-1的全部代码)

CODE SEGMENT;代码段定义语句

ASSUME CS:CODE;段分配语句

MOV AL,10010010B;8255初始化,书上207页图6.10,A口、B口输入,C口输出

MOV DX,283H;指向控制口

OUT DX,AL;写入控制字

;以下为8253延时1s总程序

START:MOV AL,00110101B;书上225页图7.2,前两位选择通道0,工作于方式2,先写低字节,后写高字节,采用BCD计数方式

MOV DX,2BBH;指向控制口

OUT DX,AL;写入控制字

MOV AL,00H;计数器初值为2000,周期为2s,先写低字节,后写高字节

MOV DX,2B8H

OUT DX,AL

MOV AL,20H

OUT DX,AL

MOV AL,10110111B;书上225页图7.2,前两位选择通道2,工作于方式3,先写低字节,后写高字节,采用BCD计数方式

MOV DX,2BBH;指向控制口

OUT DX,AL;写入控制字

MOV AL,00H;时间常数N1=2000,周期为2s,先写低字节,后写高字节

MOV DX,2BAH

OUT DX,AL

MOV AL,20H

OUT DX,AL

MOV AL,01H;将AL值送到CL暂存

MOV CL,AL

;8253输出电平上升沿进入

X1: MOV DX,280H;从 8255 A口输入

IN AL,DX

TEST AL,01H;测试 8253 输入 8255 的脉冲是否为高电平

JNZ X1;否,继续循环测试

X2: MOV DX,281H;从 8255 B口输入

IN AL,DX

TEST AL,01H;测试在B口输入的 开关输出 是否为高电平

JNZ X2;否,继续循环测试

;8255该输出啦

MOV AL,CL;将暂存在CL中的值送到AL中

MOV DX,282H

OUT DX,AL;C口输出

X3: MOV DX,280H;从 8255 A口输入

IN AL,DX

TEST AL,01H;测试 8253 输入 8255 的脉冲是否为高电平

JZ X3;是,继续循环测试

;左移一位,暂存在CL中,防止AL被修改

ROL CL,1

JMP X1;循环检测该程序

CODE ENDS;代码段定义语句

END START

实验2-3:8255键盘显示实验(代码基本参考书上218-220页)‘

e39b6385f2ad

挠头.gif

看清楚了嗷,这里是书上218-220页的代码

;端口地址

PORT_A EQU 0FF9H ;8255 A口地址,常数值0F9H赋给符号名PORT_A(A端口)

PORT_B EQU 0FFBH ;8255 B口地址

PORT_CTL EQU 0FFFH ;8255 控制口地址

;定义数据段,键盘扫描码表

DATA SEGMENT;段定义语句

; 0 1 2 3 4 5 6 7

TABLE DB 77H, 7BH, 7DH, 7EH, 0B7H, 0BBH, 0BDH, 0BEH,

; 8 9 A B C D E F

DB 0D7H, 0DBH, 0DDH, 0DEH,0E7H, 0EBH, 0EDH, 0EEH

DATA ENDS;段定义语句

;定义堆栈段

STACK SEGMENT STACK

DW 50 DUP(0);定义50个字单元,初值均为0

TOP_STAC LABEL WORD;将TOP_STAC定义为字变量

STACK ENDS

;定义代码段

CODE SEGMENT

ASSUME CS:CODE, DS:DATA, SS:STACK;段分配语句,3个段寄存器分别与哪些段有关

START:MOV AX, STACK

MOV SS, AX

LEA SP, TOP_STACK

MOV AX, DATA

MOV DS, AX

;初始化 8255A ,方式0, B口 和 C口做输入,A口做输出

MOV DX, PORT_CTL ;指向控制口

MOV AL, 10001011B ;控制字

OUT DX, AL ;写入控制字

;向所有行送0

MOV DX, PORT_A ;A口

MOV AL, 00H ;

OUT DX, AL ;向A口各位输出0

;读列,查看是否所有键松开

MOV DX, PORT_B

WAIT_OPEN:IN AL, DX ;键盘状态读入B口

AND AL, 0FH ;只查低4位(列值)

CMP AL, 0FH ;是否都为1(各键都松开)?

JNE WAIT_OPEN ;否,继续查

;各键均已松开,再查列是否有0,即是否有键压下

WAIT_PRES:IN AL, DX ;读B口

AND AL, 0FH ;只查低4位

CMP AL, 0FH ;是否有键压下

JE WAIT_PRES ;无,等待

;有键压下演示20ms,消抖动

MOV CX, 16EAH

DELAY:LOOP DELAY ;延时20ms(LOOP:CX内容自减1,若CX≠0时,转移到指定标号处,否则退出循环)

;再查列,看键是否仍被压着

IN AL, DX

AND AL, 0FH

CMP AL, 0FH

JE WAIT_PRES ;已松开,转出等待压键

;键仍被压着,确定是哪一个键被压下

MOV AL, 0FEH ;先使D0=0

MOV CL, AL ;CL=1111 1110 B

NEXT_ROW:MOV DX, PORT_A ;A口

OUT DX, AL ;向一行输出低电平

MOV DX, PORT_B ;B口

IN AL, DX ;读入B口状态

AND AL, 0FH ;只截取列值

CMP AL, 0FH ;是否均为1?

JNE ENCODE ;否,表示有键压下,转去编码(JNE:不为0,跳转)

ROL CL, 01 ;均为1,使下行输出0

MOV AL, CL

JMP NEXT_ROW ;查看下行

;已找到有一列为低电平,对压键的行列值编码

ENCODE:MOV BX, 000FH ;建立地址指针,先指向 F 键对应的地址

IN AL, DX ;从B口读入行列号

NEXT_TRY:CMP AL, TABLE[BX] ;读入的行列值与表中查得的相等吗?

JE DONE ;相等,转出(JE:为零,跳转)

DEC BX ;不等,指向下一个(键值较小值)地址

JNS NEXT_NEXT_TRY ;若地址尚未减为负值,继续查

MOV AH, 01 ;若减为负值,置出错码01 -> AH中

JMP EXIT ;退出(JMP:无条件转移指令)

DONE:MOV AL, BL ;BL中存有键的十六进制代码

MOV AH, 00 ;AH=0,读到有效键值

EXIT:HLT ;结束,停机指令

CODE ENDS

END ;程序结束语句

e39b6385f2ad

挠头.gif

看清楚了嗷,这里才是实验2-3的代码

;端口地址

PORT_A EQU 0280H;8255A口地址

PORT_B EQU 0281H;8255B口地址

PORT_C EQU 0282H;8255B口地址

PORT_CTL EQU 0283H;8255控制口地址

;数据段,键盘扫描码表

DATA SEGMENT

; 0 1 2 3 4 5 6 7

TABLE DB 77H, 7BH, 7DH, 7EH, 0B7H, 0BBH, 0BDH, 0BEH

; 8 9 A B C D E F

DB 0D7H, 0DBH, 0DDH, 0DEH, 0E7H, 0EBH, 0EDH, 0EEH

;0~F的七段代码编码,实验箱是共阳极接法

TABLE1 DB 3FH, 06H, 5BH, 4FH, 66H, 6DH, 7DH, 07H

DB 7FH, 6FH, 77H, 7CH, 39H, 5EH, 79H, 71H

DATA ENDS

;代码段

CODE SEGMENT

ASSUME CS:CODE, DS:DATA

START: MOV AX,DATA

MOV DS,AX

;初始化8255A,方式0,B口做输入,A口和C口输出

MOV DX,PORT_CTL ;指向控制口

MOV AL,10000010B ;控制字

OUT DX,AL ;写入控制字

;向所有行送0

MOV DX, PORT_A ;A口输出

MOV AL,00H

OUT DX,AL ;向A口各位输出

;读列,查看是否所有键均松开

MOV DX,PORT_B

WAIT_OPEN:IN AL,DX;键盘状态读入B口

AND AL,0FH ;只查低四位(列值)

CMP AL,0FH ;是否都为1?(各键都松开? )

JNE WAIT_OPEN ;否,继续查

;各键均已松开,再查列是否有0,即是否有键按下

WAIT_PRES:IN AL,DX ;读B口

AND AL,0FH;只查低四位

CMP AL,0FH;是否有键按下

JE WAIT_PRES;无,等待

;有键按下,延时20ms,消抖动

MOV CX,16EAH

DELAY: LOOP DELAY ;延时20ms

;再查列,看键是否仍被压着

IN AL,DX

AND AL,0FH

CMP AL,0FH

JE WAIT_PRES;已松开,转出等待压键

;键仍被压着,确定哪一个键被压下

MOV AL,0FEH;先使D0=0

MOV CL,AL ;CL=1111 1110B

NEXT_ROW:MOV DX,PORT_A;A口

OUT DX,AL ;向一行输出低电平

MOV DX, PORT_B ;B口

IN AL,DX ;读入B口状态

AND AL,0FH ;只截取列值

CMP AL,0FH ;是否均为1?

JNE ENCODE ;否,表示有键按下,转去编码

ROL CL ,01 ;均为1,使下行输出0

MOV AL,CL

JMP NEXT_ROW ;查看下行

;已找到有一列为低电平,对压键的行列值进行编码

ENCODE: MOV BX,000FH ;建立地址指针,先指向F键对应的地址

IN AL,DX ;从B口读入行列值

NEXT_TRY:CMP AL,TABLE[BX] ;读入的行列值与表中查得的相等吗?

JE DONE ;相等,转出

DEC BX ;不等,转向下一个(键值较小者)地址

JNS NEXT_TRY ;若地址尚未减为负值,继续查

MOV AH,01 ;若减为负值,置出错码01->AH中

JMP EXIT ;退出

DONE: MOV DX,PORT_C;C口输出

MOV AL,TABLE1[BX];检查0~F的七段代码表

OUT DX,AL

MOV BX,500H;将500H存入BX中,用于双层循环延时

DELAY1: MOV CX,12346;将12346存入CX

DELAY2: LOOP DELAY2;循环DELAY2,每循环一次,CX自减一次

DEC BX;BX减1

JNZ DELAY1;若BX不为0,则跳至DELAY1

JMP START;循环检测该程序

EXIT: HLT

CODE ENDS

END START

六、实验结果

实验2-1结果:利用8253芯片完成了1秒的延时。

实验2-2结果:利用8253芯片完成了硬件延时的跑马灯运行。

实验2-3结果:利用8255芯片完成了键盘显示实验。

七、实验小结

本实验相比前一次实验做的其实更顺利一些,本次实验之前我参考了书上的例程,思考了实验1中的程序及操作步骤,虽然过程仍然有些艰辛,但经过探索,最终还是实现了实验2-1和实验2-2。

  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值