单片机教程网

电脑版
提示:原网页已由神马搜索转码, 内容由www.51hei.com提供.
查看:4687|回复:5

单片机+ADC0832实现量程0~25V数字电压表的仿真程序设计

 [复制链接]
ID:825513发表于 2021-9-19 12:29|显示全部楼层
第一次接触模数转换,做了这么一个小仿真,测量0~25V的输入电压,以4位数(两位小数)的形式显示在一个四位共阳数码管上,测量误差不大于0.1V。
ADC0832只是一个对0~5V电压进行模拟转数字的器件,分辨率8位,即有从0到255个挡位,每一档约为(5/255)V,即0.02V,为了实现0~25V的转换,先将待测电压通过电位器(滑动电阻)缩小5倍,保证其始终处于0~5V内再输入ADC0832(ADC0832实际转换的模拟量在0~5V之内),然后再将ADC0832转换后的数值*5,即可获知待测电压的实际值。


但这种取巧的方式虽然能在不换器件的前提下实现量程的扩充,但缺陷是误差值也随之放大(因为先把电压通过电位器几乎零误差的缩小1/5,然后再把ADC0832的转换结果放大5倍),ADC0832的误差值大约0.02V,电压表实际测量的误差值大约0.1V

仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)
Snipaste_2021-09-19_12-25-31.png

源码:
  1. #include<reg51.h>
  2. #include<intrins.h>

  3. sbit CS=P3^5;
  4. sbit CLK=P3^3;
  5. sbit DI=P3^4;
  6. sbit DO=P3^4;
  7. sbit dot=P0^5;     //小数点

  8. unsigned char dat=0x00;
  9. unsigned char nums[]={0x00,0x00,0x00,0x00};
  10. unsigned char channel;     //转换通道
  11. unsigned char LEDS[]={0xA0,0xBB,0x62,0x2A,0x39,0x2C,0x24,0xB8,0x20,0x28};     //共阳4位数码管段码,字符显示从'0'到'9'

  12. unsigned char ADC0832(unsigned char channel)       //模数转换
  13. {
  14.    unsigned char i;
  15.    unsigned char x=0x00;
  16.    unsigned char y=0x00;

  17.    CLK=0;     //初始化
  18.    DI=1;
  19.    _nop_();
  20.    CS=0;
  21.    _nop_();
  22.    CLK=1;
  23.    _nop_();

  24.    if(channel==0x00)     //通道选择
  25.    {     //通道0
  26.        CLK=0;
  27.        DI=1;
  28.        _nop_();
  29.        CLK=1;
  30.        _nop_();
  31.        CLK=0;
  32.        DI=0;
  33.        _nop_();
  34.        CLK=1;
  35.        _nop_();
  36.    }
  37.    else       //通道1
  38.    {
  39.        CLK=0;
  40.        DI=1;
  41.        _nop_();
  42.        CLK=1;
  43.        _nop_();
  44.        CLK=0;
  45.        DI=1;
  46.        _nop_();
  47.        CLK=1;
  48.        _nop_();
  49.    }

  50.    CLK=0;
  51.    DI=1;
  52.    for(i=0;i<8;i++)       //读取ADC0832输出的前8位数据
  53.    {
  54.        x<<=1;
  55.        _nop_();
  56.        CLK=1;
  57.        _nop_();
  58.        CLK=0;
  59.        if(DO==1)
  60.        {
  61.          x|=0x01;
  62.        }
  63.        else
  64.        {
  65.          x|=0x00;
  66.        }
  67.    }
  68.    for(i=0;i<8;i++)       //读取ADC0832输出的后8位数据
  69.    {
  70.        y>>=1;
  71.        if(DO==1)
  72.        {
  73.          y|=0x80;
  74.        }
  75.        else
  76.        {
  77.          y|=0x00;
  78.        }
  79.        _nop_();
  80.        CLK=1;
  81.        _nop_();
  82.        CLK=0;
  83.    }
  84.    if(x==y)       //校验,比较前8位与后8位的值
  85.    {
  86.        dat=x;
  87.    }
  88.    _nop_();
  89.    CS=1;     //释放ADC0832
  90.    DO=1;
  91.    CLK=1;
  92.    return dat;
  93. }

  94. void Convert(unsigned char dat0)       //数据处理
  95. {
  96.    unsigned int x;
  97.    x=dat0*0.0196*100*5;
  98.    nums[0]=x/1000;
  99.    nums[1]=x%1000/100;
  100.    nums[2]=x%1000%100/10;
  101.    nums[3]=x%1000%100%10;
  102. }

  103. void Delay()       //数码管显示
  104. {
  105.    unsigned char i,j;
  106.    for(i=0;i<1;i++)
  107.    {
  108.        for(j=0;j<121;j++);
  109.    }
  110. }

  111. void Display()
  112. {
  113.    P0=LEDS[nums[0]];
  114.    P2=0xFE;
  115.    Delay();
  116.    P2=0xFF;

  117.    P0=LEDS[nums[1]];
  118.    dot=0;
  119.    P2=0xFD;
  120.    Delay();
  121.    P2=0xFF;

  122.    P0=LEDS[nums[2]];
  123.    P2=0xFB;
  124.    Delay();
  125.    P2=0xFF;

  126.    P0=LEDS[nums[3]];
  127.    P2=0xF7;
  128.    Delay();
  129.    P2=0xFF;
  130. }

  131. void main()
  132. {
  133.    while(1)
  134.    {
  135.        dat=ADC0832(channel);
  136.        Convert(dat);
  137.        Display();
  138.    }
  139. }
复制代码

51hei.png

上图仿真工程文件和.c文件51hei附件下载:
ADC0832数字电压表(0~25V).zip(43.82 KB, 下载次数: 172)

评分

黑币 +50
收起理由
+ 50
共享资料的黑币奖励!

查看全部评分

ID:262发表于 2022-9-19 22:16|显示全部楼层
634658537 发表于 2022-9-19 15:54
仿真图为什么打不开

要用Proteus8.8版本,你看我用这个版本的打开效果,动图
51hei.gif
ID:1011897发表于 2022-4-14 15:46|显示全部楼层
您好  如果我想制成0-200的 缩小40倍吗  精度我这把可以不考虑 1v都可以 需要怎么修改程序
ID:622274发表于 2022-9-19 15:54|显示全部楼层
仿真图为什么打不开
ID:579397发表于 2022-9-20 00:55|显示全部楼层
kinghhback 发表于 2022-4-14 15:46
您好  如果我想制成0-200的 缩小40倍吗  精度我这把可以不考虑 1v都可以 需要怎么修改程序

是的,把R1 R2的电阻修改,用分压公式

数据修改如下:
void Convert(unsigned char dat0)       //数据处理
{
   unsigned int x;
  x=dat0*0.0196*100*5;
   nums[0]=x/1000;
   nums[1]=x%1000/100;
   nums[2]=x%1000%100/10;
   nums[3]=x%1000%100%10;
}
ID:183990发表于 2024-7-9 21:27|显示全部楼层
你好,问下10V一下10位数的0如何不显示呢

手机版|小黑屋|51黑电子论坛|51黑电子论坛6群QQ管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网