害,不赞同你们单纯的抄袭行为嗷,希望能帮你们解决一些实际问题,但不希望你们的实验报告完全照搬嗷,还是要看懂原理,自己试着写写,不然考试咋搞啊,唉😔,头要秃了...
关于这些代码,其实可以把网址存在txt文本里,然后就可找到这个专题啦,接着搬搬代码就可以啦(啊,我什么都没说,要自己肝代码!💪),也不用每次都提前搞代码,或者手机看网页,手动抄代码,电脑大屏 + ctrl c/v 香香甜甜😏!
大佬带带我.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随便选个灯,其余线不用接
实验2-1.png
实验2-1实物图.jpg
实验2-2:利用8253硬件延时控制跑马灯运行
按照电路图红色的地方接线就可,PA0在8255芯片下面密密麻麻的那3排孔里(要仔细看!)
蓝色的圈圈注意看描述部分
没有实物图,忘拍了...😭🙃
实验2-2电路图.png
P图1小时的成果...太艰难了,可能下图这样的才是对的电路图?
实验2-2电路图(修改版).png
实验2-3:8255键盘显示实验
憨憨没做出来这个实验,没电路图(电路图应该和书上217页图6.20差不多叭),也没有实物图...
要是你们有图了,喊我一下,我去收图,把伤心的表情包和我本人从这里捡走...😭
伤心总是难免的.jpg
捡走憨憨+表情包😏
书上217页的图6.20!✊
实验2-3电路图.png
实物图拍了3张,希望你能从图里看清所有接口的位置和名称,嗷,图里有1根线是反着接的!!!
实验2-3实物图细致看.png
实验2-3实物图1.jpg
实验2-3实物图2.jpg
实验2-3实物图3.jpg
四、软件设计程序流程图
实验2-1:8253定时实验,利用8253完成1秒的延时
实验2-1程序流程图.jpg
实验2-2:利用8253硬件延时控制跑马灯运行
实验2-2程序流程图.jpg
实验2-3:8255键盘显示实验
实验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页)‘
挠头.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 ;程序结束语句
挠头.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。