设为首页 加入收藏

TOP

51单片机 | A/D转换器实现数字电压表实例
2017-10-11 15:05:15 】 浏览:745
Tags:单片机 A/D 转换器 实现 数字 电压表 实例

————————————————————————————————————————————

ADC0809

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

工作原理:

  • ADDA/ADDB/ADDC 输入3 位地址,并使ALE=1,将地址存入地址锁存器中

    ALE:地址锁存允许信号接入端,高电平时允许改变CBA的值,低电平时锁死,防止在A/D转换过程中切换通道

  • 地址经译码选通8路模拟输入IN0~IN7之一到比较器,输入与被选通道关系

通道

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

  • START端上升沿将逐次逼近寄存器复位,下降沿启动A/D转换
  • EOC输出信号变低电平,表示正在转换;当A/D转换完成,EOC变为高电平,结果数据已存入锁存器。
  • OE输入高电平,输出三态门打开,转换结果的数字量输出到数据总线上。

    OE=1时,D0-D7引脚上为转换后的数据,当OE=0时,D0-D7为对外呈现高阻状态

p.s.

其他引脚:

IN0~IN78路模拟量输入引脚

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 }

 

】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇IPC- Posix与system v 下一篇stm32之SPI通信协议

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目