找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5229|回复: 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, 下载次数: 176)

评分

参与人数 1黑币 +50 收起 理由
admin + 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 单片机教程网

快速回复 返回顶部 返回列表