实验二 8253+8255实验

2020-07-13  本文已影响0人  Redcarp

⚠本篇文章参考网址1:https://wenku.baidu.com/view/e04ce53c42323968011ca300a6c30c225901f099.html
⚠本篇文章参考网址2:
https://blog.csdn.net/qq_43207916/article/details/101175484

目测应该是个17级的大佬?
⚠感谢我可爱的室友们在实验过程中对我的帮助 + 一部分学习资料的提供
⚠感谢ZYLXGG
⚠感谢大佬们在实验课程中的扶贫工作

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

关于这些代码,其实可以把网址存在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

六、实验结果

  1. 实验2-1结果:利用8253芯片完成了1秒的延时。
  2. 实验2-2结果:利用8253芯片完成了硬件延时的跑马灯运行。
  3. 实验2-3结果:利用8255芯片完成了键盘显示实验。

七、实验小结

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

上一篇下一篇

猜你喜欢

热点阅读