标题: stc12c5a60s2单片机用自带ADC采集电压源程序 [打印本页]

作者: zc95127    时间: 2017-6-13 11:37
标题: stc12c5a60s2单片机用自带ADC采集电压源程序
stc12c5a60s2采集电压实物图:



单片机源程序如下:
  1. /***********************************************************
  2. 程序功能:STC12C5A60S2自带ADC采集电压信号+DS18B20温度传感器+LCD1602液晶显示
  3. MCU型号: STC12C5A60S2
  4. 晶振频率:11.0892MHz
  5. 整理时间:2012年4月25号
  6. ************************************************************/

  7. #include "reg51.h"
  8. #include "intrins.h"
  9. sfr P4        = 0XC0;
  10. sfr ADC_CONTR = 0XBC;
  11. sfr ADC_RES   = 0XBD;
  12. sfr ADC_LOW2  = 0XBE;
  13. sfr P1ASF     = 0X9D;

  14. typedef unsigned char BYTE;
  15. typedef unsigned int WORD;

  16. #include "1602.h"
  17. #include "DS18B20.h"

  18. #define ADC_POWER   0X80
  19. #define ADC_FLAG    0X10
  20. #define ADC_START   0X08
  21. #define ADC_SPEEDLL 0X00
  22. #define ADC_SPEEDL  0X20
  23. #define ADC_SPEEDH  0X40
  24. #define ADC_SPEEDHH 0X60

  25. void InitADC();
  26. void Delay(WORD n);
  27. WORD GetADCResult(BYTE ch);
  28. void DisplayADCResult(BYTE Channel);
  29. void DisplayTemperature();

  30. char qian=0,bai=0,shi=0,ge=0;
  31. BYTE ly_dis[4];//定义显示缓冲区

  32. void main()
  33. {
  34.         WORD i=0;
  35.         float tt;
  36.         int ltemp;
  37.         InitADC();
  38.         LCDInit();
  39.         DisplayListChar(0, 0, "Temp:");
  40.         DisplayListChar(0, 1, "Volt:");
  41.         while(1)
  42.         {

  43.                 if(i==0)
  44.                         tmpchange();              //温度转换
  45.                 if(i==100)
  46.                 {
  47.                         tt=tmp()*0.0625;          //得到真实十进制温度值,因为DS18B20
  48.                                                                 //可以精确到0.0625度,所以读回数据的最低位代表的是0.0625度。
  49.                           ltemp=tt*10+0.5;           //放大十倍,这样做的目的将小数点后第一位也转换为可显示数字,同时进行一个四舍五入操作。

  50.                         if(ltemp<0)
  51.                         {                //判断第一位显示整数还是负号
  52.                                 ly_dis[0]=0xbf;
  53.                                 ltemp=0-ltemp;        
  54.                         }
  55.                         else
  56.                                 ly_dis[0]=ltemp/1000;//显示百位值
  57.                         ltemp=ltemp%1000;
  58.                         ly_dis[1]=ltemp/100;        //显示温度十位值
  59.                         ltemp=ltemp%100;
  60.                         ly_dis[2]=ltemp/10;                //显示温度个位值
  61.                         ly_dis[3]=ltemp%10;                //显示小数点后一位
  62.                 }
  63.                 i++;
  64.                 if(i==3000)
  65.                 {
  66.                         DisplayADCResult(0);
  67.                         i=0;
  68.                 }                        
  69.                 DisplayTemperature();        //调用显示               
  70.         }
  71. }

  72. void DisplayADCResult(BYTE Channel)
  73. {

  74.         qian=GetADCResult(Channel)/1000;
  75.         bai=GetADCResult(Channel)%1000/100;
  76.         shi=GetADCResult(Channel)%1000%100/10;
  77.         ge=GetADCResult(Channel)%10;
  78.         if(0==qian)
  79.         DisplayOneChar(5,1,' ');
  80.         else
  81.         DisplayOneChar(5,1,table[qian]);

  82.         if(0==bai&&0==qian)
  83.         DisplayOneChar(6,1,' ');
  84.         else
  85.         DisplayOneChar(6,1,table[bai]);

  86.         DisplayOneChar(7,1,table[shi]);
  87.         DisplayOneChar(8,1,table[ge]);
  88.         
  89.         DisplayOneChar(9, 1, 'v');
  90.                
  91. }

  92. void DisplayTemperature()
  93. {
  94.         if(0==ly_dis[0])
  95.                 DisplayOneChar(5, 0, ' ');
  96.         else
  97.                 DisplayOneChar(5, 0, table[ly_dis[0]]);
  98.         DisplayOneChar(6, 0, table[ly_dis[1]]);
  99.         DisplayOneChar(7, 0, table[ly_dis[2]]);
  100.         DisplayOneChar(8, 0, '.');
  101.     DisplayOneChar(9, 0, table[ly_dis[3]]);
  102.         DisplayOneChar(10, 0, 0xdf);
  103.         DisplayOneChar(11, 0, 'C');
  104. }

  105. WORD GetADCResult(BYTE ch)
  106. {
  107.         ADC_CONTR=ADC_POWER|ADC_SPEEDLL|ch|ADC_START;
  108.         _nop_();
  109.         _nop_();
  110.         _nop_();
  111.         _nop_();
  112.         while(!(ADC_CONTR&ADC_FLAG));
  113.         ADC_CONTR&=~ADC_FLAG;

  114.         return ADC_RES*4+ADC_LOW2;
  115. }

  116. void InitADC()
  117. {
  118. ……………………

  119. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码


所有资料51hei提供下载:
STC12C5A60S2自带ADC采集电压信号 DS18B20温度传感器 LCD1602液晶显示.rar (458.99 KB, 下载次数: 625)




作者: dy59731286    时间: 2017-7-17 11:13
谢谢大神 的分享了,谢谢谢谢
作者: qxdqx    时间: 2018-9-16 09:29
不知道准确不?
作者: songlei3232    时间: 2018-9-16 11:19
学习一下。
作者: 751694839    时间: 2018-10-31 12:18
可以测多少V的电压呢?
作者: goodluck-ray    时间: 2018-11-16 09:54
下载看看
作者: wangsh    时间: 2018-11-22 17:23
感谢分享,谢谢
作者: jinjiaji    时间: 2018-11-29 11:01
非常感谢
作者: 79229道天    时间: 2019-3-11 20:02
能用?
作者: 白歌    时间: 2019-4-4 16:40
感谢分享
作者: 45e67    时间: 2019-4-15 14:10

谢谢大神 的分享了,谢谢谢谢
作者: Plutoace    时间: 2019-5-7 18:44
真好 谢谢 很有用
作者: RobinYuan888    时间: 2019-5-12 20:47
谢谢楼主分享
作者: RobinYuan888    时间: 2019-5-12 20:47
谢谢楼主分享,楼主大好人
作者: qq386556027    时间: 2019-8-20 21:04
下载试试  主要是ADC采集
作者: fankechang    时间: 2019-9-22 15:28
试试看
作者: 那些年,    时间: 2019-9-24 22:26
可用,哈哈
作者: jacky852    时间: 2019-12-5 08:56
好有用,非常感谢
作者: jacky852    时间: 2019-12-5 08:58
找了好久的ADC模块
作者: jacky852    时间: 2019-12-5 09:05
为什么有typedef unsigned char BYTE;啊
作者: eleventree    时间: 2019-12-8 12:18
希望能用到,感谢楼主分享!
作者: blackstar    时间: 2020-3-9 22:42
请问为什么是2倍?
作者: renwenjun1    时间: 2020-3-10 09:16
学习一下。
作者: popo321    时间: 2020-4-13 16:35
学习一下,谢谢
作者: 猪哼哼    时间: 2020-5-29 17:23
谢谢大神分享
作者: hai861017    时间: 2020-8-5 23:38
学习一下,感谢
作者: cjffengyu    时间: 2020-8-16 10:42
感谢,正在找这个资料,谢谢大神分享!
作者: 19011250    时间: 2020-8-26 16:37
调试了。挺好,我的获得的电压数据怎么是实际数据的大约两倍呢


另外一点,提示大家
void DisplayADCResult(BYTE Channel)
{

        qian=GetADCResult(Channel)/1000;
        bai=GetADCResult(Channel)%1000/100;
        shi=GetADCResult(Channel)%1000%100/10;
        ge=GetADCResult(Channel)%10;

这段最好写一次=GetADCResult(Channel),因为在获得数据接近整数时,会发生bug。
例如3.98跳到3.02,实际上应该是4.02。
改成
word data=GetADCResult(Channel);
  qian=data/1000;
        bai=data%1000/100;
        shi=data%1000%100/10;
        ge=data%10;

就不会有问题了。

作者: wbz0508    时间: 2020-8-26 21:33
能否直接把交流220V分压后供检测?是否会干扰单片机?
作者: buwangjiunian    时间: 2020-10-11 13:21
感谢分享,程序可以运行、。。。。
作者: 74LS161    时间: 2021-7-21 17:09
可以可以很可靠




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1