设计微型计算机最小系统,实现跑马灯的模拟显示功能。具体要求为: ( 1 )、 输入设备三个启动按钮、一个停止按钮,输出设备为八个跑马灯; ( 2 )、 三个启动按钮对应三种跑马灯显示效果,按下任意一个启动按钮,跑马灯显示对应的效果,按下停止按钮则跑马灯全部熄灭。 由上分析可知,我们的硬件的电路需要另行搭建,电路中需包含四个按钮和八个跑马灯以及相关芯片,既有输入设备又有输出设备,经过分析可以使用芯片 8255A 来实现输入与输出,再加上锁存地址芯片 74LS273 、译码芯片 74LS154 以及相关门电路即可构成本设计的硬件电路基础。进一步分析最终决定用 8255A 的 A 口作为输出去控制跑马灯, B 口作为按钮信号输入, CPU 通过接收输入信号从而发出对应命令去控制 8255A 芯片 A 口输出,从而 A 口输出相应电平控制跑马灯有规律的亮灭。连接好硬件电路后的主要任务就是编写相应程序,通过程序去控制和调度硬件电路的输入与输出。 1.2 系统连接图设计 8255A 是一种通过可编程并行 I/O 接口芯片。广泛用于几乎所有系列的微机系统中 , 8255A 具有三个带锁存或缓冲的数据端口 , 可与外设并行进行数据交换 , 8255A 有多种操作方式 , 通用性较强 , 可为 CPU 与外设之间提供输入 / 输出通道。 8255A 和各端口内具有中断控制逻辑 , 在外设与 CPU 之间可用中断方式进行信息交换 , 使用条件传输方式时可用 “ 联络 ” 线进行控制。在本次设计中 , 我们运用 8255A 为 CPU 与外设之间提供输入输出输出通道来实现对跑马灯花样变换的控制。 8086 微处理器,选择最小工作模式,所有的总线控制信号均由 8086 产生; 8086CPU 的 地址 \ 数据总线 AD15-AD0 和地址 \ 状态总线 A16/S3-A19/S6 是复用 的,必须通过地址锁存器把地址总线和数据总线分离。 跑马灯硬件电路如图 1 所示。电路包括 8 个 LED 彩灯、三片 74LS273 、一片 74LS154 、一片 8086CPU 、一片 8255A 以及若干导线和电阻。用 LED 可以观测在不同按键输入下,跑马灯花样的变化效果。 如图 1 所示我们利用启动按钮作为输入信号,通过 8255A 端口扩展芯片,调节输出端口的电平变化,来控制共阳极的 LED 灯的亮与灭,实现跑马灯不同的花样变化。 图 图1 跑马灯硬件电路图
1.2.1 锁存控制电路 锁存控制电路电路如图 2 所示,在微控制器单元( MCU )中,寄存器是十分重要的资源。寄存器的主要作用是快速寄存算术逻辑运算单元( ALU )运算过程中的数据,其锁存功能利用 74LS273 来实现, 74LS273 是一种带清除功能的 8D 触发器, 1D~8D 为数据输入端, 1Q~8Q 为数据输出端,正脉冲触发,低电平清除,常用作数据锁存器,地址锁存器。 D0~D7 :输入, Q0~Q7 :输出; 第一脚 WR :主清除端,低电平触发,即当为低电平时,芯片被清除,输出全为 0 (低电平); CP ( CLK ):触发端,上升沿触发,即当 CP 从低到高电平时, D0~D7 的数据通过芯片,为 0 时将数据锁存, D0~D7 的数据不变。 CPU 向外部发出地址锁存允许信号,从而使 74LS273 锁存地址信号,在通过 译码芯片 74LS154 控制接口芯片 8255A ,在此系统中充当一个桥梁的作用。这部分电路将相应信号传送给 8255A 的 A0 、 A1 和 CS 片选,进而 CPU 开始控制 8255A 从而驱动发光二极管显示不同的样式。 
图 2 锁存控制电路 1.2.2 可编程并行通信接口芯片 8255A
芯片 8255A 有三种工作方式,他们分别是方式 0 、方式 1 、方式 2 ,电路如图 3 所示。 方式 0 为简单 I/O ,查询方式,端口 A 、端口 B 、端口 C 均可使用; 方式 1 为选通 I/O ,中断方式,端口 A 、端口 B 可以使用,选通的输入 / 输出方式; 方式 2 为双向 I/O ,中断方式,只有端口 A 可以使用,双向的传输方式。 方式 0 也叫基本输入 / 输出方式。一种方式,不需要应答联络信号,端 口 A 、端口 B 和端口 C 的高 4 位及低 4 位都可以作为输入或输出端口。方式 0 的应用 场合有无条件传送和查询传送 2 种; 故根据我们系统设计的要求,综上可知,选择 8255A 为工作方式 0 , A 口作为输出、 B 口作为输入。 8255A 的 3 种基本工作方式由方式控制字来决定, D7 = 1 (特征位)表明是设定方式选择控制字; D7=0 ,则表示是端口 C 按位置位 / 复位控制字。端口 C 分成高 4 位 (PC7 ~ PC4) 和低 4 位 (PC3 ~ PC0) ,可分别设置成输入端口或输出端口;端口 C 的高 4 位与端口 A 配合组成 A 组,端口 C 的低 4 位与端口 B 配合组成 B 组。 综上可得此系统需要满足 A 端口为输出,输出数据给到 8 个 LED 彩灯;端口 B 为输入,需要检测按键的输入情况。 图 3 芯片 8255A 接口电路
1.3 算法说明 本程序涉及芯片 8255A 的初始化,因此首先需要确定端口地址, CPU 向 8255A 送出方式控制字,进而 8255A 的 A 口作为输出、 B 口作为输入;定义控制 LED 灯的相应数据段,由于需要 LED 亮后持续一段时间这就需要一个相应的延时程序片段,需要确定 B 口那个按钮开关按下,这就需要一个扫描 B 口开关按下的子程序,从而 CPU 发出相应控制等操作给 A 口送出相应电平, LED 显示相应的亮灭。 因此,主要要点就是找对端口地址,这个是程序能够运行的必需品,通过分析硬件线路可以正确找到 A 口、 B 口以及控制口的地址。
2 程序流程图设计及其说明
主程序流程图如图 4 所 示: 
图 4 主程序流程图 检测按键延时控制 LED 子程序流程图如图 5 所示 : 
图 5 子程序流程图
3 关键程序段落说明
3.1 数据段定义 - dseg segment
- num dw 0
- data1 db 0FEh,0FDh,0FBh,0F7h,0EFh,0DFh,0BFh,7Fh
- data2 db 7Fh,0BFh,0DFh,0EFh,0F7h,0FBh,0FDh,0FEh
- data3 db 7Eh,0BDh,0DBh,0E7h,0E7h,0DBh,0BDh,7Eh
- dseg ends
- 三种灯光变幻组合为:
- 第一种为 L1→L2→L3→L4→L5→L6→L7→L8 ;
- 第二种为 L8→L7→L6→L5→L4→L3→L2→L1 ;
- 第三种为 L1L8→L2L7→L3L6→L4L5→L3L6→L2L7→L1L8 。
- dw 为灯光循环的控制次数。
-
- 3.2 程序初始化
-
- cseg segment para public 'code'
- assume ss:sseg,cs:cseg,ds:dseg
- start:
- mov ax,dseg
- mov ds,ax
- 初始化程序。
- 3.3 芯片初始化
- mov dx,0206h ; 取 8255A 的控制端口的地址
- mov al,82h ; 初始化 8255A 的 A 口为输出模式, B 口为输入模式
- out dx,al
- 82h 即为 10000010b ,也就是说将 A 口定义在方式 0 下并且作为输出, B 口定义在方式 0 下并且作为输入,因此这个方式控制字不是唯一的,其通用形式为 1000X01X , C 口没有定义故可以为任意二进制数。
- mov dx,0200h ; 取 8255 的端口 A 的地址
- mov al,0FFh ; 使 8255 的 PA0-PA7 全为 1
- out dx,al
- 上边这个程序段是往外送数据置 LED 亮灭的。
- mov dx,0202h ; 取 8255 的端口 B 的地址
- in al,dx ; 检测 B 口输入信号
- 这个是将 B 口开关闭合信息读回来的,从而发出相应控制命令。
-
- 3.4 初始 LED 亮灭状态
-
- mov dx,0200h ; 取 8255 的端口 A 的地址
- mov al,0FFh ; 使 8255 的 PA0-PA7 全为 1
- out dx,al ; 使所有的灯 LED 全灭
- 电路上电工作后首先要使所有的 LED 灯全灭,防止对后面的显示造成影响。
-
- 3.5 检测按键开关子程序
-
- ledflash proc ; 检测开关闭合 , 以便确定哪种闪烁方式
- mov dx,0202h ; 取 8255A 的端口 B 的地址
- in al,dx ; 检测 B 口输入信号
- choice1:
- cmp al,0feh
- jne choice2
- mov si,offset data1 ; 置第一种灯光变幻组合
- jmp here
- choice2:
- cmp al,0fdh
- jne choice3
- mov si,offset data2 ; 置第二种灯光变幻组合
- jmp here
- choice3:
- cmp al,0fbh
- jne choice4
- mov si,offset data3 ; 置第三种灯光变幻组合
- jmp here
- choice4: ; 每盏灯亮完检测开关,如果停止开关没有按下跳到 choice5 ,如果停止开关按下灯全灭
- cmp al,0f7h
- jne choice5
- jmp exut
- choice5:
- cmp num,0h; 检测 num 是否为 0 ,若为 0 扫描开关,若不为 0 继续执行
- jne here
- jmp ledflash
- here:
- mov bx,num
- mov al,[si+bx]
- mov dx,0200h ; 取 8255 的端口 A 的地址
- out dx,al ; 输出加电数据到端口 A
- inc num ; 改变数字变量的值
- cmp num,09h
- je exit
- mov cx,005fh
- dl4: mov bx,00ffh
- dl3: dec bx
- jnz dl3
- dec cx
- jnz dl4
- jmp ledflash
- exit:
- mov num,0
- ret
- ledflash endp
- 检测到开关闭合置相应灯光变换。
- 3.6 延时程序片段
- mov cx,04c9h
- dl4: mov bx,04c9h
- dl3: dec bx
- jnz dl3
- dec cx
- jnz dl4
- 通过双层循环从而实现软件延时,延时计算公式为 ((cx)*(bx))/f , f 为 CPU 的频率, CPU 频率为 1500kHz ,可以计算得到程序大致延时为 1s 。
- 3.7 灯光变换控制
- here:
- mov bx,num
- mov al,[si+bx]
- mov dx,0200h ; 取 8255 的端口 A 的地址
- out dx,al ; 输出加电数据到端口 A
- inc num ; 改变数字变量的值
- cmp num,09h
- je exit
- 通过指针移动,逐个选中相应的数据置相应的灯光变换,共八种即一轮 LED 显示完成。
复制代码
4 程序调试说明
( 1 )、内存空间分配,汇编语言的重要特点之一是能够直接利用机器指令或者伪指令为数据或者代码程序分配内存空间, 86 系列(如 8086 微处理器)的存储器结构是分段的,有代码段,数据段,堆栈段或附加段,在程序设计时要充分考虑分段结构,要执行的程序段应设在当前段(活动段)中;分配内存空间:直接在 proteus 里面将 8086CPU 的 internal memory size 设置成一个足够用的空间大小,如 0x1000 ,默认的空间大小是 0x00000 ,如不改则仿真不成功。 程序在运行时所需要的工作单元应尽可能的设在 CPU 寄存器中,这样存取速度快,而且操作方便;在此系统源程序中都采用 8086CPU 的全部通用寄存器:累加器 AX ,基数寄存器 BX ,基数寄存器 CX ,数据寄存器 DX ;和堆栈指针寄存器 SI 。 ( 2 )、 unknow 1-byte opcode at B900:7056! 61 [SPICE]error-- -too many iterations without convergence 在仿真过程中,出现以上两行的错误,太多的迭代没有收敛性,和某个汇编语言在编码过程中的地址不正确,经过排查程序去除无用代码, proteus 不再报错。 ( 3 )、 8255A 隐藏引脚问题,需要设置芯片 Hidden Pins 里的 GND 改为 VSS , VCC 改为 VDD 。 ( 4 )、 程序一开始是将延时环节作为一个独立子程序,运行过程中由于部分情况下不满足题设,故将延时子程序改为程序段落写到检测按键的子程序中问题得以解决。
5 结果记录及分析

第一种灯光变换效果: L1→L2→L3→L4→L5→L6→L7→L8 ,如图 6 所示。


图 6 LED 第一种变换效果
第二种灯光变换效果: L8→L7→L6→L5→L4→L3→L2→L1 ; 第一种变换效果反向即为第二种效果。 
第三种灯光变换效果: L1L8→L2L7→L3L6→L4L5→L3L6→L2L7→L1L8 ,如图 7 所示。
 
图 7 LED 第三种变换效果 心得体会 通过本次设计,学到了很多使用的东西,使我受益匪浅,将课堂上所学的知识运用到实际,体会到了理论与实际联系的重要性,同时进一步学习了 PROTEUS 这款软件。 第一,在做这次设计的一开始可以说是难度重重,接口电路设计出了问题,一开始由于电路没有加入锁存器,导致地址和数据冲突,从而电路不能正常工作,最后在电路里加入了锁存器 74LS273 和译码器 74LS154 后解决了地址和数据冲突的问题。 第二,由于对软件 PROTEUS 运用不是很熟练,导致一些问题,比如说分配内存空间:直接在 proteus 里面将 8086CPU 的 internal memory size 设置成一个足够用的空间大小,如 0x1000 ,默认的空间大小是 0x00000 ,如不改则仿真不能成功。还有在运行期间 PROTEUS 仿真报错,由于不太懂报错信息就一步加大了设计的难度,还有一些其他小细节上的问题,可以说是细节决定成败。 第三,由于汇编语言运用的不太熟练,对程序反复进行修改,发现汇编语言由于语句在程序中放置的位置不同也会是不同的效果,对汇编语言有了进一步的认识。
|