**
1. A/D0809芯片特点
**
ADCO809是美国国家半导体公司生产的CMOS工艺8通道,8位逐次逼近式A/D模数转换器。其内部有一个8通道多路开关,可根据地址码选通其中一路输入信号进行AD转换。该芯片主要具有以下特性:
☆8路输入通道,8位AD转换器,即分辨率为8位;
☆具有转换启动停止控制端;
☆转换时间为100us(时钟为640KHz时),130us(时钟为500KHz时)﹔
☆单个+5V电源供电,低功耗,约15mV;
☆模拟输入电压范围O~+5V,不需零点和满刻度校准;
☆工作温度范围为-40~~+85摄氏度;
2.A/D0809引脚
ADCO809芯片有28个引脚,采用双列直插式封装。如下图所示:
3.时序图
4.实验仿真
Tips:因为Proteus里面无法使用0809,所以用0808代替0809,两者的功能差不多
首先是proteus的仿真图:
其中的蓝色的时钟在这里找:
因为0809时钟周期的典型值为100us,所以我的频率设置为10kHz
其中仿真的器件表如下:
器件 | 名称 |
---|---|
ADC0808数模转换芯片 | ADC0808 |
滑动变阻器 | POT-HG |
共阳极数码管(Common anode) | 7SEG-MPX4-CA |
单片机 | 80C51 |
汇编代码如下:
ORG 1000H
DB 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90
AD0809_ADDA BIT P1.4
AD0809_ADDB BIT P1.5
AD0809_ADDC BIT P1.6
AD0809_CLK BIT P1.3
AD0809_STAT BIT P1.2
AD0809_EOC BIT P1.1
AD0809_OE BIT P1.0
AD0809_DA EQU 71H
ORG 0000H
SJMP MAIN
ORG 0030H
MAINLOOP:
ACALL MAIN
SJMP MAINLOOP
MAIN:
;选择0通道输出
CLR AD0809_ADDA
CLR AD0809_ADDB
CLR AD0809_ADDC
;产生一个下降沿启动AD转换
CLR AD0809_STAT
SETB AD0809_STAT
CLR AD0809_STAT
LOOP1:
;等待转换完成
JNB AD0809_EOC,LOOP1
;允许输出
SETB AD0809_OE
;P3的输出到A
MOV A,P3
;下面是计算16进制转换为10进制的数,从0-255映射到0-5的比较精确的做法,
;这个做法相当于0-25500映射到0-500,然后显示的时候在百位后面加一个小数点就好
;而最后面一种做法是0-255映射到0-5,这种计算方法的累计误差到最后映射时会增大到0.1
;下面的注释都是以A=ff计算出来的结果,可以直接将A赋值为ffH,然后在调试窗口观察得到
;计算个位
MOV B,#33H ;B=51,A=254
DIV AB
MOV 30H,A ;A=4,B=50,(30h) = 4
;计算小数点后一位
MOV A,B ;A= B=50
MOV B,#0AH ;A=50,B= 10
MUL AB ;A=244,B=1=256(因为计算后B保存高位,111110100=100000000+11110100=256+244)
ADD A,B ;A=245,加B是因为b的值除以51后余数为1,要加入低位中进行计算,否则会漏掉一些数
MOV R0,A ;保存低位的值,因为后面要用A
MOV A,#05H ;A=5,B=1将A赋值为5,是因为B是高位,B=1实际是B=100000000=256除以51后为五
MUL AB ;A=5,B=0
MOV R1,A ;这个5的值是小数点后的一部分,还可能因为最开始A输入的值的不同而等于零,A的实际的数字是以A=0xFE计算所得
MOV A,R0 ;A=245,B=0;
MOV B,#33H ;A=245,B=51
DIV AB ;A=4,B=41
ADD A,R1 ;R1=9
MOV 31H,A ;(31h)=9
;计算小数点后两位,步骤跟上面一样,可以从B保存了的值计算出第二位小数
MOV A,#0AH ;A=10,B=41
MUL AB ;A=9A=154,B=1=256
ADD A,B ;A=9B=155,B=1=256
MOV R0,A ;A=155,R0=155
MOV A,#05H ;A=5,B=1
MUL AB ;A=5,B=0
MOV R1,A ;R1=A=5,B=0
MOV A,R0 ;A=155,B=0
MOV B,#33H ;A=155,B=51=0X33
DIV AB ;A=3,B=2
ADD A,R1 ;R1=8
MOV 32H,A ;(32H)=8
// 以下是第二种计算方法,在做乘法的时候原本以为高位不会有值
//;但只要乘法后的数字大于255就会对高位进行赋值但本题目高位最多为1或者为零
// MOV B,#0x33
// DIV AB
// MOV 30H,A
// MOV A,B
// MOV B,#0AH
// MUL AB
// MOV B,#0x33
// DIV AB
// MOV 31H,A
// MOV A,B
// MOV B,#0AH
// MUL AB
// MOV B,#33
// DIV AB
// MOV 32H,A
;以下是第一种转换数值的方法,发现误差太大
;MOV R0,#71H
; MOV @R0,A
;将16进制数转换到10进制数并且保存到30H,31H,32H
; MOV B,#64H
; DIV AB
; MOV 30H,A
; MOV A,B
; MOV B,#0AH
; ;DIV AB
; MOV 31H,A
; MOV 32H,B
;原来的数字,
; MOV R0,#30H
; MOV A,@R0
; MOV 33H,A
; MOV R0,#31H
;MOV A,@R0
; MOV 34H,A
; MOV R0,#32H
; MOV A,@R0
; MOV 35H,A
;转换函数.乘二
; MOV R0,#32H
; MOV A,@R0
; RL A
; MOV B,#0AH
; DIV AB
; MOV 32H,B
; MOV R0,#31H
; MOV B,A ;对A里面的内容进行保存
; MOV A,@R0 ;更新A
; RL A ;乘二
; ADD A,B ;加一
; MOV B,#0AH
; DIV AB
; MOV 31H,B
; MOV R0,#30H
; MOV B,A ;对A里面的内容进行保存
; MOV A,@R0 ;更新A
; RL A ;乘二
; ADD A,B ;加一
; MOV 30H,A
;显示函数---------------------------------------------------------
;段选:P1.0->P1.7
;位选:P2.0->P2.3
DISPLAY1:
MOV DPTR, #1000H ;码表起始地址
MOV R0, #30H ;显存起始地址
MOV R1, #02H ;位选码 P3.7->0 0 0 0 0 0 0 1->P3.0
;四位循环----------------------------------------------------------
DISPLAYLOOP:
MOV P0, #0FFH ;消影
;查表操作
MOV A, @R0 ;间接寻址,获取显存
MOVC A, @A+DPTR ;将显存中的数字映射到段码
CJNE R1,#02H,LOOP2
MOV R3,#80H
ADD A,R3
LOOP2:
MOV P0, A ;段选赋值
MOV P2, R1 ;位选赋值
ACALL DELAY ;延时
INC R0 ;显存地址自加,切换到下一位数字的显存
;位选左移,切换到下一位显示
MOV A, R1
RL A
MOV R1, A
CJNE R1, #10H,DISPLAYLOOP ;根据位选码,判断是否完成四位切换
SJMP MAIN
RET
;延时函数----------------------------------------------------------
DELAY:
MOV R7, #2
DELAYLOOP1:
MOV R6, #2
DELAYLOOP2:
MOV R5, #10
DELAYLOOP3:
NOP
DJNZ R5, DELAYLOOP3
DJNZ R6, DELAYLOOP2
DJNZ R7, DELAYLOOP1
RET
END
上面的代码废话有点多,不喜欢的可以直接看这个:
ORG 1000H
DB 0xC0, 0xF9, 0xA4, 0xB0, 0x99, 0x92, 0x82, 0xF8, 0x80, 0x90
AD0809_ADDA BIT P1.4
AD0809_ADDB BIT P1.5
AD0809_ADDC BIT P1.6
AD0809_CLK BIT P1.3
AD0809_STAT BIT P1.2
AD0809_EOC BIT P1.1
AD0809_OE BIT P1.0
AD0809_DA EQU 71H
ORG 0000H
SJMP MAIN
ORG 0030H
MAINLOOP:
ACALL MAIN
SJMP MAINLOOP
MAIN:
;选择0通道输出
CLR AD0809_ADDA
CLR AD0809_ADDB
CLR AD0809_ADDC
;产生一个下降沿启动AD转换
CLR AD0809_STAT
SETB AD0809_STAT
CLR AD0809_STAT
LOOP1:
;等待转换完成
JNB AD0809_EOC,LOOP1
;允许输出
SETB AD0809_OE
;P3的输出到A
MOV A,P3
;下面是计算16进制转换为10进制的数,从0-255映射到0-5的比较精确的做法,
;这个做法相当于0-25500映射到0-500,然后显示的时候在百位后面加一个小数点就好
MOV B,#33H
DIV AB
MOV 30H,A
MOV A,B
MOV B,#0AH
MUL AB
ADD A,B
MOV R0,A
MOV A,#05H
MUL AB
MOV R1,A
MOV A,R0
MOV B,#33H
DIV AB
ADD A,R1
MOV 31H,A
MOV A,#0AH
MUL AB
ADD A,B
MOV R0,A
MOV A,#05H
MUL AB
MOV R1,A
MOV A,R0
MOV B,#33H
DIV AB
ADD A,R1
MOV 32H,A
;显示函数---------------------------------------------------------
;段选:P1.0->P1.7
;位选:P2.0->P2.3
DISPLAY1:
MOV DPTR, #1000H ;码表起始地址
MOV R0, #30H ;显存起始地址
MOV R1, #02H ;位选码 P3.7->0 0 0 0 0 0 0 1->P3.0
;四位循环----------------------------------------------------------
DISPLAYLOOP:
MOV P0, #0FFH ;消影
;查表操作
MOV A, @R0 ;间接寻址,获取显存
MOVC A, @A+DPTR ;将显存中的数字映射到段码
CJNE R1,#02H,LOOP2
MOV R3,#80H
ADD A,R3
LOOP2:
MOV P0, A ;段选赋值
MOV P2, R1 ;位选赋值
ACALL DELAY ;延时
INC R0 ;显存地址自加,切换到下一位数字的显存
;位选左移,切换到下一位显示
MOV A, R1
RL A
MOV R1, A
CJNE R1, #10H,DISPLAYLOOP ;根据位选码,判断是否完成四位切换
SJMP MAIN
RET
;延时函数----------------------------------------------------------
DELAY:
MOV R7, #2
DELAYLOOP1:
MOV R6, #2
DELAYLOOP2:
MOV R5, #10
DELAYLOOP3:
NOP
DJNZ R5, DELAYLOOP3
DJNZ R6, DELAYLOOP2
DJNZ R7, DELAYLOOP1
RET
END