注意:Proteus中没有ADC0809因此要选择ADC0808
DATAS SEGMENT
;此处输入数据段代码
IOYO equ 0C400h;对应的端口地址
a8255 equ IOYO+00H*4;A端口
b8255 equ IOYO+01H*4;B端口
c8255 equ IOYO+02H*4;C端口
m8255 equ IOYO+03H*4;8255控制字
adc0808 equ 0C420h;对应的ADC0808的端口
table db 0c0h,0f9h,0a4h,0b0h,99h,92h,82h,0f8h
db 80h,90h,88h,83h,0c6h,0a1h,86h,8eh
result db 5 dup(?)
buf db 5 dup(?)
DATAS ENDS
STACKS SEGMENT
;此处输入堆栈段代码
db 200 dup(0)
STACKS ENDS
CODES SEGMENT
ASSUME CS:CODES,DS:DATAS,SS:STACKS
START:
MOV AX,DATAS
MOV DS,AX
;准备工作写控制字
lea di,result;用来保存计算后转换的结果
mov dx,m8255
mov al,99h;1001 1001
out dx,al
mov dx,b8255
mov al,0fh
out dx,al
;相当与单片机的while(1)部分
;这里是0808测量部分部分,这里测量得到al的结果为1010 1000
LOOP1:
mov dx,adc0808
mov al,0
out dx,al
mov dx,c8255
EOC:
in al,dx
test al,01h;00表示还在转换
jz eoc
jmp finish
Finish:
mov dx,a8255
in al,dx
;计算转换结果
mov ah,00h;将ah中的内容清零
mov bx,01f4h;500的16进制
mul bx;将al和500相乘,高位放到dx中,低位存在ax中
mov bx,0ffh
div bx;除以255得到的结果,ax中结果为0000 0001 0100 1001
mov cx,ax;cx中备份数据
;显示结果
;将数据转换为十进制
mov bx,10
mov si,2;三位
toDec:
mov dx,0
div bx;(dx,ax)/bx中的数据除以bx
mov [buf+si],dl;余数为该位上的值,第一次循环为个位,第二次为十位
dec si
cmp ax,0;商为0表示算法结束
ja toDec
;计算个位
inc si
mov al,[buf+si]
inc si
mov bx,offset table
xlat
and al,7fh;加上小数点
mov [di],al
;计算第一个小数点位
mov al,[buf+si]
inc si
xlat table
mov [di+1],al
;计算第二个小数点位
mov al,[buf+si]
xlat table
mov [di+2],al
;完成数码管动态扫描刷新
mov dx,b8255;8255芯片
or dx,0800h;;0000 1000 0000 0000
mov al,[di+2]
out dx,al
call delay_2ms
mov dx,b8255
or dx,1000h;0001 0000 0000 0000
mov al,[di+1]
out dx,al
call delay_2ms
mov dx,b8255
or dx,1800h;0001 1000 0000 0000
mov al,[di]
out dx,al
call delay_2ms
jmp LOOP1;循环
MOV AH,4CH
INT 21H
delay_2ms proc near
push bx
mov bx,1ffh
LP2:
pushf
popf
dec bx
jnz lp2
pop bx
ret
delay_2ms endp
CODES ENDS
END START
结果是可以实时显示电压值。
A/D转化部分,显示结果需要经过一些计算,首先要计算分辨率,基准源为5V,分辨率为5.0/255=0.019,然后再和ADC0808输出的结果相乘得到的就是最终的结果。这个实验的显示部分我改进了几次,因为要显示多位数值,因此要对数码管进行动态扫描,可是不知道如何使用中断,因此扫描就是用的计时的方法,每当检测一次ADC0808转化的结果,就扫描数码管显示,可是因为用了一个1s的延时程序,因此中间会有一段数码管完全没有显示,所有就改进为检测EOC位,因为EOC位转化时为低电平,转化完成后会变为高电平,因此直接检测EOC位是否变为高电平延时很短,人眼也观察不出来效果就是数码管可以持续显示,还有一个问题是ADC0808在运行程序后只能检测一次,之后改变电压值,不会输出检测的结果。后来发现是使能端start和ALE的问题,修改之后就可以正常显示了,这里给出的是修改之后的程序。
时钟信号设置:
部分使能信号: