找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 5873|回复: 2
收起左侧

单片机制作的电压表源程序 0-18v

  [复制链接]
ID:683123 发表于 2020-3-23 20:43 | 显示全部楼层 |阅读模式
从一个废仪表上拆了一个数码管版,经过改造,焊出相应的驱动板,做出一个电压表。
选用STC15w408AS单片机,由于引脚少,选用74hc138芯片作为位选,74hc595作为段选,用TL431的2.5v稳压源做参考电压。
电压表的设计思路:其实就是运用单片机内置的多个接口ADC转换。选用稳压2.5v进行ADC转换,这样电压变化小,转出的ADC的值变的也小(估值558左右),再经过另外一路两个电阻分压点转换出来的ADC的值进行计算。理论上能做到0~无穷大量程的(没啥实际意义)。根据这个思路如果分压电阻小于1R,根据分压计算也可以设计出电流表。这里没做电压电流表,其实知道原理就行了。

制作出来的实物图如下:
167258892.jpg 205917003.jpg 1025592641.jpg 1525746405.jpg 1682760983.jpg 1952476574.jpg
复制的代码注释乱码,大家可以下载附件查看,标注详细,适合初学单片机ADC的人。注:本人也是菜鸟一枚,大家互相交流学习,有更好的方案可以留言。共同进步。

单片机源程序如下:
  1. #include <STC15F2K60S2.H>
  2. #include<intrins.h>
  3. #define ADC_POWER     0x80
  4. #define ADC_FLAG      0x10
  5. #define ADC_START     0x08
  6. #define ADC_SPEEDLL   0x00
  7. #define ADC_SPEEDL    0x20
  8. #define ADC_SPEEDH    0x40
  9. #define ADC_SPEEDHH   0x60
  10. typedef unsigned char uchar;
  11. typedef unsigned int uint;
  12. sbit LSA=P1^2;
  13. sbit LSB=P1^0;
  14. sbit LSC=P3^7;  //定义138逻辑芯片A,B,C脚
  15. sbit SRCLK=P3^6;
  16. sbit RCLK=P3^3;
  17. sbit SER=P3^2;//定义595芯片驱动脚

  18. uchar number[]={0x82,0xf6,0x43,0x46,0x36,0x0e,0x0a,0xe6,0x02,0x06};  //0-9断码非标准码
  19. unsigned char ch=4; //通道4,根据手册0为P1^0,1为P1^1,依次类推
  20. float voltage=0;  //定义浮点电压参数
  21. uint ref=0,vin=0; //定义431稳压2.5v的ADC值。ref值是P1^4,vin是P1^3的ADC值
  22. void Hc595SendByte(uchar dat);//声明595函数
  23. void DigDisplay();//声明显示函数

  24. void Delay1ms()                //@24.000MHz
  25. {
  26.         unsigned char i, j;
  27.         i = 24;        j = 85;
  28.         do
  29.         {
  30.                 while (--j);
  31.         } while (--i);
  32. }
  33. void adc_int() interrupt 5   //ADC中断
  34. {
  35.        
  36.         uint j=0;
  37.         ADC_CONTR &=!ADC_FLAG;//清除中断标志位
  38.         if(ch==4)
  39.         {
  40.            ref=(ADC_RES*4+ADC_RESL);   //读取P1^4口ADC值保存在ref变量中,由于采用tl431稳压2.5v,所以这个值大约在558左右。
  41.         }
  42.         else if(ch==3)
  43.         {
  44.                  vin=(ADC_RES*4+ADC_RESL);   //读取P1^3口ADC值,这个值经过两个电阻分压得到的。
  45.            voltage=(2.5*vin)/ref;   //计算电压
  46.         }
  47.   if(ch==4)    //切换转换ADC口
  48.                 ch=3;
  49.         else if(ch==3)
  50.                 ch=4;
  51.         for(j=0;j<=30;j++);
  52.         ADC_RES=0;
  53.         ADC_RESL=0;
  54.         ADC_CONTR=ADC_POWER |ADC_SPEEDLL | ADC_START | ch;//启动ADC转换
  55. }

  56. void main()
  57. {
  58.         uint i;

  59.         P1ASF=0x18;//参考手册,0x38=00011000,开启P1^3,P1^4为ADC输入口,其余P1口为正常IO口
  60.         ADC_RES=0;
  61.         ADC_CONTR=ADC_POWER|ADC_SPEEDLL | ADC_START | ch;
  62.         for(i=0;i<1000;i++);
  63.         IE=0xA0;
  64.         while(1)
  65.         {
  66.                 DigDisplay();
  67.         }
  68. }
  69. void Hc595SendByte(uchar dat)            
  70. {
  71.         uchar a;
  72.         SRCLK=0;
  73.         RCLK=0;
  74.         for(a=0;a<8;a++)
  75.         {
  76.                 SER=dat>>7;
  77.                 dat<<=1;
  78.                 SRCLK=1;
  79.                 _nop_();          
  80.                 SRCLK=0;       
  81.         }
  82.         RCLK=1;
  83.         _nop_();       
  84.         RCLK=0;
  85. }

  86. void DigDisplay()
  87. {
  88.         uchar i;
  89.         uint j;
  90.         float k;
  91.         k=voltage*380;  //这个值可以修正,依据是根据两个电阻的分压点计算的,同事放大1000倍,这样下面显示可以显示小数。
  92.    j=(uint) k;   //转换成INT类型,不然下面的编译不了。
  93.        
  94.         for(i=0;i<8;i++)
  95.         {
  96.                 switch(i)         
  97.                 {
  98.                         case(0):
  99.                                 LSA=0;LSB=0;LSC=0;Hc595SendByte(number[vin/1000]); break;
  100.                         case(1):
  101.                                 LSA=1;LSB=0;LSC=0;Hc595SendByte(number[vin%1000/100]); break;
  102.                         case(2):
  103.                                 LSA=0;LSB=1;LSC=0; Hc595SendByte(number[vin%1000%100/10]);break;
  104.                         case(3):
  105.                                 LSA=1;LSB=1;LSC=0;Hc595SendByte(number[vin%1000%100%10]); break;   //显示当前测量的ADC的值,0-1023
  106.                         case(4):
  107.                                 LSA=0;LSB=0;LSC=1; Hc595SendByte(number[j/1000]);break;
  108.                         case(5):
  109.                                 LSA=1;LSB=0;LSC=1;Hc595SendByte(number[j%1000/100]&0xfd);  break;
  110.                         case(6):
  111.                                 LSA=0;LSB=1;LSC=1;Hc595SendByte(number[j%1000%100/10]); break;
  112.                         case(7):
  113.                                 LSA=1;LSB=1;LSC=1; Hc595SendByte(number[j%1000%100%10]);break;  //显示当前电压值
  114.                        
  115.                 }
  116.                
  117.           Delay1ms();
  118.                 Hc595SendByte(0xFF);
  119.                
  120.         }
  121. }
复制代码

所有资料51hei提供下载:
STC15W408AS电压表.zip (39.41 KB, 下载次数: 107)
回复

使用道具 举报

ID:3666 发表于 2021-10-18 10:58 | 显示全部楼层
你取采集电阻各为多少呀
回复

使用道具 举报

ID:969272 发表于 2021-10-24 18:18 | 显示全部楼层
电压范围太小了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

Powered by 单片机教程网

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