紫外工控论坛

 找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

搜索
查看: 5390|回复: 5

用DS8B20做简单的电子温度计

[复制链接]
冰糖 发表于 2009-10-21 23:21:32 | 显示全部楼层 |阅读模式

用DS8B20做的电子温度计,非常简单。

  1. #include <reg51.h>     
  2. #include"AscLed.h"
  3. #include <intrins.h>
  4. #include <stdio.h>
  5. //********************************************************
  6. #define Seck    (500/TK)            //1秒中的主程序的系数
  7. #define OffLed    (Seck*5*60)            //自动关机的时间5分钟!
  8. //********************************************************
  9. #if (FHz==0)
  10.     #define NOP_2uS_nop_()
  11. #else
  12.     #define NOP_2uS_nop_();_nop_()
  13. #endif
  14. //**************************************
  15. #define SkipK        0xcc    //跳过命令
  16. #define ConvertK    0x44    //转化命令
  17. #define RdDs18b20K    0xbe    //读温度命令
  18. //*******************************************
  19. extern LedOut(void);
  20. //*************************************************
  21. sbit PNP1=P3^4;
  22. sbit PNP2=P3^5;
  23. sbit BEEP=P3^2;
  24. //***********************************
  25. #defineDQ            PNP2   //原来的PNP2 BEEP
  26. //***********************************
  27. static unsigned char Power=0;
  28. //************************************
  29. union{
  30.     unsigned char     Temp[2];    //单字节温度
  31.     unsigned int     Tt;            //2字节温度
  32. }T;
  33. //***********************************************
  34. typedef struct{
  35.     unsigned char Flag;            //正数标志 0;1==》负数
  36.     unsigned char WenDu;        //温度整数
  37.     unsigned int WenDuDot;        //温度小数放大了10000
  38. }WENDU;
  39. //***********************************************
  40. WENDU    WenDu;
  41. unsigned char LedBuf[3];
  42. //----------------------------------
  43. //功能:10us 级别延时
  44. // n=1===> 6Mhz=14uS 12MHz=7uS
  45. //----------------------------------
  46. void Delay10us(unsigned char n){
  47.    
  48.     do{
  49.         #if (FHz==1)
  50.             NOP_2uS;NOP_2uS;
  51.         #endif
  52.     }while(--n);
  53. }
  54. //-----------------------------------
  55. //功能:写18B20
  56. //-----------------------------------
  57. void Write_18B20(unsigned char n){
  58.     unsigned char i;
  59.     for(i=0;i<8;i++){
  60.         DQ=0;
  61.         Delay10us(1);//延时13us 左右
  62.         DQ=n & 0x01;
  63.         n=n>>1;
  64.         Delay10us(5);//延时50us 以上
  65.         DQ=1;
  66.     }
  67. }
  68. //------------------------------------
  69. //功能:读取18B20
  70. //------------------------------------
  71. unsigned char Read_18B20(void){
  72.     unsigned char i;
  73.     unsigned char temp;
  74.     for(i=0;i<8;i++){
  75.         temp=temp>>1;
  76.         DQ=0;
  77.         NOP_2uS;//延时1us
  78.         DQ=1;
  79.         NOP_2uS;NOP_2uS;//延时5us
  80.         if(DQ==0){
  81.             temp=temp&0x7F;
  82.         }else{
  83.             temp=temp|0x80;
  84.         }
  85.         Delay10us(5);//延时40us
  86.         DQ=1;
  87.     }
  88.     return    temp;
  89. }
  90. //-----------------------------------
  91. void Init (void){
  92.     DQ=0;
  93.     Delay10us(45);//延时500us
  94.     DQ=1;
  95.     Delay10us(9);//延时90us
  96.     if(DQ){        //0001 1111b=1f
  97.         Power =0;    //失败0
  98.     }else{
  99.         Power++;
  100.         DQ=1;
  101.     }
  102. }
  103. //----------------------------------
  104. void Skip(void){
  105.     Write_18B20(SkipK);
  106.     Power++;
  107. }
  108. //----------------------------------
  109. void Convert (void){
  110.     Write_18B20(ConvertK);
  111.     Power++;
  112. }
  113. //______________________________________
  114. void Get_Ds18b20L (void){
  115.     T.Temp[1]=Read_18B20(); //读低位   
  116.     Power++;
  117. }
  118. //______________________________________
  119. void Get_Ds18b20H (void){
  120.     T.Temp[0]=Read_18B20(); //读高位   
  121.     Power++;
  122. }
  123. //------------------------------------
  124. //规范化成浮点数
  125. // sssss111;11110000
  126. // sssss111;1111(0.5,0.25,0.125,0.0625)
  127. //------------------------------------
  128. void ReadTemp (void){
  129.     unsigned char i;
  130.     unsigned intF1=0;
  131.     char j=1;
  132.     code int Code_F[]={6250,1250,2500,5000};
  133.     WenDu.Flag=0;
  134.     if (T.Temp[0] >0x80){    //负温度
  135.         T.Tt =~T.Tt+1;    //取反+1=源吗 +符号S     
  136.         WenDu.Flag=-1;
  137.     }
  138.     T.Tt <<= 4;                //左移4位
  139.     WenDu.WenDu=T.Temp[0];    // 温度整数
  140.     //**************************************************
  141.     T.Temp[1]>>=4;
  142.     //---------------------------
  143.     for (i=0;i<4;i++){        //计算小数位
  144.         F1 +=(T.Temp[1] & 0x01)*Code_F;   
  145.         T.Temp[1]>>=1;
  146.     }
  147.     WenDu.WenDuDot=F1;    //温度的小数
  148.     Power=0;
  149. }
  150. //----------------------------------
  151. void Delay1S (void){
  152.     static unsigned int i=0;
  153.    
  154.     if (++i==Seck) {i=0ower++;}
  155. }
  156. //----------------------------------
  157. void ReadDo (void){
  158.     Write_18B20(RdDs18b20K);
  159.     Power++;
  160. }
  161. /**********************************
  162. 函数指针定义
  163. ***********************************/
  164. code void (code *SubTemp[])()={
  165.     Init,Skip,Convert,Delay1S,Init,Skip,ReadDo,Get_Ds18b20L,
  166.     Get_Ds18b20H,ReadTemp
  167. };
  168. //**************************************
  169. void GetTemp(void){
  170.     (*SubTemp[Power])();
  171. }
  172. //---------------------------------------------------
  173. //将温度显示,小数点放大了10000.
  174. void GetBcd(void){
  175.     LedBuf[0]=WenDu.WenDu / 10;
  176.     LedBuf[1]=WenDu.WenDu % 10 +DotK;
  177.     LedBuf[2]=(WenDu.WenDuDot/1000)%10;
  178.     if(LedBuf[0]==0)LedBuf[0]=Black;
  179.     if(WenDu.Flag==0) return;
  180.     if(LedBuf[0] !=Black){
  181.         LedBuf[2]=LedBuf[1];
  182.         LedBuf[1]=LedBuf[0];
  183.         LedBuf[0]=Led_Pol;    //&#39;-&#39;
  184.     }else{
  185.         LedBuf[0]=Led_Pol;    //&#39;-&#39;
  186.     }
  187. }
  188. /*
  189. //---------------------------------------------------
  190. void JbDelay (void){
  191.     static long i;
  192.     if (++i>=OffLed){
  193.         P1=0xff;
  194.         P2=0xff;
  195.        PCON=0x02;
  196.     }
  197. }
  198. */
  199. /*****************************************************
  200. 主程序开始
  201. 1:2002_10_1 设计,采用DS18B20测量
  202. 2:采用函数数组读取DS18B20.LED数码管显示正常!
  203. 3:改变FHz可以用6,12MHz工作!
  204. ******************************************************/
  205. code unsigned char Stop[3] _at_ 0x3b;
  206. void main (void){
  207.     P1=0xff;
  208.     WenDu.WenDu=0;
  209.     while (1){
  210.         GetTemp();
  211.         GetBcd();        
  212. //        JbDelay();
  213.         LedOut();        
  214.     }
  215. }
复制代码

本帖子中包含更多资源

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

x
 楼主| 冰糖 发表于 2009-10-21 23:22:41 | 显示全部楼层
温度pcb.JPG (115.93 KB)
2009-10-12 10:55
温度计12.JPG (65.4 KB)
2009-10-12 10:55
温度计是.JPG (28.17 KB)
2009-10-12 10:55
 楼主| 冰糖 发表于 2009-10-21 23:23:35 | 显示全部楼层
  1. 测温的方法有许多。NTC也是常用!一段用NTC测温的程序,用AD采集,并计算。带数字滤波处理。
  2. #include    "use.h"
  3. #include    "Ver.H"
  4. #include    <math.h>
  5. #define        K_TEMP        (273.15)
  6. #define         NTC_R1        (10)        //25°C时的电阻值(10K)
  7. #define        NTC_T1        (25+K_TEMP)    //温度值
  8. #define        NTC_B        (3960)        //B值
  9. #define        Rm            (10)        //标准电阻值(单位k)
  10. /*************************************************************************
  11. B=(ln(r1)-ln(r2))/(1/t1-1/t2) t1=25c-->[273.15+25c]
  12. 1/t2=1/t1-(ln(r1)-ln(r2))/B
  13. **************************************************************************/
  14. float Count_NTC(float NTC_R2){
  15.     float idata i,j,r1,r2;
  16.     r1=log(NTC_R1);
  17.     r2=log(NTC_R2);
  18.     j=(r1-r2)/NTC_B;
  19.     i=1/NTC_T1-j;
  20.     j=1/i-K_TEMP;
  21.     return (j);
  22. }
  23. //****************************************************************************
  24. //计算温度值
  25. //****************************************************************************
  26. void NTC_GetTemp(void){
  27.     float idata u1,i1,r2;
  28.     u1=Get_Ad_U();                    //得到电压值
  29.     if(u1==0){
  30.         T_r=1;                    //故障!
  31.     }else{
  32.         T_r=0;
  33.         i1=u1/Rm;                //得到电流
  34.         r2=(MAX_U-u1)/i1;                //计算电阻
  35.         u1=Mp1.Cb+Count_NTC(r2);
  36.         if(fabs(u1-Mp1.C) >0.02) Mp1.C=u1;
  37.     }
  38. }
复制代码
 楼主| 冰糖 发表于 2009-10-21 23:24:07 | 显示全部楼层
NTC的计算公式
温度计算公式1.JPG (12.96 KB)
2009-10-12 11:08
温度公式.JPG (34.74 KB)
2009-10-12 11:08

还有一种方法是:利用RC充放电的方法,得到R值,也可以用此公式计算。查表也快!
longqishi 发表于 2010-9-29 21:01:47 | 显示全部楼层
这个测温的上限是多少度啊?
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则


--------------------------------------------------------------------------------------------------------------------
本站是工控技术交流站点,论坛内容均为网络收集或会员所发表,并不代表本站立场,会员拥有该内容的所有权力及责任!
本站内容如有侵犯您的版权,请按下面方式联系本站管理员,我们将及时删除处理
管理员:冰糖 QQ:5483695(请直击主题), Mail:admin#ziwai.net(#改成@) 其它非本人.
拒绝任何人以任何形式在本论坛发表与中华人民共和国法律相抵触的言论!

QQ|Archiver|手机版|小黑屋|紫外工控论坛. ( 苏ICP备11032118号-1 )

GMT+8, 2024-5-3 11:50 , Processed in 0.468753 second(s), 18 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

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