搜索
bottom↓
回复: 55

只适合新手进的帖子,单片机边学边玩之---制作一个电压表,附有视频。

[复制链接]

出0入0汤圆

发表于 2011-8-26 09:57:34 | 显示全部楼层 |阅读模式
第一回:制作一个电压表,使用STC12C5A08S2单片机、12M晶振、4位LED数码管。 (录了一段视频仅供比我还新的新手参考。)


电路图如下:

(原文件名:电压表.gif)

用洞洞板(万用板、万能板)做的电压表

(原文件名:实物图01.jpg)

上电后

(原文件名:实物图02.jpg)





C程序如下
//-----------------------------------------------------------------
#include <intrins.H>                  //头文件
#include "STC_NEW_8051.H"             //STC自己的头文件
#define uint unsigned int             //宏定义
#define uchar unsigned char
uint abc,tongd0,tongd7;               //定义uint型变量
uchar tt0;                            //定义uchar型变量
sbit gewei=P2^0;                      //个十百千位的位声明
sbit shiwei=P2^1;
sbit baiwei=P2^2;
sbit qianwei=P2^3;
sbit dian=P0^7;                       //小数点的声明
uchar code led[]=
{0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0xf8,0x80,0x90};  //定义0-9数字的编码
void delay(uint z)                    //延时函数
{
     uint x,y;
     for(x=z;x>0;x--)
     for(y=100;y>0;y--);
}
void display()                        //显示函数
{
     qianwei=0;                       //显示千位
     P0=led[abc/1000];
     dian=0;
     delay(50);
     qianwei=1;

     baiwei=0;                        //显示百位
     P0=led[abc%1000/100];
     delay(50);
     baiwei=1;

     shiwei=0;                        //显示十位
     P0=led[abc%100/10];
     delay(50);
     shiwei=1;

     gewei=0;                         //显示个位
     P0=led[abc%10];
     delay(50);
     gewei=1;
}

//以下直接引用自STC的网站数模转换的例子-------------------------------------
//以下选择 ADC 转换速率,只能选择其中一种
//SPEED1 SPEED0  A/D转换所需时间
#define AD_SPEED   0x60 //  0110,0000   1      1   70 个时钟周期转换一次,
//CPU工作频率21MHz时 A/D转换速度约 300KHz
//#define AD_SPEED   0x40 //0100,0000   1      0     140 个时钟周期转换一次
//#define AD_SPEED   0x20 //0010,0000   0      1     280 个时钟周期转换一次
//#define AD_SPEED   0x00 //0000,0000   0      0     420 个时钟周期转换一次

uint get_AD_result(uchar channel)                   //模数转换程序
{
     uchar AD_finished=0;                           //存储 A/D 转换标志
     ADC_RES = 0;
     ADC_RESL = 0;
     channel &= 0x07;                               //0000,0111 清0高5位
     ADC_CONTR = AD_SPEED;
     _nop_();
     ADC_CONTR |= channel;                          //选择 A/D 当前通道
     _nop_();
     ADC_CONTR |= 0x80;                             //启动 A/D 电源
     delay(1);                                                //使输入电压达到稳定
     ADC_CONTR |= 0x08;                             //0000,1000 令 ADCS = 1, 启动A/D转换,
     AD_finished = 0;
     while (AD_finished ==0 )                       //等待A/D转换结束
     {
           AD_finished = (ADC_CONTR & 0x10);        //0001,0000 测试A/D转换结束否
     }
     ADC_CONTR &= 0xE7;                             //1111,0111 清 ADC_FLAG 位, 关闭A/D转换,
     return (ADC_RES*4+ADC_RESL);                   //返回 A/D 高8位+低2位转换结果
}

//------下面是主函数--------
void main()                                         //主程序
{                                                   //进入主程序后先对定时器初始化

      TMOD=0x01;                                    //设定定时器0工作方式  
      TH0=(65536-10000)/256;                        //定时器0高8位装初值  12M晶振定时10毫秒
      TL0=(65536-10000)%256;                        //定时器0低8位装初值  
      ET0=1;                                        //开定时器0中断
      TR0=1;                                        //启动定时器0
      EA=1;                                         //开总中断

      P1ASF = 0x81;                                 //1000,0001, 将 P1.0 P1.7 置成模拟口
//    ADRJ = AUXR1^2:
//    0: 10 位A/D 转换结果的高8 位放在ADC_RES 寄存器, 低2 位放在ADC_RESL 寄存器
//    1: 10 位A/D 转换结果的最高2 位放在ADC_RES 寄存器的低2 位, 低8 位放在ADC_RESL 寄存器
      AUXR1 &= ~0x04;                               //0000,0100, 令 ADRJ=0
//    AUXR1 |= 0x04;                                //0000,0100, 令 ADRJ=1
      ADC_CONTR |= 0x80;                            //1000,0000 打开 A/D 转换电源

      while(1)
     {
           abc=(tongd0*1.0/tongd7)*2500;            //让abc等于通道0和通道7转换后的运算结果
           display();                               //显示具体数字
     }
}

void timer0() interrupt 1                           //定时器0服务程序
{
      TH0=(65536-10000)/256;                        //再装一次初值
      TL0=(65536-10000)%256;
      tt0++;
      if(tt0==20)                                   //200ms转换一次
     {
           tt0=0;
           tongd0=get_AD_result(0);                 //转换P0.0通道
           tongd7=get_AD_result(7);                 //转换P0.7通道
     }
}


刚出锅的视频,仅供新手参考,下载
地址1:http://u.115.com/file/clqe209u
地址2:http://www.rayfile.com/files/7bd097b5-cd65-11e0-a13e-0015c55db73d/

阿莫论坛20周年了!感谢大家的支持与爱护!!

曾经有一段真挚的爱情摆在我的面前,我没有珍惜,现在想起来,还好我没有珍惜……

出0入0汤圆

 楼主| 发表于 2011-8-26 09:59:40 | 显示全部楼层
原来主要玩模电,刚刚对单片机产生兴趣所以趁热打铁赶紧玩玩免得过几天又没兴趣了。

出0入0汤圆

发表于 2011-8-26 10:35:04 | 显示全部楼层
不错!

出0入0汤圆

发表于 2011-8-26 11:00:19 | 显示全部楼层
围观一下

出0入0汤圆

发表于 2011-8-26 11:27:51 | 显示全部楼层
围观

出0入0汤圆

发表于 2011-8-26 16:13:33 | 显示全部楼层
学习学习

出0入0汤圆

发表于 2011-8-28 15:25:22 | 显示全部楼层
不错

出0入0汤圆

发表于 2011-8-28 20:48:37 | 显示全部楼层
学习

出0入0汤圆

发表于 2011-8-29 14:59:18 | 显示全部楼层
呵呵,缺检测参考电压。

你怎么知道你的5V就一定是5V不动呢。建议在采样一个2极管的0.7V。用这个值 反推当前电压。在算你的测量值

出0入0汤圆

发表于 2011-8-29 20:41:59 | 显示全部楼层
1楼说的没错,要跟着兴趣走就最好,学到最多东西。多谢楼主分享

出0入0汤圆

发表于 2011-8-29 21:42:54 | 显示全部楼层
我没看出是那两个管脚是输入管脚,是自己近视吗?

出0入0汤圆

 楼主| 发表于 2011-11-3 21:07:35 | 显示全部楼层
回复【9楼】lichking
呵呵,缺检测参考电压。
你怎么知道你的5v就一定是5v不动呢。建议在采样一个2极管的0.7v。用这个值 反推当前电压。在算你的测量值
-----------------------------------------------------------------------

回复【11楼】311421 沙漠中的骆驼
我没看出是那两个管脚是输入管脚,是自己近视吗?
-----------------------------------------------------------------------

有参考电压的,P1.7接的TL431就是参考源。
P1.0是电压输入检测端,我是用电位器来模拟输入0-5v电压的变化。图中是测试5v以下电压的,如果测量更高电压可以用电阻分压再输入。比如测量50v以内电压可以按下图



(原文件名:未命名.GIF)

出0入0汤圆

发表于 2011-11-3 22:07:22 | 显示全部楼层
好东西   学习

出0入0汤圆

发表于 2011-11-9 23:18:09 | 显示全部楼层
回复【楼主位】zbn2010
-----------------------------------------------------------------------

不好意思,俺是新手。LZ 的A/D是靠什么转换的??  单片机自带的??

出0入0汤圆

发表于 2011-12-7 16:41:30 | 显示全部楼层
学习

出0入0汤圆

发表于 2011-12-7 16:56:01 | 显示全部楼层
正好,俺也是新手

出0入0汤圆

发表于 2011-12-7 23:21:40 | 显示全部楼层
感谢,我是新手。

出0入0汤圆

发表于 2011-12-9 02:33:54 | 显示全部楼层
楼主到期了946330281

出0入0汤圆

发表于 2011-12-9 16:00:48 | 显示全部楼层
lz ad结果最好加算数平均滤波,否则殊跳的乱。

出0入0汤圆

发表于 2011-12-9 17:24:12 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-12-9 17:59:28 | 显示全部楼层
回复【楼主位】zbn2010
-----------------------------------------------------------------------

学习学习

出0入0汤圆

发表于 2011-12-9 18:32:33 | 显示全部楼层
哗~感觉楼主那洞洞板五颜六色呀~

出0入0汤圆

发表于 2011-12-9 18:36:13 | 显示全部楼层
回复【14楼】qun453176385 囡囡
回复【楼主位】zbn2010  
-----------------------------------------------------------------------
不好意思,俺是新手。lz 的a/d是靠什么转换的??  单片机自带的??
-----------------------------------------------------------------------

STC12C5A60S2单片机是有自带AD的, 自己去找datasheet瞅瞅吧~

出0入0汤圆

发表于 2011-12-9 22:39:45 | 显示全部楼层
真好。

出0入0汤圆

发表于 2011-12-10 10:49:36 | 显示全部楼层
楼主很强大   最近对单片机有兴趣了

出90入0汤圆

发表于 2011-12-10 23:10:52 | 显示全部楼层
谢谢楼主分享^
边玩边学是最快乐的,也能学到很多东西,兴趣最重要!

出0入0汤圆

发表于 2011-12-24 23:29:24 | 显示全部楼层
楼主你好,如果加上超过(低于)某电压报警功能,应该怎样写程序?

出0入0汤圆

发表于 2011-12-25 22:22:52 | 显示全部楼层
多少V电压的呢

出0入0汤圆

发表于 2011-12-28 11:22:06 | 显示全部楼层
mark

出0入0汤圆

发表于 2011-12-28 14:11:49 | 显示全部楼层
我用2052做过.不过2052精度不太好,但是还用差分放大器显示了电流,不过显示不到小电流,误差还是很大的,后来就没继续玩下去了

出0入0汤圆

 楼主| 发表于 2011-12-28 14:24:46 | 显示全部楼层
回复【27楼】iSTC
楼主你好,如果加上超过(低于)某电压报警功能,应该怎样写程序?
-----------------------------------------------------------------------

用一个io口驱动pnp三极管接蜂鸣器。
程序部分先对这个io口位声明
比如 sbit baojing=P*^*;

然后在主程序的while(1)里加上一个判断语句就行了
比如电压超过4v就报警可以这样写
if(abc>4000)
   baojing=0;
else
   baojing=1;

出0入0汤圆

发表于 2012-6-1 22:52:01 来自手机 | 显示全部楼层
准备学习下

出0入85汤圆

发表于 2012-6-1 23:39:53 | 显示全部楼层
不知道这STC12系列的AD稳定不

出0入0汤圆

发表于 2012-6-2 16:43:40 来自手机 | 显示全部楼层
太强了,再搞搞,万用表就出来

出0入0汤圆

发表于 2012-6-3 14:56:26 | 显示全部楼层
学习了!!!

出0入0汤圆

发表于 2012-6-14 11:31:48 | 显示全部楼层
围观一下

出0入0汤圆

发表于 2012-9-5 10:02:28 | 显示全部楼层
不错      

出0入0汤圆

 楼主| 发表于 2012-9-6 09:35:35 | 显示全部楼层
有人顶上来了,那我就再更新一下。原来的显示程序如果刷新率比较高时“鬼影”现象明显,稍改一下就可以了。如下图

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2012-9-6 15:21:25 | 显示全部楼层
提示楼主,妖怪的PDF里说明了,RC复位没有电阻分压复位可靠

出0入0汤圆

发表于 2012-9-6 15:31:33 | 显示全部楼层
STC这个NC的东西,没有独立的VREF。。。楼主的VCC要一定稳定才行啊,

出0入0汤圆

发表于 2012-9-6 15:33:24 | 显示全部楼层
标记下!学习了

出0入0汤圆

发表于 2012-9-8 16:28:23 | 显示全部楼层
好东西,顶一下

出0入0汤圆

发表于 2012-9-21 12:34:44 | 显示全部楼层
那个P1.7的参考电压是用来做什么的?

出0入0汤圆

发表于 2012-9-21 13:13:12 | 显示全部楼层
不错, 加了一个基准电压作参考,TL431。因为7805 的输出的5V 电压范围 比较宽,所以会有些误差, 接入TL431,计算出来的误差就更小一些了。

出0入0汤圆

发表于 2012-9-22 23:49:51 | 显示全部楼层
学习了!!!

出0入85汤圆

发表于 2012-9-23 00:28:51 | 显示全部楼层
不知道这个电压表和万用表对比下,准不?另外接一固定电压,最后一位能跳几个数?

出0入0汤圆

发表于 2012-10-18 13:55:53 | 显示全部楼层
真好,学习学习

出0入0汤圆

发表于 2013-2-24 11:38:03 | 显示全部楼层
楼主你的视频下载不到了,能重给个下载地址吗?

出0入0汤圆

发表于 2013-3-17 23:36:59 | 显示全部楼层
不错,我精度是多少啊

出0入0汤圆

发表于 2013-3-17 23:58:27 来自手机 | 显示全部楼层
比我爱折腾多了
来自:amoBBS 阿莫电子论坛 Windows Phone 7 客户端

出0入0汤圆

发表于 2013-3-18 02:33:47 | 显示全部楼层
路过看看、、、

出0入0汤圆

发表于 2013-6-5 12:43:45 | 显示全部楼层
i7gly 发表于 2011-12-28 14:11
我用2052做过.不过2052精度不太好,但是还用差分放大器显示了电流,不过显示不到小电流,误差还是很大的,后来 ...

你好,我只买到STC12C2052,想做个电压表装在电动车上检测电池电压。能指导下我给点资料吗?

出0入0汤圆

发表于 2013-6-5 20:42:28 | 显示全部楼层
huq2012 发表于 2013-6-5 12:43
你好,我只买到STC12C2052,想做个电压表装在电动车上检测电池电压。能指导下我给点资料吗? ...

其实都差不多,看看STC的文档就能做了

出0入0汤圆

发表于 2013-6-6 00:24:59 | 显示全部楼层
用滑动平均滤波,效果会更好,我也做过的,不过没有加参考电压

出0入0汤圆

发表于 2013-6-6 12:22:23 | 显示全部楼层
新手好成功了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-8-26 12:21

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

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