微机系统 - 第7章 -可编程接口芯片
可编程并行输入/输出接口芯片 8255A
-1:结构
8255A为40引脚、双列直插封装。
内部结构由数据端口、组控制电路、数据总线缓冲器、读/写控制逻辑四部分组成。
数据总线缓冲器:三态8位双向缓冲器,D7-D0同系统数据总线相连。CPU通过执行输入/输出指令来实现对缓冲器发送或接收数据,传送控制字和状态字。
读写控制逻辑: 管理数据信息、控制字和状态字的传送,接收来自CPU地址总线和控制总线的有关信号,向8255A的A、B两组控制部件发送命令
A组和B组控制电路:3个端口分成两组来管理。A口及C口高4位为A组,B口及C口低4位为B组。两组分别设有控制电路,每个控制组都接收来自读/写控制逻辑的“命令”,接收来自内部数据总线的“控制字”,并向与其相连的端口发出适当的控制信号。
数据端口:
3个8位数据端口:端口A、端口B和端口C
A1 A0 选择端口
0 0 A口(数据口)
0 1 B口(数据口)
1 0 C口(数据口)
1 1 控制口
-2控制字
8255A有两种控制字。一个是方式选择控制字,另一个是对C口进行置位或复位的控制字。
-3 : 8255A的工作方式
方式0:基本的 输入/输出方式。 适用A、B、C口。
方式1:选通的 输入/输出方式。 适用A、B口。
方式2:双向选通输入/输出方式。适用A口。
在方式0下,C口的高4位和低4位以及A口、B口都可以独立地设置为基本的输入口或输出口。4个口的输入/输出可以有16种组合方式
方式1输入的逻辑功能结构
接口介绍:
STB-bar:输入的选通信号,低电平有效。由外设提供 ,为低电平时,把输入的数据送入A端口或B端口的数据锁存器.
IBF :输入缓冲器满信号 , 高电平有效。由8255A输出 ,有效时,用以通知外部设备输入的数据已写入缓冲器.
INTRx:中断请求信号,高电平有效。当STB-bar、IBF和INTE都为高电平时,表明数据锁存器内已写入了数据,使INTR成为高电平输出。 (我满了,你没有输入了,我允许读出了)
CPU响应中断执行IN指令后,在控制下从8255A中读取数据时,RD的下降沿使INTR复位,RD的上升沿又使IBF复位,使外设知道可以进行下一字节输入了。
INTE:中断允许信号。
A端口用PC4位的置位/复位控制,B端口用PC2位的置位/复位控制。
只有当PC4或PC2置“1”时,才允许对应的端口送出中断请求。
方式1输出的逻辑功能结构
OBF-bar:输出缓冲器满信号;低电平有效。由8255A输出,当其有效时,表示CPU已经将数据输出到指定的端口,通知外设可以将数据取走。
ACK-bar:响应信号,低电平有效。由外设送来,有效时表示8255A的数据已经被外设所接收。
INTR:中断请求信号,高电平有效。当外设接收了由CPU送给8255A的数据后,8255A就用INTR端向CPU发出中断请求,请求CPU再输出后面的数据。
INTR是当OBF、ACK和INTE都为高电平时,才能被置成高电平。由的WR下降沿清除.
INTE:中断允许信号。
A口的INTE由PC6置/复位,
B口的INTE由PC2置/复位。
方式2的逻辑功能结构:
INTE2是与输入相关的中断允许,由对PC4的置位/复位控制.
INTEl是与输出相关的中断允许,由对PC6的置位/复位控制.
5个联络信号与在方式1中的含义基本相同,因为是双向传送,所以INTRA在输入或输出
时都可以产生。
-4:例 7.1.1 8255A 方式 0 应用:
8255A 产生波形接口电路。
利用 8255A 在方式 0 下工作,使其在PC 0.PC 3引脚产生如图 所示的波形,试编写相应程序段。
设8255A 各端口地址分别设为60H .61H.62H和63H,波形延时时间可调用延时 1ms 子程序(D1ms)实现
PC0,PC3对应了C的低4位(,也就是控制字的最后一个)
先看看控制字:输出为0,
- | (00)(0)(0) | (0)(0) | (0)
传输的数据的顺序是 01H->09H->00H->08H
START: MOV AL,80H ;送各口方式0,C输出输出控制字
OUT 63H,AL
A1: MOV AL,01H
OUT 62H,AL
CALL D1ms
MOV AL,09H
OUT 62H,AL
CALL Dlms
MOV AL,00H
OUT 62H,AL
CALL D1ms
MOV AL,08H
OUT 62H,AL
CALL D1ms
JMP A1
8253A 计数器/定时器
-1基本功能:
3个独立的16位计数器,可以进行3个16位的独立运算
每一个计数器具有六种工作方式
可以进行2/10进制计数,
计算频率0~2Mhz
可以作为计数器or定时器
-2结构:
A1 A0 选择端口
0 0 计时器0(数据口0)
0 1 计时器1(数据口1)
1 0 计时器2(数据口2)
1 1 控制口
-3:初值计算:
计数方式:计数值= 要求的计数次数
定时方式:计数值= OUT时间÷CLK周期
计数值读写格式:
只低,高八位清0
只高,低八位清0
先低后高
计数值读出的方式:直接读 or 锁存读
-4:控制字:
-5:六种工作方式:
-6:启动方式:
软:CPU写入计数值
硬:GATE上跳沿
计数值的极限值:
-7例题:
例 7.2.1 8253 的初始化设计。
• 设某8253通道1工作于方式0,按BCD方式计数,计数初值为400。计数器0、计数器1、计数器2和控制寄存器的端口地址依次为80H-83H,试编写8253的初始化程序
1,先看看控制字:
(01)(11)(000)(1)
通道1,xx,0模式,BCD模式 ,
这里的xx因为我们需要送400,12位,但是一次只能送8位,所以需要使用先低后高的11读写格式
2,再看计数值:使用BCD码,也就是0400H,送入计数器1的数据端口,地址是81H,先低后高,先送低位00H,后送高位04H
3,初始化程序
MOV AL,71H ;控制字
OUT 83H,AL ;送达控制字
MOV AL,00H ;低8位计数值
OUT 81H,AL
MOV AL,04H ;高8位计数值
OUT 81H,AL
可编程串行通信接口芯片 8251A
-1工作方式
两种基本的通信方式:并行,串行
串行通常在两个设备之间传送
按照通信的线路可以分为3类:单工通信,半双工,全双工
-2功能:
(1)同步下波特率:0~64K. 异步下波特率0 ~ 19.2K
(2)同步模式下,可以用5,6,7,8来代表字符,并且内部可以自动检测同步字符,实现同步(还可以增加同步下的奇偶校验)
(3)异步模式下,可以用5,6,7,8位代表字符,1位奇偶校验,每个字符设置1,1.5,2个停止位
(4)所有的输入输出电路都与TTL电平兼容。
(5)全双工双缓冲的接收/发送器。
-3内部结构
数据总线缓冲器:
三态双向8位缓冲器,它是8251A与微机系统数据总线的接口,数据、控制命令及状态信息均通过此缓冲器传送。
内容:命令寄存器 ,状态寄存器 .方式寄存器 ,两个同步字符寄存器 ,数据输入缓冲器 ,数据输出缓冲器
发送缓冲器:
接收CPU送来的并行数据,按照规定的数据格式变成串行数据流后,由TXD输出线送出。
TXRDY:发送器准备好,高电平有效。有效时,表示发送器已准备好接收CPU送来的数据。当CPU向8251A写入一个数据后,TXRDY自动复位。当8251A允许发送,且数据输出缓冲器为空时,此信号有效。在用中断方式时,此信号作为中断请求信号。
TXD:发送数据线
TXEMPTY:发送移位器空,高电平有效。有效时,表示发送器中的移位寄存器已经变空。8251A从CPU接收待发的数据后,自动复位。
TXC:发送时钟,由它控制8251A发送数据的速度。在异步方式下,TXC的频率可以是波特率的1倍、16倍或64倍,可由程序设定。在同步方式下,TXC的频率与发送数据波特率相同。
发送方式
异步:发送器为每个字符加上一个起始位,并按照规定加上奇偶校验位以及1个、1.5个或者2个停止位。然后在发送时钟TXC的作用下,由TXD脚逐位地串行发送出去。
同步:发送缓冲器在准备发送的数据前面先插入由初始化程序设定的一个或两个同步字符,在数据中插入奇偶校验位。然后在发送时钟TXC的作用下,将数据逐位地由TXD引脚发送出去。
接收缓冲器:
接收在RXD脚上输入的串行数据,并按规定的格式把串行数据转换为并行数据,存放在数据总线缓冲器中的数据输入缓冲器中。
SYNDET:同步检测。只用于同步方式。内同步时,作为输出,如果8251A检测到了同步字符,则输出高电平。外同步时,作为输入,这个输入端上的一个正跳变,使8251A在RXC的下一个下降沿时开始装配字符。
RXC:接受时钟
RXD:接收数据线
RXRDY:接收数据准备好,高电平有效。在允许接收的条件下,当8251A已经从它的串行输入端接收了一个字符,并完成了格式变换,此信号有效,通知CPU读取数据。当CPU从8251A读取一个字符后,RXRDY信号自动复位。在中断方式时可作为中断请求信号。
异步接收方式:在“允许接收”条件下,接收缓冲器监视RXD线。发现起始位后,开始采样并进行字符装配,装配一个后直接送到数据输入缓冲器,同时发出RXRDY有效信号。
同步接收方式:先搜索同步字符。匹配同步字符后,SYNDET引脚变为高电平。
外同步方式:SYNDET端出现高电平,8251A便认为已经完成同步。实现同步之后,对RXD线采样,把收到的数据送入移位寄存器中。装配字符,然后送入数据输入缓冲器,并且在RXRDY引脚上发出有效信号
读写控制逻辑电路:
CLK:时钟,产生8251A的内部时序。同步方式时,CLK频率要大于RXC和TXC频率的30倍。异步方式时,此频率要大于RXC和TXC频率的4.5倍。
调制解调控制电路
DTR-bar:数据终端准备好,输出,低电平有效。由命令字的D1置“1”变为有效,用以表示8251A准备就绪。
RTS-bar:请求发送,输出,低电平有效。用于通知调制解调器,8251A要求发送。由命令字的D5位置“1”来使其有效。
DSR-bar:数据装置准备好,输入,低电平有效。表示调制解调器已经准备好。CPU通过读状态寄存器的D7位检测这个信号。
CTS-bar:请求发送清除,也称为允许发送,输入,低电平有效,是调制解调器对8251A的信号的响应,当其有效时8251A方可发送数据。
(1)调制解调控制电路用来简化8251A和调制解调器的连接。
(2)在进行远程通信时,要用调制器将串行接口送出的数字信号变为模拟信号,再发送出去;接收端则要用解调器将模拟信号变为数字信号。
(3)在全双工通信情况下,每个收发端都要连接调制解调器。DTR:数据终端准备好,输出,低电平有效。由命令字的D1置“1”变为有效,用以表示8251A准备就绪。
-4:控制字:方式选择/操作命令
方式选择控制字在8251A复位之后送入,
操作命令控制字在方式选择控制字之后的任何时间均可送入
方式选择:方式选择控制字用来选择工作方式,确定数据位长度、是否要奇偶校验、停止位的位数或同步字符的个数等。
命令控制字:命令控制字控制8251A的发送、接收、内部复位等的实际操作。
CPU可以任意时候通过in将8251A内部状态寄存器的内容读入来判断8251A的工作状态
题目
下列几种芯片中能接管总线、控制I/O接口与存储器直接进行数据传送的是( )。A
A. 8237A B. 8259A C. 8255A D. 8253A
选用如下图给出的元器件设计一个恒温箱温度采集控制系统。该系统有两个状态:设置状态和控制状态。在设置状态时,通过键盘可以修改恒温箱的设定温度;在控制状态时,用开关量输出进行简单控制。检测温度与设定温度进行比较,当检测温度小于设定温度时,控制继电器加热;当检测温度大于设定温度时,关闭加热。当有按键时,发出1kHz声音,用于按键提示。
系统有两位七段数码管显示温度值(0~99℃)。在设置状态时,系统显示设定温度;在控制状态时,系统显示当前检测温度。系统通过4x4键盘输入设定温度值和启动控制,键盘有0~9键、Setting键和Control键共12个键可用。
(1)画出系统的硬件连接原理图,并标明分配给各元器件的端口地址。
(
设置状态,通过键盘来输入,采用矩阵+行扫描 (c)
显示,使用2个7段七段数码管 (ab)
8255连接CPU,两个数码管,一个键盘输入(4位) ,一个输入c低,3个输出abc高 ,10001000
CPU使用8086即可
)
(2)写出“0”对应的七段数码管译码值;编写8255、8253初始化程序;
(3)编写AD转换子程序(adc)、显示子程序(display)、按键识别子程序(key)和主程序(main)。
(1)硬件原理图如下
(2)写出“0”对应的七段数码管译码值;编写8255、8253初始化程序;
“0”对应的七段数码管译码值是:0C0H
;8255初始化
init_8255 proc near
mov dx, PORT_CTR_8255
mov al, 10001000b ;初始化8255控制字
out dx, al
ret
init_8255 endp
;8253_计数器0初始化---20ms中断请求
init_8253 proc near
mov dx, PORT_CTR_8253
mov al, 00110100b ;初始化8253控制字 : 计数器选择, 读写格式, 工作方式 BCD/B
out dx, al
mov dx, PORT_COUNTER0_8253
mov ax, 20000 ;计数常数 ; 20ms/(1/1Mhz) =20000
out dx, al ;写低8位
mov al, ah
out dx, al ;写高8位
ret
init_8253 endp
;开始发声,8253计数器1,方式3, 1kHz方波----
startBeep proc near
mov dx, PORT_CTR_8253
mov al, 01110110b ; 初始化8253控制字,计数1,r/w低8位 ,高8位,方式3,二进制计数
out dx, al
mov dx, PORT_COUNTER1_8253
mov ax, 1000 ; 计数常数 ; 1mhz/1khz =1000
out dx, al ; 写低8位
mov al, ah ; 写8位
out dx, al
ret
startBeep endp
;----5.2停止发声,方式0----
stopBeep proc near
mov dx, PORT_CTR_8253
mov al, 01110000b ; 初始化8253控制字,计数1,方式0
out dx, al
ret
stopBeep endp
;----5.3发声100ms----
beep_200ms proc near
push dx
call startBeep
delay 0ffh
call stopBeep
pop dx
ret
beep_200ms endp
(3)编写AD转换子程序(adc)、显示子程序(display)、按键识别子程序(key)和主程序(main)。
Adc proc near
; 启动AD转换
mov dx, PORT_START_0809
mov al, 0
out dx, al ;选择通道0
mov is_adc_started, 1; 下次是查询状态
sample_ch0:
; 查询转换结束引脚eoc,非阻塞方式
mov dx, PORT_EOC_0809
in al, dx
test al, 00000001b ;eoc引脚为高电平?
jz exit_isr ;eoc变高到此,输入adc转换结束数值
mov dx, PORT_DATA_0809
in al, dx
mov [sample_ch0_val], al; 保存AIN0采集数字量
mov is_adc_started, 0 ; 下次是启动AD状态
call calc_ad2tmp; 计算当前温度值
exit_isr:
ret
Adc endp
display proc far
push ax
push bx
push cx
mov bx, offset led_table
cmp is_in_control_state, 1
je get_cur_tmp_val
mov cl, setting_tmp_val
jmp start_display
get_cur_tmp_val:
mov cl, sample_tmp_val
start_display:
mov al, 0
to_w10:
cmp cl, 10
jb display_w10
inc al
sub cl, 10
jmp to_w10
…
cmp is_on_heatting_state, 1; 在加热时
je on_heatting
and al, 01111111b
jmp out_w1
on_heatting:
or al, 10000000b
out_w1:
mov dx, PORT_B_8255
out dx, al ;显示个位
pop cx
pop bx
pop ax
ret
display endp
key_identify proc near
;(1)判断是否有键按下
mov dx, PORT_C_8255
mov al,0
out dx, al; PC3~0行输出全0
nop
in al, dx ;读入列值PC7~4
and al, 11110000b
cmp al, 11110000b
jne re_confident
mov is_new_key, 0; 无新键值
jmp error_exit
;(2)有键按下,软延时,再次判断
re_confident:
delay 0ffh
in al, dx ;读入列值PC7~4
and al, 11110000b
cmp al, 11110000b
jne has_key
mov is_new_key, 0; 无新键值
jmp error_exit
;(3)识别按键。确实有键按下,开始扫描,
has_key:
mov ah, 11111110b
mov cx,4
scan_next_row:
mov al, ah
out dx, al
nop
in al, dx
and al, 11110000b
cmp al, 11110000b
jne find_key ; 行值ah, 列值al
rol ah, 1
loop scan_next_row
jmp error_exit
find_key:
and ah, 00001111b
mov cl,4
shr al, cl
; 计算键位值,行值ah, 列值al
;计算行计数值
…
mov ah, bl ; 保存行计数值ah
;计算列计数值
mov bl, -1 ;计数0位置
mov cx, 4
next_column:
inc bl; 列号计数
shr al, 1
jnc find_column
loop next_column
mov is_new_key, 0; 无新键值
jmp error_exit
find_column:
mov al, bl;保存列计数值al
shl ah, 1
shl ah, 1; x4
add al, ah ;al键位置值
mov cur_key, al; 保存当前键值
mov is_new_key, 1; ***有新键值
call beep_200ms;发声
;(4)判断是否键释放,行输出全0
no_release_wait:
mov al, 0
out dx, al ; PC7~4列输入,PC3~0 行输出
nop
in al, dx; 读入行值
and al, 11110000b
cmp al, 11110000b
jne no_release_wait
delay 0ffh ;键释放,软延时
error_exit:
ret
key_identify endp
main:
;----(0)初始化
call init_vct_table ;中断时用
call init_8255 ;8255A初始化;!!!初始化8255时,端口数据消失
call init_8253 ;中断时不用
call init_8259 ;仿真时不用
call display
; --->转到两个状态
main_loop:
cmp is_in_control_state, 1
…
;----(1)设置状态---------------
loop_in_setting_state:
call key_identify;识别按键
cmp is_new_key, 1
jne loop_in_setting_state
cmp cur_key, 0Bh; 0Bh,进入控制状态
je change2control_state
…
jmp main_loop
;----(2)控制状态-----------
loop_in_control_state:
call key_identify
cmp cur_key, 0AH; 0AH,设置按键
je change2setting_state; 转到设置状态
…
call display
jmp main_loop
ret
选择使用如下元器件,设计一个多路传感器电压采集显示系统。
设计要求:
(1)由两位共阳极七段数码管组成静态显示器,由八个按键组成线性键盘,8通道的ADC连接8个传感器(由可变电阻代替),一路DAC的输出连接一个电压表, 并由8259和8253组成定时中断请求和按键提示音。
(2)每20毫秒由8253产生一次中断请求。设8253时钟CLK等于1MHZ,8253的OUT0连接到8259的IR2端,已知写入8259的ICW2是08H,每次中断时,中断服务程序对ADC的8个通道传感器电压值采集一遍,中断服务程序函数名称为isr_20ms_adc。
(3)当有按键按下时,发出1kHz提示声音,两位七段数码管显示与按键对应的ADC通道电压值(保留小数点后1位,单位为V),K0键对应第一个ADC通道,...,K7对应第8个ADC通道,并用DAC0832输出这个通道传感器电压的值,用电压表可以测量。
(4)当无按键按下时, 不发提示音,用两位七段数码管显示八个传感器平均电压值(电压范围为0.0V~5.0V,保留小数点后1位数,单位为V),并用DAC0832输出八个传感器电压的平均值,用电压表可以测量。
试完成如下设计:
1. 画出与8086连接的硬件原理图。
2. 编写8255、8253和中断向量表的初始化程序;写出七段数码管段码译码表;并编写多路传感器电压采集显示系统的程序。
答:
(1)
(2)
; 由MASM32编译, 并开始使用.IF .REPEAT .WHILE .UNTIL 等宏, 可以不用低层的分支结构,
; 结构化更好。
; Author: hyp@jlu.edu.cn , QQ:hyper/790516
;----0.主程序-----------------------------------------------------------------
main proc far
; (1)初始化
call init_vct_table ;中断向量初始化
call init_8255 ;8255A初始化
call init_8253 ;8253初始化
call init_8259 ; 8259初始化
enable_isr; 开中断
; (2)循环
.WHILE 1
call key_identify ;判断和识别按键
.IF key_is_pressed == 0 ;无键按下时
call display_AV_Vx ;显示8个通道平均电压
.ELSE ;有键按下时
call display_CH_Vx ;显示当前按键对应Kn通道电压
.ENDIF
.ENDW
ret
main endp
;1.中断向量表初始化
init_vct_table proc near
;mov bx, 4*12h ; n = 12H, IR2有中断请求输入, ICW2=10H
mov bx, 4*2 ; n = 2, NMI非屏蔽中断
mov ax, 0
mov es, ax
mov ax, offset isr_20ms_adc
mov es:[bx], ax
mov ax, seg isr_20ms_adc
mov es:[bx+2], ax
ret
init_vct_table endp
;-----------------------------------------------------------------------------
;2.8255初始化
init_8255 proc near
out_port PORT_CTR_8255, 10001001b ;初始化8255控制字
ret
init_8255 endp
;-----------------------------------------------------------------------------
;3.8253_计数器0初始化---20ms中断请求
init_8253 proc near
out_port PORT_COUNTER_CTR, 00110100b ;初始化8253控制字,计数0,r/w低8位 ,高8位,方式2,二进制计数
mov ax, 20000 ;计数常数 ; 20ms/(1/1Mhz) =20000, ; 40ms/(1/1Mhz) =40000
out_port PORT_COUNTER0, al ;写低8位
out_port PORT_COUNTER0, ah ;写高8位
ret
init_8253 endp
;-----------------------------------------------------------------------------
;4.8259初始化
init_8259 proc near
out_port PORT_8259_0, 00010010b ;初始化8259控制ICW1
out_port PORT_8259_1, 08H; ICW2
out_port PORT_8259_1, 01H; ICW4
ret
init_8259 endp
;-----------------------------------------------------------------------------
;5.发声xxms----
beep_start proc near
push ax
out_port PORT_COUNTER_CTR, 01110110b ; 开始发声:初始化8253控制字,计数1,r/w低8位 ,高8位,方式3,二进制计数
mov ax, 1000 ; 计数常数 ; 1mhz/1khz =1000
out_port PORT_COUNTER1, al ; 写低8位
out_port PORT_COUNTER1, ah ; 写8位
pop ax
ret
beep_start endp
beep_stop proc near
push ax
out_port PORT_COUNTER_CTR, 01110000b ; 停止发声:初始化8253控制字,计数1,方式0,
pop ax
ret
beep_stop endp
;6.中断服务程序--- 双状态,非阻塞方式
; 进两次采集一次AD值,40ms采集一次, 循环采集8个通道AD值,并计算8个Vx_x10电压值
isr_20ms_adc proc far
.IF ( I_Flag == 1)
push ax
push bx
push cx
push dx
push si
pushf
.IF is_adc_started == 0 ; 没有启动,则启动
out_port PORT_ADC_START, cur_sensor_channel ;启动当前通道
mov is_adc_started, 1; 标志已经启动
.ELSE
; 查询转换结束引脚eoc,非阻塞
in_port PORT_ADC_EOC ; 输入值在al中
test al, 00000001b ;eoc引脚为高电平?
.IF !zero? ; AD转换结束?
in_port PORT_ADC_DATA ; 输入值在al中
mov si, offset sensor_Nx
mov bh, 0
mov bl, cur_sensor_channel
add si, bx
mov [si], al ; 保存当前通道ADC数字量
;计算Vx_x100电压,并保存。sensor_Vx_x100 = 100*5*Nx/256
mov si, offset sensor_Vx_x100
shl bx, 1 ; x2
add si, bx
mov ah, 0
mov cx, 500
mul cx ; dxax = ax *cx
mov cx, 256
div cx ; ax = dxax/cx
mov [si], ax
; 下次采集下一个通道
inc cur_sensor_channel
.IF cur_sensor_channel == 8
mov cur_sensor_channel, 0
.ENDIF
mov is_adc_started, 0 ; 下次是启动AD状态
.ENDIF
.ENDIF
popf
pop si
pop dx
pop cx
pop bx
pop ax
.ENDIF
iret
isr_20ms_adc endp
;-----------------------------------------------------------------------------
;7.识别键盘---8个线性按键,非阻塞。出口:保存按键位置值到当前按键变量cur_key
key_identify proc near
in_port PORT_C_8255 ; ;读入列值PC7~0
;(1)判断是否有键按下
.IF al == 11111111b
mov key_is_pressed, 0 ;无按键
call beep_stop ;停止发声
.ELSE
;(2)有键按下,软延时,再次判断
;delay 0ffh
in_port PORT_C_8255 ;读入列值PC7~0
.IF al == 11111111b ;再次判断
mov key_is_pressed, 0 ;无按键,是干扰
call beep_stop ;停止发声
;(3)确实有键按下,识别具体按键。
.ELSE
mov ch, 8 ;共8个按键
mov cl, 0 ;按键序号
.WHILE ch != 0
shr al, 1
.IF carry? ;C=1?
inc cl
.ELSE
.BREAK ;C=0?
.ENDIF
dec ch
.ENDW
mov cur_key, cl ;保存键序号值到当前按键变量
mov key_is_pressed, 1 ;有按键
call beep_start ;发声
.ENDIF
.ENDIF
ret
key_identify endp
;-----------------------------------------------------------------------------
;8.Kn按键按下时,显示ADC n通道的电压值,并输出这个电压值到DAC
display_CH_Vx proc near
mov si, offset sensor_Vx_x100
mov bh, 0
mov bl, cur_key
shl bx, 1 ; x2
add si, bx
disable_isr ;关中断
mov ax, [si] ;取某通道的sensor_Vx_x100
enable_isr ;开中断
;计算百位和十位数电压数值
mov bx, offset led_table
mov cl, 100
div cl ; ahal = ax/cl
xlat ;al <-- [bx + al]
and al,01111111b ;加小数点
out_port PORT_A_8255, al ;显示带小数点的百位数
mov al, ah
mov ah, 0
mov cl, 10
div cl ; ahal = ax/cl
xlat ;al <-- [bx + al]
out_port PORT_B_8255, al ;显示十位数
; DAC输出当前通道的电压
mov si, offset sensor_Nx
mov bh, 0
mov bl, cur_key
add si, bx
disable_isr ;关中断
mov al, [si] ;取当前通道Nx值
enable_isr ;开中断
out_port PORT_DAC_DATA, al
ret
display_CH_Vx endp
;-----------------------------------------------------------------------------
;9.显示8个通道平均电压
display_AV_Vx proc near
; 计算8个通道的平均Nx值
mov bx, offset sensor_Nx
mov cl, 8
mov ax, 0
mov dx, 0
clc
.WHILE (cl != 0)
disable_isr ;关中断
mov dl, [bx]
enable_isr ;开中断
adc ax, dx
inc bx
dec cl
.ENDW
mov cl, 8
div cl; al = ax/cl
mov sensor_Nx_AV, al
out_port PORT_DAC_DATA, al; DAC输出平均电压
; Vx_x100 = 500*Nx/256
mov ah, 0
mov cx, 500
mul cx ; dxax = ax*cx
mov cx, 256
div cx ; ax = dxax/cx, sensor_Vx_AV_x100
; 计算百位和十位数电压数值
mov cl, 100
div cl ; ah(余)al(商) = ax/cl
mov bx, offset led_table
xlat ;al <-- [bx + al]
and al,01111111b;加小数点
out_port PORT_A_8255, al ;显示百位
mov al, ah ; ah(余)
mov ah, 0
mov cl, 10
div cl ; ahal=ax/cl
xlat ;al <-- [bx + al]
out_port PORT_B_8255, al ;显示十位数
ret
display_AV_Vx endp
;-----------------------------------------------------------------------------
End
五. 综合设计题(15分)
一般乐器需要保存在一定的湿度范围内,试设计一个湿度闭环采集控制系统。
系统由两位七段数码管、4x4 按键、湿度检测和输出控制加湿器四部分组成。显示湿度范围为0~99%;键盘有0~9键、设置键和控制工作键共12个键可用。
该系统有两个状态:目标湿度设置状态和控制状态。由键盘可输入设定的目标湿度值和启动控制工作。
- 在设置状态时,可以修改设定的目标湿度值, 显示并保存设定的湿度值;
- 在控制状态时,显示采集的当前湿度值,采集的当前湿度与设定湿度进行比较:
- 当检测湿度小于设定目标湿度 - 10% 时,控制强加湿(2V输出电压);
- 当检测湿度大于设定目标湿度 - 10%,并且检测湿度小于设定目标湿度 + 10% 时,控制中等加湿(1V输出电压);
- 当检测湿度大于设定目标湿度 + 10%时,关闭加湿(0V输出电压)。
要求:
(1) 画出系统硬件连接图(7分)。
利用一片8255连接两位共阳极七段数码管,以静态方式显示;键盘以行列反转方式工作。湿度采集采用ADC0809; 输出控制加湿器采用DAC0832。当有按键时,用8253发出1kHz声音,用于按键提示。
(2)编写8255、8253初始化程序。编写静态显示子程序(display)、按键识别子程序(key)、湿度采集子程序(adc)、控制加湿子程序(dac)和主程序(main)。(8分)选择使用以下参考资料:
8255A编程字:
从方式名称、启动方法、计数值有效期限角度,说明8253的方式1与方式2的工作特点。
方式1是可编程发单稳态方式,由硬件启动,计数值多次有效,计数过程中输出保持为低,直到计数到0,OUT向高电平跳变。
方式2是脉冲发生器,有硬件和软件两种启动方式,计数值重复有效,OUT可以产生一个连续的波形。开始计数后当减到1时输出将变低一个时钟的宽度,然后恢复为高电平又重新计数。
(对比这个去记忆:
)
为什么对8253A写入计数值0是最大的计数值?在二进制计数方式下计数值相当于多少?如果8253A的时钟CLK频率为1.193MHz,工作在周期工作方式时,计算最大可以产生每秒多少次的周期信号(保留一位小数)?
因为8253A的OUT引脚是的计数器从1减少到0是有变化,设置计数值为0时,第一时钟到来时数值减1后变为65535,OUT引脚并不变化,则设置计数值为0则比65535还多一个,相当于65536.
取最大计数值65536, 则时钟为1.193MHz时, 在周期工作方式时,周期 = 1.193MHz/65536 = 18.2Hz (1/一个计数*T)
-用8253A产生5ms的周期信号,做为8259A中断请求输入,CLK=1MHz,分析8253A计数器需采用哪种工作方式,计数初值是多少。
方式 3(方波发生器)比较合适。方式 3 能持续输出周期性的方波信号,且输出信号的频率和周期容易通过设置计数初值来控制,满足产生周期信号的需求
周期 T = 1/CLK = 1μs。要产生 5ms 的周期信号,根据公式计数值 = 要求的定时时间 ÷CLK 周期,计数初值 N = 5ms÷1μs = 5000
方式2(脉冲频率发生器)也可以
- 已知
CLK=1MHz
,时钟周期为1μs
,目标周期为5ms=5000μs
。 - 计数初值
N = 目标周期 / CLK周期 = 5000μs / 1μs = 5000
说明8253的方式2与方式3的工作特点。
- 方式 2(脉冲频率发生器方式):可软、硬件启动计数。计数过程中,输出端平时为高电平,当计数值减到 1 时,输出变为低电平,减至 0 后,输出又变高,同时计数值重新装入,开始新的计数周期,输出连续的负脉冲,脉冲频率为输入时钟频率的 1/N(N 为计数初值)。
- 方式 3(方波发生器方式):同样可软、硬件启动。当计数初值为偶数时,输出高、低电平宽度相等的方波;为奇数时,高电平比低电平多一个时钟周期。计数到 0 后自动重新装入初值继续计数,持续输出方波
说明8253的方式1与方式5的工作特点。
- 方式 1(可编程单稳方式):由硬件(GATE 上跳沿)启动计数,写入控制字后 OUT 初态为高电平,GATE 触发后,OUT 输出 N 个 CLK 宽度的低电平脉冲(N 为计数初值),计数到 0 后,可再次由外部触发启动,计数初值下次有效,在 OUT 输出低电平时,若 GATE 出现上升沿,计数器重新计数,OUT 低电平宽度变长。
- 方式 5(硬件触发选通方式):也是硬件启动(GATE 上跳沿),写入控制字后 OUT 初态为高电平,GATE 触发后开始计数,计数到 0 时,OUT 输出一个 CLK 周期的负脉冲,之后恢复高电平,可再次由外部触发启动,计数过程中 GATE 上升沿会使计数器从初值重新计数 。
简述8253的主要特点。(36十二,兼容计数定时)
- 有 3 个独立的 16 位计数器,可进行 3 个 16 位的独立计数。
- 每个计数器有六种工作方式,通过编程设置。
- 能进行二进制或十进制(BCD 码)减法计数 。
- 计数频率范围为 0 - 2MHz。
- 既可以作计数器,对外部事件计数;也可以作定时器,根据输入时钟频率和设定的计数初值产生定时信号。
- 所有的输入输出都与 TTL 电平兼容。
8253有几个通道?各采用几种工作方式?简述这些工作方式的特点。
- 8253 有 3 个通道,每个通道都可采用 6 种工作方式。
- 方式 0(计数结束中断方式):软件启动计数,每设置一次初值只启动一次计数过程。写入控制字后 OUT 初态为低,计数过程中保持低电平,计数到 0 时 OUT 变为高电平,可用于产生中断请求。GATE 为 1 时正常计数,为 0 时计数暂停。
- 方式 1(可编程单稳方式):硬件(GATE 上升沿)启动,写入控制字后 OUT 初态为高,GATE 触发后 OUT 输出低电平脉冲,宽度由计数初值决定,可重复触发,计数初值下次有效。
- 方式 2(脉冲频率发生器方式):软、硬件均可启动,输出连续负脉冲,频率为输入时钟的 1/N,计数值减到 1 时 OUT 变低,减到 0 时恢复高并重新装入计数值。
- 方式 3(方波发生器方式):软、硬件启动,根据计数初值奇偶输出不同占空比方波,计数到 0 后自动重装初值继续计数。
- 方式 4(软件触发选通方式):软件启动(装入初值且 GATE 为高时),计数到 0 时 OUT 输出一个 CLK 周期的低电平脉冲。
- 方式 5(硬件触发选通方式):硬件(GATE 上升沿)启动,计数到 0 时 OUT 输出一个 CLK 周期的负脉冲,可重复触发。
8253有几种读操作方式?简述之。
4种(锁存不算就是3种)
- 直接读/写low:只读写低 8 位,高 8 位清 0;
- 直接读/写high或只读写高 8 位,低 8 位清 0 。这种方式简单,但可能丢失数据精度。
- 锁存读:计数值锁存
- 先低 8 位,后高 8 位:先读取低 8 位,再读取高 8 位,适用于需要完整获取 16 位计数值的情况,确保数据的完整性 。
在8253计数器的六种工作方式中,方式2和方式3各输出何种波形,它们有何特点。
- 方式 2 输出波形及特点:输出连续的负脉冲。特点是可软、硬件启动,计数值减到 1 时 OUT 变低,减到 0 时恢复高并重新装入计数值,脉冲频率为输入时钟频率的 1/N。
- 方式 3 输出波形及特点:根据计数初值奇偶输出不同占空比的方波。初值为偶数时,高、低电平宽度相等;初值为奇数时,高电平比低电平多一个时钟周期,可软、硬件启动,计数到 0 后自动重装初值持续输出方波。
某系统中有一片8253,其计数器0至控制口地址依次为40H-43H,请按如下要求编程:
8253的控制字:选择 ,读写, 工作, 计数
(1)通道0:方式3,CLK0=2MHz,要求在0UT0输出1KHz方波。
00 11 011 0 ==> 36H, 2M/1k=2000
MOV AL, 36H ;控制字
OUT 43H, AL ;写入控制口
MOV AX, 2000 ;计数初值
MOV AL, AL ;高8位
OUT 40H, AL ;写入di8位
MOV AL, AH ;低8位
OUT 40H, AL ;写入高8位
(2)通道l:方式2,CLK1=1MHz,要求OUT1输出1KHz脉冲波。
01 11 010 0 ===>74H,
MOV AL, 74H ;控制字
OUT 43H, AL ;写入控制口
MOV AX, 1000 ;计数初值
MOV AL, AL ;低8位
OUT 41H, AL ;写入8位
MOV AL, AH ;低8位
OUT 41H, AL ;写入8位
(3)通道2:方式4,CLK2=OUT1,计数值为1000,计数到0时输出一个控制脉冲。
10 11 100 0 ==> B8H
MOV AL, B8H ;控制字
OUT 43H, AL ;写入控制口
MOV AX, 1000 ;计数初值
MOV AL, AL ;8位
OUT 42H, AL ;写入8位
MOV AL, AH ;8位
OUT 42H, AL ;写入8位
某系统采用一片8253产生周期为2ms、个数为10的脉冲序列,已知有一个时钟源,频率为2MHz。要求:
(1)画出硬件接口电路图,并确定8253的端口地址。
(2)编写相应程序。
假设 80H~83H
2MHz==>0.5us ==>N= 4000
假设计数器0,读写11,工作方式2,2进制 ==>00 11 010 0
MOV AL, 34H ;控制字
OUT 83H, AL ;写入控制口
MOV AX, 4000 ;计数初值
MOV AL, AL ;di8位
OUT 82H, AL ;写入di8位
MOV AL, AH ;gao8位
OUT 81H, AL ;写入gao8位
画出8255工作于方式1输入的波形,并说明其工作过程。
- 方式 0(计数结束中断方式):软件启动计数,每设置一次初值只启动一次计数过程。写入控制字后 OUT 初态为低,计数过程中保持低电平,计数到 0 时 OUT 变为高电平,可用于产生中断请求。GATE 为 1 时正常计数,为 0 时计数暂停。
- 方式 1(可编程单稳方式):硬件(GATE 上升沿)启动,写入控制字后 OUT 初态为高,GATE 触发后 OUT 输出低电平脉冲,宽度由计数初值决定,可重复触发,计数初值下次有效。
- 方式 2(脉冲频率发生器方式):软、硬件均可启动,输出连续负脉冲,频率为输入时钟的 1/N,计数值减到 1 时 OUT 变低,减到 0 时恢复高并重新装入计数值。
- 方式 3(方波发生器方式):软、硬件启动,根据计数初值奇偶输出不同占空比方波,计数到 0 后自动重装初值继续计数。
- 方式 4(软件触发选通方式):软件启动(装入初值1个周期,且 GATE 为高时),计数到 0 时 OUT 输出一个 CLK 周期的低电平脉冲。
- 方式 5(硬件触发选通方式):硬件(GATE 上升沿)启动,计数到 0 时 OUT 输出一个 CLK 周期的负脉冲,可重复触发。
并行接口芯片8255A的A口-控制口的端口地址依次为60H-63H。编一段程序使从PC5输出一个负脉冲。另外,若脉冲宽度不够,应如何解决。
先选择方式,然后对c操作,0 00 0 1 0 0 0
这里是PC4的单独的控制字,0xxx{101} 0,
MOV AL, 00001000B ;方式选择控制字,PC5输出
OUT 63H, AL ;写入控制口
MOV AL, 00001010B ;对PC5置位
OUT 62H, AL ;使PC5输出高电平
NOP ;可插入适当延时
MOV AL, 00001001B ;对PC5复位
OUT 62H, AL ;使PC5输出低电平,形成负脉冲
- 若脉冲宽度不够的解决方法:可以在置位和复位 PC5 的指令之间插入更多的 NOP 指令或调用延时子程序,增加延时时间,从而增加负脉冲的宽度。
当串行通信的波特率是2400波特时,数据位时间周期是多少?
数据位时间周期 = 1 / 波特率 = 1 / 2400 s ≈ 0.417ms。
简述异步通信和同步通信的主要区别。
发送时:
异步:发送器为每个字符加上一个起始位,并按照规定加上奇偶校验位以及1个、1.5个或者2个停止位。然后在时钟TXC的作用下,由TXD脚逐位地串行发送出去。
同步:发送缓冲器在准备发送的数据前面先插入由初始化程序设定的一个或两个同步字符,在数据中插入奇偶校验位。然后在发送时钟TXC的作用下,将数据逐位地由TXD引脚发送出去。
接收时:
异步接收方式:在“允许接收”条件下,接收缓冲器监视RXD线。发现起始位后,开始采样并进行字符装配,装配一个后直接送到数据输入缓冲器,同时发出RXRDY有效信号。
同步接收方式:先搜索同步字符。匹配同步字符后,SYNDET引脚变为高电平
简述8251A初始化的一般步骤。
送入方式控制字==>检查是不是异步,
不是==>输出第一个同步字符,检查是不是但同步字符,不是就输出第二个同步字符
输出命令控制字,检查需要是否需要复位,不需要就传送数据,否则回到开头,
最后检查是不是完成,没有完成就回到上面等待继续送数据,否则回到上面发送命令控制字
串行异步通信字符格式中的停止位和空闲位有什么不同?
- 停止位:是每个字符传输结束时发送的高电平信号,用于表示一个字符的结束,其位数可以是 1 位、1.5 位或 2 位,是字符格式的固定组成部分。
- 空闲位:在没有数据传输时,通信线路上保持的高电平状态,它不属于任何一个字符的格式部分,只是表示线路处于空闲状态。
在串行异步通信中,为什么接收时时钟频率一般是波特率的16倍频?
接收端需要对接收数据进行采样来判断 数据位。使用 16 倍波特率的时钟,接收端可以在每位数据的中间位置进行多次采样(一般为 16 次采样中的第 7、8、9 次),这样能更准确地判断数据位的电平状态,有效减少因噪声或线路干扰导致的误判,提高数据接收的准确性 。
8251A可检测到几种接收数据错误,详细说明。
-接收数据位奇偶校验不对,则标志有奇偶错误,在状态寄存器中PE会置1;
-CPU还没在把上一个接收的数据取走,下一个数据已经到来,则产生溢出错误,在状态寄存器中OE会置1;
-当没在检测到停止位时,产生帧错误,状态寄存器中的FE会置1。
在8251A异步方式时,接收时钟RxC和发送时钟TxC都等于115200Hz,波特率因子为1,通信格式为115200、8、N、1,即波特率为115200、8个数据位、无奇偶校验位和一个停止位。计算每秒可以传送多少字节? 并画出传送字符‘B’的帧格式。
115200/10 = 11520字节/s
8255A:
8253A:
8251A
若要用8253A产生20ms周期的信号,做为8259A中断请求输入,其中8253A的时钟CLK频率为1MHz,问8253A计数器需要工作在哪两个工作方式之一?并计算出8253A的计数初值是多少?
方式2(脉冲频率发生器方式),方式3(方波发生器方式)
1MHz==>1/1*10^6/s
次数= CLK频率/目标频率 ===>20000
8251A工作于异步通信方式,通信格式为9600、8、N、1,即波特率为9600、8个数据位、无奇偶校验位和一个停止位。计算每秒可以传送多少字节? 并画出传送字符‘A’的帧格式。要求写出计算过程。
10=8+1+1+0
9600/10=960字节/s
‘A’=41H=01000001b
8251异步通信工作时,接收时钟Rxc和发送时钟Txc都等于19200Hz,波特率因子为16,异步通信格式为:一个起始位、8个数据位、无奇偶位、一个停止位。计算每秒钟最多能传送多少个字节?传送一个字节最少大约需要多少毫秒?
19200/10*16===>30720
一个字节需要 10位 ==?625ms
注意脉冲从右往左