<<**汇编与接口技术>>
基于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.386ad_cs equ 200hi8254_0 EQU 210Hi8254_1 equ 211hi8254kz equ 213hled_cs equ 220hdata segmentledcode db 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,67h,77h,7ch,39h,5eh,79h,71h ;0-Fbit_num db 01h,02h,04h,08h,10h,20h,40h,80h ;led 位置选择码i8255_a equ 230hi8255_b equ 231hi8255kz equ 233hsum db ?point dw ?,? ;存放位置选择码指针data endscode segmentassume cs:code,ds:datastart: mov ax,datamov ds,axmov dx,i8254kzmov al,36h ;计数器0方式3,BCD码计数out dx,almov ax,400 ;写入循环计数初值1000mov dx,i8254_0 ;计数器0设置初值out dx,al ;先写低字节mov al,ahout dx,al ;后写高字节rpt: mov dx,ad_cs ;ADC启动转换地址out dx,almov dx,ad_cs ;获取ADC EOC状态地址add dx,2l1: in al,dxtest al,01h ;测试EOC=1?jz l1mov dx,ad_cs ;读数据地址inc dxin al,dxmov [sum],al ;读取数据量;and sum,0fh; 数码管示数call dispcmp sum,7fhjb erromov dx,i8255kzmov al,04h ;置PC2为1,PC2接扬声器out dx,al;88点阵显示心形call heart_dispjmp rpterro: ;此处为电压小于2.5Vmov dx,i8255kzmov al,05h ;置PC2为0,PC2接扬声器out dx,al;88点阵显示囧字call error_dispjmp rpterror_disp procpush axpush bxpush cxpush dxmov dx,i8255kz ;8255 控制口地址mov al,80hout dx,alkL1:stc ;置 CF=1,准备形成位置码mov al,0lea di,bit_num ;初始位选码指针mov point,dikkk:rcl al,1 ;设置 V0=1mov bl,al ;保护mov dx,i8255_a ;8255 端口 A 地址out dx,al ;选中一行mov si,point ;取位置表开始地址指针mov cx,8 ;列循环次数krow1:mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址loop krow1lea di,bit_nummov point,di ;从位置表首地址开始mov al,blkrow2:rcl al,1 ;设置 V0=2mov bl,al ;保护mov dx,i8255_a ;8255 端口 A 地址out dx,al ;选中一行mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址inc si;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=3mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址inc siinc si;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址inc si;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址lea di,bit_nummov point,di ;从位置表首地址开始mov al,blkrow3:rcl al,1 ;设置 V0=2mov bl,al ;保护mov dx,i8255_a ;8255 端口 A 地址out dx,al ;选中一行mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=3mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址inc siinc siinc siinc si;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址lea di,bit_nummov point,di ;从位置表首地址开始mov al,blkrow4:rcl al,1 ;设置 V0=2mov bl,al ;保护mov dx,i8255_a ;8255 端口 A 地址out dx,al ;选中一行mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址inc si;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=3mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址mov al,[si] ;设置 Hx=3mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址mov al,[si] ;设置 Hx=3mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址inc si;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址lea di,bit_nummov point,di ;从位置表首地址开始mov al,blkrow5:rcl al,1 ;设置 V0=2mov bl,al ;保护mov dx,i8255_a ;8255 端口 A 地址out dx,al ;选中一行mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址inc si;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=3mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址inc siinc si;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址inc si;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址lea di,bit_nummov point,di ;从位置表首地址开始mov al,blkrow6:rcl al,1 ;设置 V0=2mov bl,al ;保护mov dx,i8255_a ;8255 端口 A 地址out dx,al ;选中一行mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址inc si;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=3mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址mov al,[si] ;设置 Hx=3mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc simov al,[si] ;设置 Hx=3mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址inc si;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址lea di,bit_nummov point,di ;从位置表首地址开始mov al,blkrow7:rcl al,1 ;设置 V0=2mov bl,al ;保护mov dx,i8255_a ;8255 端口 A 地址out dx,al ;选中一行mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址inc siinc si ;修改地址inc siinc siinc si ;修改地址inc si;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址lea di,bit_nummov point,di ;从位置表首地址开始mov al,blkrow8:rcl al,1 ;设置 V0=1mov bl,al ;保护mov dx,i8255_a ;8255 端口 A 地址out dx,al ;选中一行mov si,point ;取位置表开始地址指针mov cx,8 ;列循环次数krow88:mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址loop krow88lea di,bit_nummov point,di ;从位置表首地址开始mov al,blpop dxpop cxpop bxpop axreterror_disp endpheart_disp procpush axpush bxpush cxpush dxmov dx,i8255kz ;8255 控制口地址mov al,80hout dx,alstc ;置 CF=1,准备形成位置码mov al,0lea di,bit_num ;初始位选码指针mov point,dirow2: rcl al,1rcl al,1 ;设置 V0=1mov bl,al ;保护mov dx,i8255_a ;8255 端口 A 地址out dx,al ;选中一行mov si,point ;取位置表开始地址指针inc simov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=3mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址inc siinc si;mov si,point ;取位置表开始地址指针mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示inc silea di,bit_nummov point,di ;从位置表首地址开始mov al,blrow3:rcl al,1 ;设置 V0=1mov bl,al ;保护mov dx,i8255_a ;8255 端口 A 地址out dx,al ;选中一行mov si,point ;取位置表开始地址指针mov cx,8 ;列循环次数row33:mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址loop row33lea di,bit_nummov point,di ;从位置表首地址开始mov al,blrow4:rcl al,1 ;设置 V0=1mov bl,al ;保护mov dx,i8255_a ;8255 端口 A 地址out dx,al ;选中一行mov si,point ;取位置表开始地址指针mov cx,8 ;列循环次数row44:mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址loop row44lea di,bit_nummov point,di ;从位置表首地址开始mov al,blrow5:rcl al,1 ;设置 V0=1mov bl,al ;保护mov dx,i8255_a ;8255 端口 A 地址out dx,al ;选中一行mov si,point ;取位置表开始地址指针mov cx,5 ;列循环次数inc sirow55:mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,alinc si ;选中一列并显示loop row55lea di,bit_nummov point,di ;从位置表首地址开始mov al,blrow6:rcl al,1 ;设置 V0=1mov bl,al ;保护mov dx,i8255_a ;8255 端口 A 地址out dx,al ;选中一行mov si,point ;取位置表开始地址指针mov cx,3 ;列循环次数inc siinc sirow66:mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址loop row66lea di,bit_nummov point,di ;从位置表首地址开始mov al,blrow7:rcl al,1 ;设置 V0=1mov bl,al ;保护mov dx,i8255_a ;8255 端口 A 地址out dx,al ;选中一行mov si,point ;取位置表开始地址指针mov cx,1 ;列循环次数inc siinc siinc sirow77:mov al,[si] ;设置 Hx=1mov dx,i8255_b ;8255 端口 B 地址out dx,al ;选中一列并显示;call delayinc si ;修改地址loop row77lea di,bit_nummov point,di ;从位置表首地址开始mov al,blpop dxpop cxpop bxpop axretheart_disp endpdisp procmov si,offset ledcodemov bx,simov ch,almov cl,4ror al,cl ;截取AL高四位并转换。and al,0fhmov ah,0add bx,axmov al,[bx] ;获取LED显示编码mov dx,led_csout dx,almov al,02hinc dxnopout dx,al ;显示call delaymov al,chand al,0fh ;截取低四位,并转换mov ah,0add si,axmov al,[si]mov dx,led_csout dx,almov al,01hinc dxout dx,al ;显示call delayretdisp endpdelay procpush cxmov cx,50hx1: loop x1pop cxretdelay endpcode endsend start

