————————————————————————————————————————————
ADC0809
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
工作原理:
通道 |
C |
B |
A |
IN0 |
0 |
0 |
0 |
IN1 |
0 |
0 |
1 |
IN2 |
0 |
1 |
0 |
IN3 |
0 |
1 |
1 |
IN4 |
1 |
0 |
0 |
IN5 |
1 |
0 |
1 |
IN6 |
1 |
1 |
0 |
IN7 |
1 |
1 |
1 |
p.s.
其他引脚:
IN0~IN7:8路模拟量输入引脚
CLK:时钟信号输入端
V_(REF(+)):参考电压正端
V_(REF(-)):参考电压负端
————————————————————————————————————————————
数字电压表实验
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
实现效果:
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
实现思路:
-
A/D转换
- 初始化时启动A/D转换,转换结束后OE自动置位
- 检查OE状态,为高电平时读取数据口数据并转换成对应的电压值
- 显示结束后启动下一次A/D转换
-
数码管显示
- 读入数据并转换成电压值后,通过数码管显示,百位数值后显示小数点
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
连接说明:
ADC0808 |
OUT1-OUT8 |
89C51 |
P0.0-0.7 |
转换后数据输出到单片机 |
|
START |
|
P3.0 |
|
|
EOC |
|
P3.1 |
|
|
OE |
|
P3.2 |
|
|
IN0 |
POT-HG |
+ |
输入模拟信号 |
|
ADDA/ADDB/ADDC/VREF(-) |
GND |
|
0 0 0 选择通路IN0 |
|
ALE/VREF(+) |
POWER |
|
将地址存入地址锁存器中 |
数码管 |
1/2/3/4/5/6/7 |
89C51 |
P2 |
控制数码管显示位数 |
|
A/B/C/D/E/F/G/DP |
|
P1 |
控制显示段码 |
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
实现代码:
1 #include <reg52.h>
2 typedef unsigned char uchar;
3 typedef unsigned int uint;
4 typedef unsigned long ulong;
5 uchar code table[] =
6 {
7 0xfc, 0x60, 0xda, 0xf2, 0x66, 0xb6, 0xbe, 0xe0, 0xfe, 0xf6, 0xee, 0x3e, 0x9c, 0x7a, 0x9e, 0x8e
8 };
9 sbit start = P3 ^ 0; //控制start引脚
10 sbit eoc = P3 ^ 1; //查询eoc引脚情况
11 sbit oe = P3 ^ 2; //输出允许控制端
12 sbit dot = P1 ^ 0; //数码管小数点
13 void Delay(uint m)
14 {
15 while(m--);
16 }
17 void main()
18 {
19 ulong temp, temp_data;
20 // uint temp;
21 start = 0;
22 oe = 0; //oe为高阻状态
23 start = 1; //start下降沿开始转换
24 start = 0;
25 while(1)
26 {
27 if (eoc == 1) //当eoc为1时转换结束
28 {
29 /*读入状态*/
30 oe = 1; //打开oe,数据读入引脚
31 temp = P0;
32 /*
33 读入的数值转换成模拟电压对应的电压值,由于ADC0809将0-5V平分为255份,每一份为5/255v,电压=1.0v时,temp=1.0*(5/255),为了方便显示小数,则扩大一百倍,得到公式temp=temp*1.0/255*500
34 但是在此处存在个问题,temp转换成为flout类型后运算量过大,影响后数码管显示速度,在一定范围内数码管显示错误
35 temp = temp * 1.0 / 255 * 500; → temp = temp * 500 / 255;
36 p.s. 修改后的temp要改成unsigned long, FF*500溢出int范围
37 */
38 temp = temp * 500 / 255;
39 oe = 0; //oe呈高阻
40 /*数码管显示*/
41 temp_data = temp % 10;
42 P2 = 0xfe; //数码管选择最后一位
43 P1 = table[temp_data];
44 Delay(500);
45 temp_data = temp / 10 % 10;
46 P2 = 0xfd; //数码管选择十位
47 P1 = table[temp_data];
48 Delay(500);
49 temp_data = temp / 100 % 10;
50 P2 = 0xfb; //数码管选择百位
51 P1 = table[temp_data];
52 dot = 1; //显示小数点
53 Delay(500);
54 /*启动下一次转换*/
55 start = 1;
56 start = 0;
57 }
58 }
59 }