第十一章 微机最小系统与监控程序
介绍一个具体的以 8086CPU为核心的最小系统 。
学习微机系统监控程序结构,功能及组成模块;重点介绍以键盘输入程序为核心的监控思想与程序设计 。
本章内容
建立微机系统的整体概念;
了解微机系统硬件设计的一般原则;
了解监控程序的常用算法与相应的程序设计方法 。
学习目的
11.1 Intel 8086最小系统实例
CPU (8086),存贮器芯片 (2732,
6116),I/O接口芯片 (8251,8253,8255、
8259)
可用的微机系统问题:
答案,利用 CPU的三条总线
AB — 地址总线
DB — 数据总线
CB — 控制总线将各类芯片连接组成微机系统。
EPROM2732 RAM1(6116) RAM6(6116)
8086
EPROM2732 …
8259A 8253A 8255A 8251A
OUT0 OUT2
OUT1
IR7

IR0 显示器 键盘
AB
DB
CB
Intel 8086微机最小系统框图一,系统方框图
EPROM2732 RAM1(6116) RAM6(6116)
8086
EPROM2732 …
8259A 8253A 8255A 8251A
OUT0 OUT2
OUT1
IR7

IR0 显示器 键盘
A
B
D
B
C
B
Intel 8086微机最小系统框图
CPU,3MHZ最小模式
2732:存放监控程序
6116:读 /写存贮器,
堆栈等
8253:计数与定时器
8259:中断控制器
8251:串行通讯器
8255,6× 4矩阵式键盘输入和七段码显示器输出二,存储器与 CPU的接口
·
·


AD15~ AD8
AD7~ AD0
BHE
RD
ALE
M / IO
WR
74LS 373 74LS 138
74LS 13874LS 373
D15~ D8
D7~ D0
A12~ A1 A11~ A1 A11~ A1
A15~ A13
WR
CE
RD
WR
CE
U6
RD
WR
CE U5
RD
WR
CE U
1
CE
RD
2732A
2732A
RD
CE U8 U2
U7 6116 6116
U4
奇片
U3
GOC
G
Y7
Y0
C
B
A
G2B
G2A
G1
G1C
B
A
G2A
G2B
Y1
Y2
Y2
Y7
Y0
Y1
OC
D7
D0

Q7
Q0~
A0
RD
存贮容量,EPROM,2732 2片 8K
RAM,6116 6片 12K
奇体存储器 (奇片 ):
·
·


AD15~ AD8
AD7~ AD0
BHE
RD
ALE
M / IO
WR
74LS 373 74LS 138
74LS 13874LS 373
D15~ D8
D7~ D0
A12~ A1 A11~ A1 A11~ A1
A15~ A13
WR
CE
RD
WR
CE
U6
RD
WR
CE U5
RD
WR
CE U
1
CE
RD
2732A
2732A
RD
CE U8 U2
U7 6116 6116
U4
奇片
U3
GOC
G
Y7
Y0
C
B
A
G2B
G2A
G1
G1C
B
A
G2A
G2B
Y1
Y2
Y2
Y7
Y0
Y1
OC
D7
D0

Q7
Q0~
A0
RD
·
·


AD15~ AD8
AD7~ AD0
BHE
RD
ALE
M / IO
WR
74LS 373 74LS 138
74LS 13874LS 373
D15~ D8
D7~ D0
A12~ A1 A11~ A1 A11~ A1
A15~ A13
WR
CE
RD
WR
CE
U6
RD
WR
CE U5
RD
WR
CE U
1
CE
RD
2732A
2732A
RD
CE U8 U2
U7 6116 6116
U4
奇片
U3
GOC
G
Y7
Y0
C
B
A
G2B
G2A
G1
G1C
B
A
G2A
G2B
Y1
Y2
Y2
Y7
Y0
Y1
OC
D7
D0

Q7
Q0~
A0
RD
偶片存储器 (偶片 )
A0 — 用于偶体的 体选 控制 。
A1~ A12 — 用于各存贮芯片的 片内寻址 。
A13~ A15 — 用于各存贮芯片的 片选控制 。
存储器的译码方式 —— 部分译码:
存贮地址分配例 1,奇片的地址译码逻辑
C
B
A
G2A
A13
A14
A15
M / IO
BHE
74LS138
A12~ A1 A
11~ A1
A11~ A0 A10~ A0
61162732A
CE CE U
5
U7
……
G1
Y2
Y7
CBA必须为 111
1 1 ……1 1 最大地址
U7 (2732)的地址:
A19 A18 A17 A16 A15 A14 A13 A12 A11 ……A 1 A0
0 0 ……0 1 X X X X 1 1 1 最小地址未参与译码逻辑 对应 Y7 =0 …
取 A19~ A16为 全 0,则对应地址为:
0E001~ 0FFFFH 中的全部 奇地址 有重叠区!
对应 Y2 = 0
必须 CBA=010
X 1 ……1 1 最大地址取 A19~ A16为 全 0,A12为 0,则对应地址为:
04001H~ 04FFFH 中的全部奇地址 有 重叠区 !
取 A19~ A16为 全 0,A12为 1,则对应地址为:
05001H~ 05FFFH 中的全部奇地址 有 重叠区 !
U5 (6116)的地址:
A19 A18 A17 A16 A15 A14 A13 A12 A11 ……A 1 A0
X 0 ……0 1X X X X 0 1 0 最小地址...
....
存储地址分配表:
0000 ~ 0FFFH或 1000~ 1FFFH
2000 ~ 2FFFH或 3000~ 3FFFH
4000 ~ 4FFFH或 5000~ 5FFFH
E000~ FFFFH
2KB× 2RAM
2KB× 2RAM
2KB× 2RAM
4KB× 2RAM
器 件地 址 A15~ A13 A12~ A0
000
001
010
111
U1U
2U
3U
4
U5U
6
U7U
8
可变可变可变可变译码器有效输出
Y0 = RAM CS
Y1 = RAM CS
Y2 = RAM CS
Y7 = ROM CS
存储空间分配表问题,上述地址有重叠区吗?为什么?
答案,有!因为 A19~ A16未参与译码控制。
三,I/O接口芯片与 CPU的连接
Q7
Q6
Q5
Q0
Q2
Q1
74LS373
D7
D0

G
74LS138
C
B
A
G2B
G2A
G1
+5V
AD7~ AD0
INTA
WR
RD
ALE
M / IO
INTR
CPU
RESET
Y0
Y1
Y2
INTA
RESET
RD
RD
CS
D7~ D0
WRRD
A1
A0
8255A
8253
8259A
WR
D7~ D0
INT
A0
CS
A1
A0
D7~ D0
CS
WR
CPU与接口电路连接示意图说明,1,74LS373用于锁存 A7~ A0低八位地址总线。
2,74LS138用于对 A7~ A5三位地址译码,接 A0,接G2B G2A M / IO
即得 74LS138能工作的条件是,CPU访问
I/O且端口地址为偶地址 。
因此 8253,8255,8259三芯片的地址全部为 偶地址 。
若取 A4,A3为 00,则对应四个端口地址为 00,02,
04,06 (注:有重叠区 )
Q7
Q6
Q5
Q0
Q2
Q1
74LS373
D7
D0

G
74LS138
C
B
A
G2B
G2A
G1
+5V
AD7~ AD0
INTA
WR
RD
ALE
M / IO
INTR
CPU
RESET
Y0
Y1
Y2
INTA
RESET
RD
RD
CS
D7~ D0
WRRD
A1
A0
8255A
8253
8259A
WR
D7~ D0
INT
A0
CS
A1
A0
D7~ D0
CS
WR
CPU与接口电路连接示意图最大地址由 Y0 作为 CS
控制信号决定未参与译码
1 1 0
以 8255的地址为例;
A7 A6 A5 A4 A3 A2 A1 A0
0 0 0 X X 0 0 0 最小地址…
I/O端口地址分配表:
A7~ A5 A2 A1 译码器有效输出 器 件 地 址
000
001
010
00~ 11
00~ 11
00~ 01
011~ 111
Y0 = 8255 CS
Y1 = 8253 CS
Y2 = 8259 CS
Y3~ Y7
8255A
8253
8259A
扩 展
00~ 06H
20~ 26H
40~ 42H
? 0 ~? XH
(? 为 6,8,A,C 或 E )
注,1,表中各芯片的所有端口均为偶地址。
2,所有地址均有重叠区。
四,键盘与 CPU的接口技术
1,常用键盘的分类
(1) 编码的键盘:如 ASCⅡ 码键盘。
特点,① 按下键后,送给 CPU的是相应键的 ASCⅡ 码 。
② CPU识别方便 。
③ 键盘内部有一片单片机负责扫描键盘和键译码 。
特点,1,一个键占用一根输入线。
2,CPU识别方便。
3,适用于小型键盘。
(2) 未编码的键盘:又可分为两类
a,独立连接的小型键盘:
c8086 8255
PA0
PA7
…+5V
+5V
K1
K8

3× 4矩阵键盘的接口
PA0
PB0
8255A
PA1
PA2
PB1
PB2
PB3
键 0 1 2 3
5 6 74
9 0A 0B8
行 0
行 1
行 3
+5V列 0 列 1 列 2 列 3
b,矩阵式键盘:
特点:
1,将所有的键排成一个矩阵,占用
CPU两个端口 。 一个输出端口 (对应矩阵的行 ),一个输入端口 (对应矩阵的列 )。
2,由 CPU用扫描方式来输入和识别按键信号 。
3,节省 CPU I/O端口线,但 CPU识别较复杂 。
矩阵式键盘应用举例:
1,接口电路:
3× 4矩阵键盘的接口
PA0
PB0
8255A
PA1
PA2
PB1
PB2
PB3
键 0 1 2 3
5 6 74
9 0A 0B8
行 0
行 1
行 3
+5V列 0 列 1 列 2 列 3
8255A PA0~ PA2作为 输出端口,控制矩阵的 行线 。
PB0~ PB3作为 输入端口,控制矩阵的 列线 。
键盘扫描输入过程:分两次扫描。
第一次扫描 (粗扫描 )过程:
3× 4矩阵键盘的接口
PA0
PB0
8255A
PA1
PA2
PB1
PB2
PB3
键 0 1 2 3
5 6 74
9 0A 0B8
行 0
行 1
行 3
+5V列 0 列 1 列 2 列 3
① CPU输出三条行线全为低电平。
② CPU输入 4条列线的信号。
③ 判断,若 4条列线全部为高电平,则转出,
否则表明至少有一个键按下 。 转入 第二次扫描 。
第二次扫描 (细扫描,逐行扫描 )
目的,找到按下键的行,列号。
方法,① 逐行扫描,以找到所按键的行号。
② 逐列判断,以找到所按键的列号。
以键 5被按下为例:
按键被找到,两次扫描完成!
3× 4矩阵键盘的接口
PA0
PB0
8255A
PA1
PA2
PB1
PB2
PB3
键 0 1 2 3
5 6 74
9 0A 0B8
行 0
行 1
行 3
+5V列 0 列 1 列 2 列 3
键盘输入程序,
/*,第一次扫描,等待键按下 */
MOV AL,82H
OUT 06H,AL ; 8255A初 始 化,选 择 方 式 0,; PA 口 为 输 出,PB 口 为 输 入 。
8255控制字含义:
82H,1 0 0 0 0 0 1 0 —C口下半都为 输出 。
方式设置标志
A口为方式 0
输出 C 口上半部为输出
B口为 方式 0输入
BEGIN,MOV AL,0
OUT 00H,AL ; AL→PA 口,使 三 条 行 线 全 部 输出 为 0
LOP1,IN AL,02H ; PB 口 → AL,读 入 4 条 列 线
AND AL,0FH ; AL∧ 0F →AL,屏 蔽 无 用 位 ( PB7~ PB4 )
CMP AL,0FH ; AL=0FH?即 有 4 条 列线 全部为 高电 平?
JZ LOP1 ;是,转 回 LOP1,继 续 粗 扫 描第二次扫描 (细扫描 )程序:
功能,找到所按键的行、列号。
以下程序又分为二段、先找到行号、再求键号。
MOV BL,3 ;矩 阵 行 数
MOV BH,4 ;矩 阵 列 数
MOV AL,11111110B ;起 始 扫 描 码,先 扫 第 0 行
MOV CL,0FH ;屏 蔽 码
MOV CH,0FFH ;取 键 号 初 值 FFH
LOP2,OUT 00H,AL ; 逐 行 扫 描,第 一 次 时 扫 0 行
ROL AL,1 ; AL 左移 一位,修改 扫描 码,准备 扫下 一行
MOV AH,AL ;暂 存 扫 描 码 到 AH
IN AL,02H ;读 入 列 线 数 据
AND AL,CL ;屏 蔽 无 用 位,保 留 线 位
CMP AL,CL ; AL=0FH?即有 列 线 为 ‘ 0’?
JNZ LOP3 ; AL≠0FH,即找到了按键的行,转出
ADD CH,BH ;不是 这 一 行则修改 键号,使 之 适合下一 行
MOV AL,AH ;取 回 扫 描 码 到 AL 中
DEC BL ;已 扫 过 一 行,计 数 一 次
JNZ LOP2 ;未 扫 描 完,转 回 继 续 扫 下 一 行
JMP BEGIN ;已 扫 完 3 列,仍 未 发 现,则 返 回 BEGIN; 重 新 粗 扫 描小结,本段程序有两个出口:
1)扫完 3行后,仍未找到按下键,则认为是干扰使得粗扫描出错,故返回到
BEGIN重新开始粗扫描 。
2)扫描找到按键的所在行,则转到
LOP3去寻找其键号,此时,该行的列线数据在 AL中 。
寻找键号的程序段,
LOP3,INC CH ; 键号加 1,进入时 CH=FFH 或 03H或 07H
RCR AL ; 列线数据右移一位
JC LOP3 ; C=1,表明不是该列,则转去检查下一列
MOV AL,CH ;是 这 一 列,CH 即 为 所 求 键号
CMP AL,0 ;是 ‘ 0’ 号 键?
JZ KEY0 ;是,转 ‘ 0’ 号 键 处 理 程 序
CMP AL,1 ; 是 ‘ 1’ 号 键?
JZ KEY1 ;是,转 ‘ 1’ 号 键 处 理 程 序
CMP AL,OBH ;是 ‘ B’ 号 键?
JZ KEY11 ;转 ‘ B’ 号 键 处 理 程 序
C AL
小结,本程序有两个功能,分述如下:
1,寻找所按键的键号;
算法,键号寄存器 CH加 1与列线数据 AL左移一位 两者同步进行,直到 AL移出的位为 0,则 CH中的值即为所求键号 。
2,根据键号转到相应的处理程序:
算法,采用 逐个比较 的查询方式。
五,七段码显示器与 CPU的接口
1,两种不同结构的七段码显示器
a
f bg
e cd
D7? D0
g f e d c b a
( a)七段显示器结构
+5Vg
f
e
d
c
b
a
g
f
e
d
c
b
a
( b) 共阳极 LED ( c) 共阴极 LED
2,段码控制线:
共七根,即 a~ g输出到 7个引脚上,一般按如下顺序连接到数据线:
D7? D0
g f e d c b a
3,七段显示代码:
即 CPU用来控制显示不同字符的代码 。
当 CPU对七段显示器采用 原码 输出时,则
0~ 9十个数字的七段显示代码如下表所示 。
十进制数字的七段显示代码十 六 进 制 表 示十进制数共阳极 共阴极
0
1
2
3
4
5
6
7
8
9
40
79
24
30
19
12
02
78
00
18
3F
06
5B
4F
66
6D
7D
07
7F
67
问题,确定七段显示代码的关键因素是什么?
答案是,a~ g段对应位线为 ‘ 0’ 时发光,
还是对应为 ‘ 1’时发光,
它由两个因素共同确定:
① 显示器是共阴极还是共阳极。
② CPU是采用原码驱动,还是反相驱动显示器。
图中为同相驱动共阴极七段显示器电路,
故其七段显示代码 ‘ 0’ ~ ‘ 9’对应为 3FH,
06H,5BH,4FH,?,67H。
4,七段显示器接口电路及驱动程序举例:
自 CPU
8255A
驱动电路
A0
A6
D0
D6
a
b
c
d
e
f
g
七段显示器共阴极
DISP,MOV BX,OFFSETDATA
MOV AL,[ BX ] ;取 待 显 示 的 数 字
MOV BX,OFFSET LEDSEG
XLAT ;将 数 字 转 换 成 七 段 码
MOV DX,PORTSEG ; PORT 为 并 行 接 口 端口地址
OUT DX,AL ;显 示 代 码 送 显 示 管
LEDSEG DB 3FH ;’ 0’ 的 显 示 代 码
DB 06H ;’ 1’ 的 显 示 代 码
DB 5BH ;’ 2’ 的 显 示 代 码
DB 4FH ;’ 3’ 的 显 示 代 码
驱动程序举例:
此程序将 DATA单元中的 未组合型 BCD
码 送显示,含两部分;
1,利用 XLAT指令查表求得要显示数字的七段显示代码 。
2,将七段显示代码送显示器显示 (经 8255PA
口 )
5,8255A与键盘,显示器的连接:
采用一片 8255A作为一个 6× 4矩阵式键盘 和一个 8位的七段显示器 的接口器件。
a
b
c
d
e
f
g
h
+5V
+5V
+5VPA
0
PA3
PC3
PC0
PC7
PC4
PB4
PB7
PB0
PB3
( 10)·( 11)
( 14)


0 1 2 3
( 15)
( 18)
4 5 6 7
( 19)-+?
( 1C) ( 1D)
8 9 A B
C D E F
1A 1Y

4A 4Y75492
75492
1A 1Y

75491
4A 4Y
1A 1E
4A 4E
75491
1A 1E
4A 4E


8255

图中,*PB口 —显示器的段码锁存器,PB0~
PB7对应控制 a~ h段,h为小数点对应的发光二极管 。
*PC口 —显示器的位控锁存器 。 PC7~ PC0
依次选取中左起的八位数码管 。
PC5~ PC0同时兼作键盘的行输出端口 。 其中 PC0控制第 1行,PC5
控制第 6行 。
* 75491—同相驱动器,E为输出端,E=A。
* 75492—反相驱动器,Y=A
* 显示器 采用动态扫描方式依次在八位数码管上显示不同的数字,利用眼睛的,视觉暂留,功能,产生同时显示 8位不同数字的效果 。
* PA口 —键盘的列输入 端口,PA0~ PA3
依次输入第 1列~第 4列 。
11.2 系统监控程序简介一、监控程序 (Debugging Program)简介
是微机小系统的管理程序,也提供软件开发功能;
以键盘输入程序为核心构成,可及时响应键盘命令,完成各种功能;
类似于操作系统 (Operating System)的低层模块
(BIOS— Basic Input Output System).
监控程序的一般功能,通过键盘和显示器可以完成以下操作:
1,检查和修改存贮器单元的内容 (输入程序,更新数据等 。 )
2,检查和修改 CPU内各寄存器的内容 。
3,启动和停止用户程序的运行 。
4,分段 (设置断点 )和单步执行用户程序 。
5,实现数据块在存贮器中的移动 。
6,检查和修改 I/O 端口芯片的数据 。
7,完成十六进制的加,减运算 。
监控程序的结构与组成:
* 采用模块化程序结构,模块的功能单一。
* 主要的模块有:
1) 初始化程序:是监控程序的入口,完成系统的初始化 。
2) 显示子程序:将显示缓冲区的内容输出显示一遍后返回 。
3) 键盘输入程序:扫描并分析,处理键盘命令 。
4) 实用子程序:完成各特定的动作或运算 。
5) 命令键处理子程序:完成各命令键对应的功能 。
二、显示子程序
1,调用参数 (入口条件 ):
设置堆栈指针 SP,004CH? SP
设置小数点显示标志字,堆栈段内 004EH单元,
若其某位为 1,则表示对应该位置要带小数点显示 。
要显示的八位数字的七段显示代码送入显示缓冲区:数据段 (附加段 )内 0068~ 006FH单元 。
2,出口条件:
将显示缓冲区中的七段显示代码送相应的显示管,扫描显示一遍后返回 。
0068H
0069H
006FH

3,显示程序流程图:
初始化;位选控制字 01H→DL,
(选中最右边显示管 );
取出小数点显示标志字 → BL;
设置循环显示计数器,8 →CX ;
SI指向显缓区末地址,6FH →SI ;
建立方向标志,1 →DF 。
取出要显示的七段代码 → AL
即,(SI) →AL,SI+1 →SI ;
AL∨ 80H →AL ; 加上小数点显示位
RET
显示完
8位?
Y
N此位要显示小数点?
N
Y
输出段码:
AL → 段码锁存器 (PB口 );
送位选控制字:
DL → 位控锁存器 (PC口 );
位控制字左移一位,指向左边一位显示管;
延时 1ms(大约值 )
SUB_11 PROC NEAR
PUSH BP ;入口时 SP=004CH,压入后 SP=004AH
MOV BP,SP ; BP=004AH
MOV DL,01H ;位选控制字指向显示器最右边显示管
MOV BL,[BP+4] ;小 数 显 示 标 志 字 ( 004EH )→BL
MOV CX,8 ;循 环 显 示 8 位
MOV SI,6FH ; SI 指 向 显 缓 区 最 低 位 数 字
SID ; 1 →DF
LOC_1,LODSB ; (SI) →AL,SI- 1 →SI,取 显示代码
RCR BL,1 ;本 位 要 带 小 数 点 显 示?
JNC LOC_2 ;否 (CF=0),则 转 移 到 LOC_2
OR AL,80H ;要 带 小 数 点 显 示,则 1 → AL
LOC_2,OUT 2,AL ;输出 显示 代码到 段码锁存器 (PB口 )
MOV AL,DL ;位 选 控 制 字
OUT 4,AL ;送 入位选 锁存器,选 通要显示的位
ROL DL,1 ; DL 左 移 一 位,指 向 左 边 的 位
PUSH CX
MOV CX,7FH
LOC_3,RCR AL,1 ; 延 时 约 1ms 具 体 时 间; 与 晶 振 频 率 有 关
LOOP LOC_3
POP CX
LOOP LOC_1 ;共 循 环 显 示 8 次
POP BP
RET
SUB_11ENDP
三、键盘扫描程序
程序功能:
扫描键盘,判断有无键按下?
若无键按下,则返回到显示程序;
若有键按下,则逐行扫描,找到按键的行,列号,并求得相应的键值送入 005AH单元后返回 。
入口条件:无
出口条件:扫描键盘若有键按下,则 0?CF,所按键的键值
(005AH) ; 无键按下,则 1? CF
注,逐行扫描的次序为 4- 3- 2- 1- 6- 5
原因,按键号的顺序进行,以便于译码产生相应的键值。
程序流程图:
关显示;键盘粗扫描:输出使所有行线为低电平,
输入列信号
4根列线为全,1”
键盘细扫描:先扫第 4行:
扫描行码初值 08H →DL ;
键值初值 0 →AH ;
1 →CF ; 返回主程序后,再调用显示程序无键按下有键按下
Y
N
A
B
键值 AH →BL ; 输出扫描行码,DL →(PC 口 )
输入扫描列码,(PA口 ) →AL
AL带 CF右移一位修改键盘,BL+4 →BL
指向下一列键的值已查完 4列?
延时 20ms以消除键抖动建立有键按下标志,0→CF
保存键值 BL →(005AH)
CF=1

RET
LOC–13:
N
Y
LOC–14:
LOC–151:
不是此列:
N
Y
A
C
修改扫描行码,DL右移一位
DL=0?
已扫完第 1行,准备扫描第 6行:
修改键值,10H →AL
修改扫描行码,20H →DL
即刚扫完的不是第 1行
DL=08H?
准备扫描下一行:
修改键值,AH+1 →AH
Y
N
Y
N
LOC–15
A BC
源程序分析,
SUB_12 PROC NEAR
MOV AL,0
OUT 2,AL ; 0 →(PB 口 ),清显示,全部不发光
MOV AL,3FH
OUT 4,AL ; 3FH?(PC口 ),使六行输出为全低
IN AL,0 ; (PA口 ) →AL,输入 PA口的列数据
INC AX ;检 查 4 根 列 线 是 否 为 全 ‘ 1’
AND AL,0FH ;只 保 留 4 根 列 线 的 位
JNZ LOC_12 ;若 Z=1,即 AL=0,表示无键按下
LOC_11,STC ; 1 →CF
RET
LOC_12,MOV DL,8 ;扫 描 行 码 初 值,先 扫 第 4 行
MOV AH,0 ;键值初值 ( 第 4 行第 1 列对应 ‘ 0’号键 )
LOC_13,MOV BL,AH ;键 值 → BL
MOV AL,DL ;输 出 扫 描 行 码
OUT 4,AL ;从 第 4 行开 始 逐 行 扫 描
IN AL,0 ;输 入 列 线 状 态 ( 列 码 )
MOV CX,4 ;共 4 列,需 内 循 环 4 次 以 查找 列号
LOC_14,RCR AL,1 ; 判断是否此列键按下?
JNC LOC_151 ; C=0,表 示 是 此 列 键 按 下,则 此键; 的 键 值 ( 号 ) 在 BL 中,转 LOC_151
C AL
ADD BL,4 ;不 是 此 列 键,修 改 键 值,使 适 合下 一 列
LOOP LOC_14 ;本段循环中,扫描输入的列码 AL 右移一位与 BL加 4;同步进行,直到移出的位为 0 时或移完 4 位时止
SAR DL,1 ; 修 改 扫 描 行 码,准 备 扫下 一 行
CMP DL,0 ; DL 初 值 为 08 H,右 移 4 次 后 将 变 为 00H
JE LOC_15 ;为 0,表示已扫描 4~ 1 行,转 LOC_15 扫描第 6 行
CMP DL,8 ;若 DL=08H,表示 6,5行已扫描完,仍未找到按下的键
JE LOC_11 ;转 返 回
ADD AH,1 ;键 值 加 1,指 向 下 一 行 要 扫 描 的 键
JMP SHORT LOC_13 ;转 回 扫 描 下 一 行
C DL
LOC_15,MOV AH,10H ;从第 6 行开始扫描,AH=10H,; 对 应 第 6 行 第 1 列 的 键 值
MOV DL,20H ;第 6 行的 扫 描 行 码
JMP SHORT LOC_13 ;转 回 扫 描 下 一 行
LOC_151,PUSH BX
MOV CX,28F8H ;延 时 20ms,等待 按键 抖动 消失
LOC_16,ROL BX,1
LOOP LOC_16
POP BX
CLC ; 0→C,建 立 有 键 按 下 的 标 志
MOV BYTE PTR DS,[ 5AH ],BL ; 键 值 → ( 005AH )
RET
SUB_12 ENDP
键抖动 (Debounce)及消除方法:
问题,什么是键抖动?
按键闭合时,是一种机械运动,触头将在闭合一断开一闭合之间弹跳数次,一般占十几 ms以下,键闭合时理想的电信号波形,实际波形,(放大后 )
带来的危害?
尽管只按一次键,因计算机处理速度度快,可能会被误认为按了几次 。
消除键抖动的三种方式:
注,单稳输出的脉冲宽度由 RC的参数决定,
应能覆盖键抖动的时间 。
(1) 利用单稳电路:
DW
C R
Q 去 CPU I/O口
+5V +5V
>
(2) 利用双稳电路:
原理:利用双稳的记忆功能和 R-S触发器的
‘ 0’触发,‘1’不能触发的特性 。 实现按一次键,只送给 CPU一个负脉冲 。
+5V
R
&
&
去 CPU I/O口
+5V
R
(3) 利用软件延时:
一般延时 20ms,等待键抖动消失后,
CPU才开始处理按键的要求 。
四,应用程序举例
1,‘8’字的循环显示程序功能,将数字 ‘ 8’在七段码显示器上,
从右到左依次循环显示 。
ORG 0100H
MOV DL,1 ;位 选 控 制 字,从右边 第 一位 开始 显示
LOC_1,MOV AL,DL
OUT 4,AL ;输 出 到 字 位 锁 存器,选 中 一 位 显 示
MOV AL,7FH ;‘ 8’ 的 七 段 显 示 代 码
OUT 2,AL ;输 出 显 示
MOV CX,30FFH
LOC_2,RCR AL,1 ;延 时 程 序,保 证 每 一 位 有 足够的 显示 时间
LOOP LOC_2
ROL DL,1,位 选 控 制 字 左 移 一 位,指 向 左边 显示管
JMP SHORT LOC_1
2,程序结构,整个程序由以下部分构成:
数据段、中断矢量区、主程序,8253中断服务程序和显示程序例 2.实时时钟及显示程序
1,功能,利用 8253生成一个实时时钟,并按如下格式在显示器上显示:
时 分 秒数据段:分为三部分
(1) 10ms 软件计数器,COUNT100 (0100H)
用于对来自 8253的 10ms 定时信号 (中断请求 )
减 1记数。初值为 100,减到 0时,即为 1s 时间到
(2) 显示缓冲区 (0101~ 0108H):亦为秒~时记数器;
依次存放待显示的实时时钟的数值
(3) 七段码显示代码表 (0109~ 0113H):
依次存放‘ 0’ ~‘ 9’和分隔符‘ _’的显示代码
DATA SEGMENT PARA PUBLIC ‘DATA’
COUNT 100 DB 100 ; 10ms 计 数 器
TENHOUR DB 0 ;’小时‘ 十 位 计 数 器
HOUR DB 0 ;’小时‘ 个 位 计 数 器
PLOT1 DB 10 ; ‘分隔符‘ 在显示代码表中的序号
TENMIN DB 0 ;’ 分‘ 十 位 计 数 器
MINUTE DB 0 ;’ 分‘ 个 位 计 数 器
PLOT2 DB 10 ;’分隔符‘ 在显示代码表中的序号
TENSEC DB 0 ;’ 秒‘ 十 位 计 数 器
SECOND DB 0 ;’ 秒‘ 个 位 计 数 器
DISP_TAB DB 3FH,06H,5BH,4FH,66H
DB 6DH,7DH,07H,7FH,6FH,40H
DATA ENDS
中断矢量区位于 0000,0200~ 0203,对应 8253 0通道中断向量为 80H ( ∵ 80H× 4=0200H )
INTTAB DW 0340H 中断服务程序的偏移量
DW 0000H 中断服务程序的段地址相应的伪指令为:
主程序:
含初始化和循环显示实时时钟两部分
(1) 初始化部分:
含,SP置初值; 8253,8259 等芯片的初始化
(2) 循环显示部分:
从左至右周而复始将当前的时间在显示器上扫描显示,直到按 RESET 键方可退出主程序,
CLI ; 0 → IF,初 始 化 完 成 前,禁 止 中 断
MOV SP,0500H
MOV AL,17H ; 8259 初 始 化,ICW1 命 令 字
17H,0 0 0 1 0 1 1 1—— 下有 ICW4
ICW1特征字 边沿触发 单片系统
OUT 40H,AL ;送 ICW1 到 8259
MOV AL,80H ; ICW2 命 令 字,8259 中 断 向 量
OUT 42H,AL
MOV AL,01H ; ICW4 命 令 字
01H,0 0 0 0 0 0 0 1—— 8086系统
OUT 42H,AL
ICW4特征字非特殊全套方式非缓冲方式正常中断结束方式
MOV AL,36H ; 8253 初 始 化 计 数 器 0 的 控 制 字
36H,0 0 1 1 0 1 1 0—— 二进制数
OUT 26H,AL ;送入 8253 控 制 寄存 器
MOV BX,15000 ;对 应 10ms 定时器 ( 8253计数器 0)
MOV AL,BL ; 的 初 始 值
OUT 20H,AL ;写 入 8253 计 数 器 0 低 八 位
MOV AL,BH
OUT 20H,AL ;写 入 计 数 值 高 八 位
STI ;开 中 断,初 始 化 完 成选中计数器 0 先写低八位先写高八位方式 3:方波速率发生器
FOREVER,MOV BX,OFFSET TENHOUR
MOV CX,8
MOV DL,80H ;位 选 控 制 字,先 从 最 左 边 位 开 始; 扫 描 显 示
DISPCLK,MOV AL,[ BX ] ;取 出 要 显 示 的 数 字
CALL DISPCHAR ;调 显 示 子 程 序 将 此 数 字 送; 显示,返 回 时,DL 已 右 移 一位INC BX ; 修改 显缓区 指针,指向 下一个 要显; 示 的数字 (注,本指令影响 ZF标志 )
LOOP DISPCLK ;循 环 显 示 下 一 位
JMP SHORT FOREVER ;开 始 新 一 轮 循 环显示子程序:
* 功能,将 AL中的数字查表转换成七段代码后,
送到 DL所指示的显示管上显示出来 。
* 入口条件,要显示的一位数字 ( ≤OAH) → AL,
该数字要显示的位置代码 (位选控制字 )→DL
* 出口条件,完成一位显示,且将 DL逻辑右移一位后返回 。
显示子程序,
PUSH BX
RET。
MOV BX,OFFSET DISP_TAB
XLAT,[BX+AL] →AL,查 表 求 得 相 应 的 七 段 代 码
OUT 02H,AL ;送 段 码 锁 存 器 ( 8255 PB口)
MOV AL,DL ;取 位 选 控 制 字
OUT 04H,AL ;送 字 位 锁 存 器( 8255 PC口)
CALL DISPLAY;调 延 时 1ms 子 程 序 让 显 示 管 充 分 发 光
ROR DL,1 ; 修 改 位 选 控 制 字,指 向
POP BX ; 右 边 一 位 显 示 管
DLC
10ms 定时器中断服务程序:
* 入口条件,8253 0通道作为 10ms 定时器,
每隔 10ms 产生一次中断时进入
* 出口条件,对实时时钟计时操作后返回。
* 流程图:
AX压入堆浅 ; 10ms 计数一次,(COUNT100)- 1 → (COUNT100)
(COUNT100) =0
10ms计数器再置初值,100 → (COUNT100)
秒钟数一次,(SECOND)+1 → (SECOND)
(SECOND) > 9?
秒计数器再置初值,0→(SECOND)
10秒计数一次,(TENSEC)+1→(TENSEC)
10秒计数器再置初值,0→ (TENSEC)
分计数一次,(MINUTE)+1 →(MINUTE)
(TEUSEC) ≥6?
入口
Y
Y
Y
N
N
N
分计数器再置初值,0→(MINUTE)
10分计数,(TENMIN)+1 →(TENMIN)
(MINUTE) > 9?
(HOUR) > 9?
(HOUR)=4?
(HOUR)=2?
小时清 0,0 →(HOUR),0 →(TENHOUR)
时计数器清 0,0 → (HOUR)
10时计数一次:
(TENHOUR)+1 → (TENHOUR)
送中断结束命令,20H → (8259)
AX弹出堆栈
10分计数器再置初值,0→(TENMIN)
时计数一次,(HOUR)+1 →(HOUR)
(TENMIN) ≥6?
RET
Y
N
Y
N
ADJHOUR:
TIMERX:
Y
Y
Y
N N
N
中断服务程序,
PUSH AX
DEC COUNT100 ; 10ms 计 数 器 减 1
JNZ TIMERX ; 未 到 1 秒,转 返 回
MOV COUNT100,100 ; 已 到 1 秒,重 赋 初 值 100
INC SECOND ; 秒 计 数 器 加 1
CMP SECOND,9 ; 秒 钟 大 于 9?
JLE TIMERX ; 否,转 返 回
MOV SECOND,0 ; 是,再 赋 初 值 0
INC TENSEC ; 10 秒 计 数 器 加 1
CMP TENSEC,6 ; 已 到 60 秒?
JL TIMERX ; 否,则 转 返 回
MOV TENSEC,0 ; 是,再 赋 初 值 0
INC MINUTE ; 分 计 数 器 加 1
CMP MINUTE,9 ; 分 钟 大 于 9?
JLE TIMERX ; 否,转 返 回
MOV MINUTE,0 ; 是,分 计 数 器 清 0
INC TENMIN ; 10 分 计 数 器 加 1
CMP TENMIN,6 ; 已 到 60 分?
JL TIMERX ; 否,转 返 回
MOV TEMMIN,0 ; 是,再 赋 初 值 0
INC HOUR ; 小 时 计 数 器 加 1
CMP HOUR,9 ; 小 时 个 位 大 于 9?
JA ADJHOUR ; 是,转 调 整 小 时
CMP HOUR,4 ; 否,则 判 是 否 等 于 4
JNZ TIMERX ; 否,转 返 回
CMP TENHOUR,2 ;是,则 判 10 时 位 为 2?
JNZ TIMERX ; 否,转 返 回
MOV HOUR,0 ; 已 到 24 小 时,则 小 时 计 数 器 清 0
MOV TENHOUR,0
JMP SHORT TIMERX ; 转 返 回
ADJHOUR,INC TENHOUR ; 10 小 时 位 加 1
MOV HOUR,0 ; 小 时 个 位 清 0
TIMERX,MOV AL,20H ; 8259A 的 中 断 结 束 命 令
OUT 40H,AL ; 字 EOI → ( 8259A )
POP AX
IRET
本章综合运用前面几章学过的知识,构建了一个实用的微机系统 —— 8086CPU最小系统 。
重点应掌握的两个内容:
1,由芯片 → 系统所必须解决的接口技术
2,在裸机上构建的监控程序的功能和常用算法。
本章小结