zoukankan      html  css  js  c++  java
  • 51单片机 | 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 }

  • 相关阅读:
    程序员的自我救赎---1.4.3: 核心框架讲解(MVC)
    程序员的自我救赎---1.4.2: 核心框架讲解(BLL&Tool)
    程序员的自我救赎---1.4.1:核心框架讲解(DAL)
    程序员的自我救赎---1.3:事务的使用
    【零基础】极星9.5量化入门一:自定义套利的K线绘制
    【零基础】神经网络实践:BeatSaber粪谱生成器(使用方法篇)
    【零基础】使用Tensorflow实现神经网络
    【零基础】神经网络优化之Adam
    【零基础】神经网络优化之动量梯度下降
    【零基础】神经网络优化之mini-batch
  • 原文地址:https://www.cnblogs.com/hughdong/p/6979204.html
Copyright © 2011-2022 走看看