8086-翻转课堂-汇编-微机-七段数码管-程序设计-proteus仿真

8086-翻转课堂-汇编-微机-七段数码管-程序设计-proteus仿真_第1张图片

如图所示proteus7仿真图,实现以下几点功能:

 按键检测+7段数码管显示+循环显示数字+闪烁

通过8086驱动8255的ABC三个端口,检测C口按键状态,并做出响应。

 1. SW0按下,   PA闪烁显示0,

 2. SW1按下,   PB闪烁显示1,

 3. SW0,1闭合,循环显示1~9

 4. SW0,1断开,全部熄灭

---首先要确定 8255的工作模式:

这设置 8255的ABC口分别为 0模式输出,0模式输出,输入  

> 参考8255如何设置https://blog.csdn.net/wuzhihun111/article/details/124573768

--然后要确定8255 A B C 以及控制寄存器的地址:

--接下来才是驱动8255输出数码管

8086-翻转课堂-汇编-微机-七段数码管-程序设计-proteus仿真_第2张图片

这里选取的是共阳极数码管

--最后,确定好硬件连接,编写asm汇编代码

 asm源代码

IOA     EQU 0FFD0H ;8255A的 PA口地址            0FFD0H in binary is 1111 1111 1101 0000.
IOB     EQU 0FFD2H ;8255A的 PB口地址            0FFD2H in binary is 1111 1111 1101 0010.
IOC     EQU 0FFD4H ;8255A的 PC口地址            0FFD4H in binary is 1111 1111 1101 0100.
IOCON   EQU 0FFD6H ;8255A的控制寄存器的地址      0FFD6H in binary is 1111 1111 1101 0110.


DATA SEGMENT                                                                                             ;数据段定义
    ; 7段数码管共阳极编码16进制
    ;         0    1    2    3    4    5    6    7    8    9    a    b    c    d    e    f   全灭
    Table     DB 0C0H,0F9H,0A4H,0B0H,099H,092H,082H,0F8H,080H,090H,088H,083H,0c6H,0a1H,086H,08eH,0ffH
    Table_num =  $-Table

    ; 按键我们选取 C0为SW0, C1为SW1;  对于单个按键,例如 IOC0 =0 表示按下 ; IOC0 =1 表示断开
DATA ENDS

;   按键检测+7段数码管显示+循环显示数字+闪烁
; 代码段实现 以下功能
; 1.SW0按下,PA闪烁显示0, 
; 2.SW1按下,PB闪烁显示1, 
; 3.SW01闭合,循环显示1~9 
; 4.SW01断开,全部熄灭


CODE SEGMENT                                            ;代码段段定义
        ASSUME CS:CODE,DS:DATA
 
START:              
        MOV    AX, DATA
        MOV    DS, AX                   ;程序开始切入点
    init:               
            CALL   Init_8255_A0_B0_Cin      ;初始化8255工作模式 A模式0输出,B模式0输出,C输入
    checkSW_status:     
            CALL   CheckSW                  ; 检查开关状态

    SW01_close:                                         ;如果0闭合,1闭合PA PB 0~9循环显示
            CALL   Disp_0123456789
    SW0_close:                                          ; 如果0闭合,1打开,PA显示数字0,PB灭
            CALL   Extinguish               ; 清除显示,全部熄灭
            CALL   Delay                    ; 延时阻塞一段时间
            MOV    AL, BYTE PTR[Table+0]    ; 取出Table中 共阳极0的编码
            MOV    DX, IOA
            OUT    DX, AL                   ;A口数码管显示数字0
            CALL   Delay                    ; 延时阻塞一段时间
            JMP    checkSW_status           ;重新循环
                        
    SW1_close:                                          ; 如果0打开,1闭合, PB显示数字1,PA灭
            CALL   Extinguish               ;清除显示,全部熄灭
            CALL   Delay                    ; 延时阻塞一段时间
            MOV    AL, BYTE PTR[Table+1]    ;取出Table中 共阳极1的编码
            MOV    DX, IOB
            OUT    DX, AL                   ;B口数码管显示数字1
            CALL   Delay                    ; 延时阻塞一段时间
            JMP    checkSW_status           ;重新循环

    SWothers:                                           ; 其他情况,; 如果0打开,1打开,全部熄灭
            CALL   Extinguish               ; 清除显示,全部熄灭
            CALL   Delay                    ; 延时阻塞一段时间
            JMP    checkSW_status

 ; 下方均为CODE SEGMENT 段内子程序,被上面CALL的都在下面
    Init_8255_A0_B0_Cin PROC   ; 子程序,初始化8255工作模式 A模式0输出,B模式0输出,C输入
        MOV    AL, 10001001B            ; 初始化8255工作模式 A模式0输出,B模式0输出,C输入
        MOV    DX, IOCON                ; 控制寄存器地址存入DX
        OUT    DX, AL                   ; 向控制寄存器地址 写入 AL指令,设置8255工作模式 A模式0输出,B模式0输出,C输入
        RET
    Init_8255_A0_B0_Cin ENDP

    CheckSW PROC                                            ;子程序 检查开关状态  在Init_8255_A0_B0_Cin 之后调用
        MOV    DX,IOC                   ; 将IOC 地址写入DX
        IN     AL,DX                    ; 读取IOC 输入
        TEST   AL,  00000011B           ; 如果0闭合,1闭合,则跳转到SW01_close标签
        JZ     SW01_close               ;
        TEST   AL,  00000001B           ; 如果0闭合,1打开,跳转到SW0_close标签
        JZ     SW0_close                ;
        TEST   AL,  00000010B           ; 如果0打开,1闭合,跳转到SW1_close标签
        JZ     SW1_close                ;
        JMP    SWothers                 ; 如果0打开,1打开,跳转到SWothers标签
    CheckSW ENDP

    Extinguish PROC  ; 子程序,同时熄灭A口和B口的数码管函数 在Init_8255_A0_B0_Cin 之后调用
        MOV    AL, 0FFH
        MOV    DX, IOB                  ; 关闭B口数码管 熄灭
        OUT    DX, AL
        MOV    DX, IOA
        OUT    DX, AL                   ; 关闭A口数码管 熄灭
        RET
    Extinguish ENDP

    Disp_0123456789 PROC  ;子程序 循环在IOA ICB口显示 0-9
        dispInit:           
            MOV    SI, OFFSET Table         ;LEA SI, Table ; 0-9共阳极编码的首地址放入 SI
            MOV    CX, 10                   ;循环十次
        dispLoop:           
            MOV    AL, BYTE PTR[SI]
            MOV    DX, IOA
            OUT    DX, AL
            MOV    DX, IOB
            OUT    DX, AL
            CALL   Delay                    ;延时
            ADD    SI, 1
        satisfy:            
            MOV    DX,IOC                   ; 将IOC 地址写入DX
            IN     AL,DX                    ; 读取IOC 输入 ,也就是读按键状态
            TEST   AL, 00000011B            ; 如果不满足条件:0闭合,1闭合,则跳转到checkSW_status标签
            JNZ    checkSW_status           ;
            LOOP   dispLoop
            JMP    dispInit                 ;重新循环
    Disp_0123456789 ENDP

    Delay PROC   ;子程序 延时函数
            PUSH   CX
            MOV    CX,  0FFFFh
        DelayLoop:          
            NOP
            LOOP   DelayLoop
            POP    CX
            RET
    Delay ENDP
    
OVER:
    MOV  AH,4CH ;程序结束  无限循环程序到不了这里吧
    INT  21H

CODE ENDS ;代码段结束
    END START;

然后就是整理文件,总结梳理,加注释。

8086汇编实验让我学习到了很多,比C语言抽象,思维奇特。

你可能感兴趣的:(8086汇编,汇编,proteus,8086,微机)