<<**汇编与接口技术>>
基于A/D采集的交互式报警系统**
一、实验目的
(1)考察和培养综合运用学到的接口知识自主设计和完成实验的能力。
(2)培养团队合作的能力。
二、实验内容
基于A/D采集的交互式报警系统
当继电器电压值小于2.5V时,代表着错误的状态,此时应该发出报警信号,为了能够有效对外界进行提醒,此时8X8点阵显示一个“囧”脸形状,扬声器发出报警信号。当电压大于2.5V时,代表着正确的状态,此时不用发出报警信号,8X8点阵显示一个“心”的形状,扬声器不发声。
所需器件: 8X8点阵,扬声器,8255并行接口,8254定时器,ADC0809,电位器,继电器数码管显示所采集的数字量的值。
三、实验设计
实验简述: 我们需要通过ADC0809从电位器读取电平进行AD转换,将模拟信号转化为数字信号,然后读取数字信号并将其显示到LED数码管上,同时,判断该数值的大小是否小于7F也就是电平所对应2.5V分界。如果该读数大于7F,我们就在8X8点阵上显示“心”型,如果小于7F,则在8X8点阵上显示为“囧”,并且使用8054使扬声器发出警告。
实验流程图:
实验连线图:
8x8点阵显示原理:
简述: TPC386实验箱中8x8点阵由64个发光二极管组成,64个发光二极管组成8x8矩阵。某行线给出高电平,某列线给出低电平则行线与列线交叉的发光二极管就会被点亮。8x8点阵的点亮是采用扫描式的,8x8点阵一次只能点亮一个耳光二极管。但是两个发光二极管间的点亮间隔很小,人眼无法分辨,所以可以造成视觉差显示某个特定的图案。例如本实验中的“心”形和“囧”形。
连线: 我们将8x8点阵与8255并行接口进行配合使用,该实验中,我们使用PA0-7作为行输入而PB0-7作为列输入以此来操作。8255的PA0-7接8x8点阵的H0-7,PB0-7接V0-7。连线图如下:
代码实现:** 为了程序的简洁和美观,我们将显示“心”形和“囧”形的功能分别写为两个子函数,在主程序中调用。所以通过模块化思想,我们分别设计两个子程序。error_disp和heart_disp。
我们对显示图形的每一行每一列进行程序编写,所以代码很冗杂臃肿,光是显示一个“囧”字就写了超过300行代码。而“心”字比较连续也写了200多行。
LED显示原理:
简述: 在该实验中我们需要将读取到的数值显示到数码管上,跟以往在数码管上显示一位数字不同,这一次需要显示两位16进制数,也就是除了0-9还有A-F。我们的数码管并不能同时显示两位数,所以我们可以用与8x8点阵类似的思想,造成视觉效果,以为同时显示了两位数字。
连线: 直接将220端口与LED数码管相连即可。
代码实现: 我们也将数码管示数写入一个子程序中,disp。采用位屏蔽技术提取高位数字和低位数字分别显示。
扬声器发声原理:
原理: 我们使用8254定时器和8255 PC2口配合与门使用,我们通过配置8254控制扬声器发声的频率,使用PC2 控制扬声器发声。如果PC2置1,则扬声器发声,置0则不发声。
连线:
代码实现: 首先对8254进行初始化。如果读取到的数值小于7F,则置PC2为1,否则置为0。
ADC0809数模转换:
原理: ADC启动地址转换,通过读取EOC状态判断是否转换完成,然后进行读数操作。
连线:
代码实现:
四、实验结果
code
.Model small
.386
ad_cs equ 200h
i8254_0 EQU 210H
i8254_1 equ 211h
i8254kz equ 213h
led_cs equ 220h
data segment
ledcode db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,67h,77h,7ch,39h,5eh,79h,71h ;0-F
bit_num db 01h,02h,04h,08h,10h,20h,40h,80h ;led 位置选择码
i8255_a equ 230h
i8255_b equ 231h
i8255kz equ 233h
sum db ?
point dw ?,? ;存放位置选择码指针
data ends
code segment
assume cs:code,ds:data
start: mov ax,data
mov ds,ax
mov dx,i8254kz
mov al,36h ;计数器0方式3,BCD码计数
out dx,al
mov ax,400 ;写入循环计数初值1000
mov dx,i8254_0 ;计数器0设置初值
out dx,al ;先写低字节
mov al,ah
out dx,al ;后写高字节
rpt: mov dx,ad_cs ;ADC启动转换地址
out dx,al
mov dx,ad_cs ;获取ADC EOC状态地址
add dx,2
l1: in al,dx
test al,01h ;测试EOC=1?
jz l1
mov dx,ad_cs ;读数据地址
inc dx
in al,dx
mov [sum],al ;读取数据量
;and sum,0fh
; 数码管示数
call disp
cmp sum,7fh
jb erro
mov dx,i8255kz
mov al,04h ;置PC2为1,PC2接扬声器
out dx,al
;88点阵显示心形
call heart_disp
jmp rpt
erro: ;此处为电压小于2.5V
mov dx,i8255kz
mov al,05h ;置PC2为0,PC2接扬声器
out dx,al
;88点阵显示囧字
call error_disp
jmp rpt
error_disp proc
push ax
push bx
push cx
push dx
mov dx,i8255kz ;8255 控制口地址
mov al,80h
out dx,al
kL1:
stc ;置 CF=1,准备形成位置码
mov al,0
lea di,bit_num ;初始位选码指针
mov point,di
kkk:
rcl al,1 ;设置 V0=1
mov bl,al ;保护
mov dx,i8255_a ;8255 端口 A 地址
out dx,al ;选中一行
mov si,point ;取位置表开始地址指针
mov cx,8 ;列循环次数
krow1:
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
loop krow1
lea di,bit_num
mov point,di ;从位置表首地址开始
mov al,bl
krow2:
rcl al,1 ;设置 V0=2
mov bl,al ;保护
mov dx,i8255_a ;8255 端口 A 地址
out dx,al ;选中一行
mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
inc si
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=3
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
inc si
inc si
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
inc si
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
lea di,bit_num
mov point,di ;从位置表首地址开始
mov al,bl
krow3:
rcl al,1 ;设置 V0=2
mov bl,al ;保护
mov dx,i8255_a ;8255 端口 A 地址
out dx,al ;选中一行
mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=3
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
inc si
inc si
inc si
inc si
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
lea di,bit_num
mov point,di ;从位置表首地址开始
mov al,bl
krow4:
rcl al,1 ;设置 V0=2
mov bl,al ;保护
mov dx,i8255_a ;8255 端口 A 地址
out dx,al ;选中一行
mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
inc si
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=3
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
mov al,[si] ;设置 Hx=3
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
mov al,[si] ;设置 Hx=3
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
inc si
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
lea di,bit_num
mov point,di ;从位置表首地址开始
mov al,bl
krow5:
rcl al,1 ;设置 V0=2
mov bl,al ;保护
mov dx,i8255_a ;8255 端口 A 地址
out dx,al ;选中一行
mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
inc si
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=3
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
inc si
inc si
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
inc si
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
lea di,bit_num
mov point,di ;从位置表首地址开始
mov al,bl
krow6:
rcl al,1 ;设置 V0=2
mov bl,al ;保护
mov dx,i8255_a ;8255 端口 A 地址
out dx,al ;选中一行
mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
inc si
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=3
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
mov al,[si] ;设置 Hx=3
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si
mov al,[si] ;设置 Hx=3
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
inc si
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
lea di,bit_num
mov point,di ;从位置表首地址开始
mov al,bl
krow7:
rcl al,1 ;设置 V0=2
mov bl,al ;保护
mov dx,i8255_a ;8255 端口 A 地址
out dx,al ;选中一行
mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
inc si
inc si ;修改地址
inc si
inc si
inc si ;修改地址
inc si
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
lea di,bit_num
mov point,di ;从位置表首地址开始
mov al,bl
krow8:
rcl al,1 ;设置 V0=1
mov bl,al ;保护
mov dx,i8255_a ;8255 端口 A 地址
out dx,al ;选中一行
mov si,point ;取位置表开始地址指针
mov cx,8 ;列循环次数
krow88:
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
loop krow88
lea di,bit_num
mov point,di ;从位置表首地址开始
mov al,bl
pop dx
pop cx
pop bx
pop ax
ret
error_disp endp
heart_disp proc
push ax
push bx
push cx
push dx
mov dx,i8255kz ;8255 控制口地址
mov al,80h
out dx,al
stc ;置 CF=1,准备形成位置码
mov al,0
lea di,bit_num ;初始位选码指针
mov point,di
row2: rcl al,1
rcl al,1 ;设置 V0=1
mov bl,al ;保护
mov dx,i8255_a ;8255 端口 A 地址
out dx,al ;选中一行
mov si,point ;取位置表开始地址指针
inc si
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=3
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
inc si
inc si
;mov si,point ;取位置表开始地址指针
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
inc si
lea di,bit_num
mov point,di ;从位置表首地址开始
mov al,bl
row3:
rcl al,1 ;设置 V0=1
mov bl,al ;保护
mov dx,i8255_a ;8255 端口 A 地址
out dx,al ;选中一行
mov si,point ;取位置表开始地址指针
mov cx,8 ;列循环次数
row33:
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
loop row33
lea di,bit_num
mov point,di ;从位置表首地址开始
mov al,bl
row4:
rcl al,1 ;设置 V0=1
mov bl,al ;保护
mov dx,i8255_a ;8255 端口 A 地址
out dx,al ;选中一行
mov si,point ;取位置表开始地址指针
mov cx,8 ;列循环次数
row44:
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
loop row44
lea di,bit_num
mov point,di ;从位置表首地址开始
mov al,bl
row5:
rcl al,1 ;设置 V0=1
mov bl,al ;保护
mov dx,i8255_a ;8255 端口 A 地址
out dx,al ;选中一行
mov si,point ;取位置表开始地址指针
mov cx,5 ;列循环次数
inc si
row55:
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al
inc si ;选中一列并显示
loop row55
lea di,bit_num
mov point,di ;从位置表首地址开始
mov al,bl
row6:
rcl al,1 ;设置 V0=1
mov bl,al ;保护
mov dx,i8255_a ;8255 端口 A 地址
out dx,al ;选中一行
mov si,point ;取位置表开始地址指针
mov cx,3 ;列循环次数
inc si
inc si
row66:
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
loop row66
lea di,bit_num
mov point,di ;从位置表首地址开始
mov al,bl
row7:
rcl al,1 ;设置 V0=1
mov bl,al ;保护
mov dx,i8255_a ;8255 端口 A 地址
out dx,al ;选中一行
mov si,point ;取位置表开始地址指针
mov cx,1 ;列循环次数
inc si
inc si
inc si
row77:
mov al,[si] ;设置 Hx=1
mov dx,i8255_b ;8255 端口 B 地址
out dx,al ;选中一列并显示
;call delay
inc si ;修改地址
loop row77
lea di,bit_num
mov point,di ;从位置表首地址开始
mov al,bl
pop dx
pop cx
pop bx
pop ax
ret
heart_disp endp
disp proc
mov si,offset ledcode
mov bx,si
mov ch,al
mov cl,4
ror al,cl ;截取AL高四位并转换。
and al,0fh
mov ah,0
add bx,ax
mov al,[bx] ;获取LED显示编码
mov dx,led_cs
out dx,al
mov al,02h
inc dx
nop
out dx,al ;显示
call delay
mov al,ch
and al,0fh ;截取低四位,并转换
mov ah,0
add si,ax
mov al,[si]
mov dx,led_cs
out dx,al
mov al,01h
inc dx
out dx,al ;显示
call delay
ret
disp endp
delay proc
push cx
mov cx,50h
x1: loop x1
pop cx
ret
delay endp
code ends
end start