单片机论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 15070|回复: 11
收起左侧

比较适合初学者自己动手仿制的电压表

  [复制链接]
dzdiy 发表于 2015-4-11 19:39 | 显示全部楼层 |阅读模式
    这是一个用STC12C2052AD单片机制作的电压表,由电子乐屋收集整理,来源于网络。A/D转换单元用的是单片机的自己带的,比较适合初学者自己动手仿制。单片机采用的是STC12C2052AD,4位共阳极数码管,TL431作为电压基准。电路板采用的感光蓝油制作,使用环保刻蚀剂刻蚀。整个电压表制作容易,非常容易成功。






程序源码:
  1. /**********************************************************************

  2. 基于STC12C4052AD单片机的0-99V数字电压表程序

  3. P1.6口为0-5V模拟量输入端,P1.5口连接TL431l输出的2.5V基准电源,4位串行LED数码管显示

  4. **********************************************************************/

  5. #include <STC/STC12C2052AD.H> //单片机头文件

  6. #include <intrins.h> //51基本运算(包括_nop_空函数)

  7. #define uchar unsigned char

  8. #define uint unsigned int

  9. #define LEDBus P3

  10. //a3.0-b3.1-c3.2-d3.3-e3.4-f3.5-g3.7-dp1.0

  11. sbit ge=P1^4;            //个位位选

  12. sbit shi=P1^3;            //十位位选

  13. sbit bai=P1^2;            //百位位选

  14. sbit qian=P1^1;            //千位位选

  15. sbit db=P1^0;

  16. char d[5];

  17. uint R,M,N;//若定义成uchar型就只能显示2.5V以下的数值

  18. uchar code LEDTab[]={0xc0,0xf9,0x64,0x70,0x59,0x52,0x42,0xf8,0x40,0x50};//应为没有P3.6,所以这里管脚定义和普通的有点区别

  19. unsigned char port[4]={0xfe,0xfd,0xfb,0xf7};

  20. /*****************************************************************

  21. 函数名:毫秒级CPU延时函数

  22. 调  用:delay (?);

  23. 参  数:1~65535(参数不可为0)

  24. 返回值:无

  25. 结  果:占用CPU方式延时与参数数值相同的毫秒时间

  26. 备  注:应用于1T单片机时i<600,应用于12T单片机时i<125

  27. /******************************************************************/

  28. void delay(uint t)

  29. {

  30. uint i;               //定义变量

  31. for(;t>0;t--)             //如果t大于0,t减1(外层循环)

  32.   for(i=600;i>0;i--);         //i等于124,如果i大于0,i减1

  33. }

  34. /*******************************************************************

  35. 函数名:ADC初始化及8位A/D转换函数

  36. 返回值:8位的ADC数据

  37. 结  果:读出指定ADC接口的A/D转换值,并返回数值

  38. 备  注:适用于STC12C2052AD系列单片机(必须使用STC12C2052AD.h头文件)

  39. *******************************************************************/

  40. uchar Read (uchar CHA){

  41. uchar AD_FIN=0; //存储A/D转换标志;若在函数外定义此变量则不能得到连续变化的模拟量的显示

  42. /******以下为ADC初始化程序****************************/

  43.     CHA &= 0x07;            //选择ADC的8个接口中的一个(0000 0111 清0高5位)

  44.     ADC_CONTR = 0x60;  //ADC转换的速度(0XX0 0000 其中XX控制速度,请根据数据手册设置)

  45.     _nop_();

  46.     ADC_CONTR |= CHA;       //选择A/D当前通道

  47.     _nop_();

  48.     ADC_CONTR |= 0x80;      //启动A/D电源

  49.     delay(1);            //使输入电压达到稳定(1ms即可?

  50. /******以下为ADC执行程序****************************/

  51.     ADC_CONTR |= 0x08;      //启动A/D转换(0000 1000 令ADCS = 1)

  52.     _nop_();

  53.     _nop_();

  54.     _nop_();

  55.     _nop_();

  56.     while (AD_FIN ==0){     //等待A/D转换结束

  57.     AD_FIN = (ADC_CONTR & 0x10); //0001 0000测试A/D转换结束否

  58.     }

  59.     ADC_CONTR &= 0xE7;      //1111 0111 清ADC_FLAG位, 关闭A/D转换,

  60. return (ADC_DATA);          //返回A/D转换结果(8位)

  61. }

  62. /******************************************************************

  63. 显示函数转换函数:

  64. M=模拟量采样值,N=基准电压源采样值(本例为2.5V),R=模拟量输入值(待显示值)

  65. N=256*2.5/Vcc;变形后得Vcc=256*2.5/N; 代入M=256*R/Vcc;得到M=R*N/2.5;变形后得R=M*2.5/N

  66. 1为输入端分压比。

  67. ******************************************************************/

  68. void transfer(void){

  69. M=Read(6);//P1.6口模拟量转换

  70. N=Read(5);//P1.5口2.5V基准电压源采样(转换)

  71. R=((M*2.5)/N)*9.31*1000;//输入模拟量换算并放大1000倍;

  72. /***以下为3位显示转换***/

  73. d[3]=R/1000;

  74. R=R%1000;

  75. d[2]=R/100;

  76. R=R%100;

  77. d[1]=R/10;

  78. d[0]=R%10;

  79. }

  80. /******************************************************************

  81. 函数功能:显示子程序

  82. ********************************************************************/

  83. void xian_shi (void)

  84. {

  85.    P1=0xfe;        //P1.3引脚输出低电平

  86.    P3=LEDTab[d[0]];          //显示个位

  87.    delay(1);

  88.    P1=0xfd;       //P1.2引脚输出低电平

  89.    P3=LEDTab[d[1]];         //显示十位

  90.     delay(1);

  91.     db=0;

  92.    P1=0xfb;       //P1.1引脚输出低电平

  93.    P3=LEDTab[d[2]];         //显示百位

  94.    

  95.     delay(1);

  96.    if (LEDTab[3]!=0)

  97.    P1=0xf7;       //P1.0引脚输出低电平

  98.    P3=LEDTab[d[3]];         //显示千位

  99.    db=0;

  100.     delay(1);

  101.     P1=0xff;     //关闭所有数码管

  102.   

  103. }

  104. /******************************************************************

  105. 函数名:主函数

  106. 调  用:无

  107. 参  数:无

  108. 返回值:无

  109. 结  果:程序开始处,无限循环

  110. 备  注:

  111. ******************************************************************/

  112. void main (void)

  113. {

  114. P1M0 = 0x60; //P1.0/P1.1:0000 0011(高阻)//注意:更改ADC通道时须同时将对应的IO接口修改为高阻输入。

  115. P1M1 = 0x00; //P1.0/P1.1:0000 0000

  116. while(1){

  117. uchar i;

  118. delay(1);

  119. i++;

  120. if (i==30)

  121. {

  122. transfer();

  123. i=0;

  124. }

  125. xian_shi();

  126. //delay(10);

  127. }

  128. }
复制代码



评分

参与人数 2黑币 +8 收起 理由
vvv64 + 5
XDDZ1013 + 3 赞一个!

查看全部评分

回复

使用道具 举报

1300811688 发表于 2016-3-24 15:46 | 显示全部楼层
很好,我最近想在开关电源的输出端添加一个单片机显示电压电流的功能,学习了。
回复

使用道具 举报

越快乐越堕落 发表于 2016-6-18 22:21 | 显示全部楼层
为什么我做了好几次,都是只显示最后一位0???而且无法测量,我把75K改成了30K的,75K貌似不合理。
回复

使用道具 举报

XDDZ1013 发表于 2017-5-12 22:29 | 显示全部楼层
数码管用共阴极的,怎么改
回复

使用道具 举报

15895149620 发表于 2017-5-13 10:28 | 显示全部楼层
楼主,求发源文件,仿真
回复

使用道具 举报

尹德文 发表于 2017-11-30 19:54 | 显示全部楼层
我做的只能显示三位数,不知什么原因
回复

使用道具 举报

bhjyqjs 发表于 2018-2-7 15:20 | 显示全部楼层
准确度如何?稳定性怎样?总觉得实用性欠佳
回复

使用道具 举报

nklug 发表于 2018-3-5 10:16 | 显示全部楼层
无分压电阻,只能测到5V以下(单片机工作电压以下)。大约百分之二的误差。
回复

使用道具 举报

ltp 发表于 2018-3-16 13:22 | 显示全部楼层
谢谢分享!
回复

使用道具 举报

干就得了 发表于 2018-3-19 14:32 | 显示全部楼层
楼主能不能测负压
回复

使用道具 举报

ty417502873 发表于 2018-11-24 05:01 | 显示全部楼层
学习一下。
回复

使用道具 举报

zpz181818 发表于 2019-2-9 11:27 | 显示全部楼层
赞,非常好!
回复

使用道具 举报

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

本版积分规则

QQ|手机版|小黑屋|单片机论坛 |51Hei单片机16群 联系QQ:125739409;技术交流QQ群7344883

Powered by 单片机教程网

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