4 7
您的位置: 电子制作DIY -> 单片机 -> 51单片机 -> 基于51单片机控制的DS18B20数字温度系统
本帖共有693个阅读者
发表帖子 发表投票 回复主题
基于51单片机控制的DS18B20数字温度系统
尊贵身份标志
wujinlin(VIP会员)
wujinlin
头衔:社区公民
帮派:无帮无派
帖数:26
金钱:380
积分:112
注册时间:2020/12/30
楼主信息 | 留言 | Email | 主页 | 编辑 | 管理 | 离线
基于51单片机控制的DS18B20数字温度系统
本文主要介绍了一个基于 AT89C51单片机的测温系统,详细描述了利用数字温度传感器 DS18B20 开发测温系统的过程。对采集的信息都希望用最直接的方式显示出来,但是传感器所采集的信息是模拟的信号,并且信号是非常微小的,需要用放大器进行放大。模拟信号不能直接用数字仪器直接显示,通过模数转换之后就可以将模拟量转变成数字量,在通过数码管进行显示。有些可以直接与单片机链接。数码管有共阳极与共阴极两类,本次设计采用的是共阴极的七段数码管。  设计要求:利用数字温度传感器 DS18B20 与单片机结合来测量温度。利用数字 温度传感器 DS18B20 测量温度信号,计算后在 LED 数码管上显示 相应的温度值。其温度测量范围为−55℃~125℃,精确到 0.5℃;实 现超限报警  DS18B20 数字温度计是 DALLAS 公司生产的 1-Wire ,即单总线器件,具有线路简单、体积小的特点。因此用它来组成一个测温系统,线路简单,在一根通信线上,可以挂很多这样的数字温度计,十分方便。 DS18B20 是美国DALLAS 公司新推出的一种可组网数字式温度传感器,与 DS1820 相似,DS18B20 也能够直接读取被测物体的温度值。但是与 DS1820 相比, DS18B20 的功能更强大些。它体积小,电压适用范围宽( 3--5V ),用户还可以通过编程实现 9--12 位精度的温度读数,即具有可调的温度分辨率,因此它的实用性和可靠性比同类产品更高。
总原理图:

  20211411573626.png [ 101.22 KB 1522×793 ] (缩略时请点击查看原图)

 
C程序源代码:
#include<reg51.h>
#include<intrins.h>
sbit DQ=P1^7;           //定义DS18B20的接受端口
sbit p0_7=P0^7;
sbit p3_0=P3^0;                //以下五个端口为按钮
sbit p3_1=P3^1;
sbit p3_2=P3^2;
sbit p3_3=P3^3;
sbit p3_4=P3^4;
sbit p1_0=P1^0;
#define uchar unsigned char
#define uint  unsigned int        
void yanshi(int );                            //普通延时函数
void jinyan(int );                          //  精确延时
void yan_us        (uchar);                   // us级延时
bit chushi(void);                           // DS18B20通信初始化
void xie(uchar );                           //  向DS18B20写数据
uint du(void);                                   //  读取DS18B20的数据
float chuli(uint);                           // 处理DS18B20返回的数据
void xianshi(float);                  //  数码管显示函数
uchar biao[12]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x39,0x71};//        数码管0-9 的显示数据
bit huan=1;

void main(void){
        uint ab=0;
        float ac=0;
        char shang=50;
        char xia  =10;
        int bian=0;
    DQ=1;
        p3_0=1;
        p3_1=1;
        p3_2=1;
        p3_3=1;
        p3_4=1;
        TMOD=0x01;
        EA=0;
        ET0=0;
while(1){
        if((ab==1)&&chushi()){                //         向DS18B20发送转换温度指令
         yan_us(100);
         xie(0xcc);
         xie(0x44);
        }
        if((DQ==1)&&(ab==500)&&chushi()){         //接受DS18B20的数据
         yan_us(100);
         xie(0xcc);
         xie(0xbe);
         ac=chuli(du());
         ab=0;
        }
        ab++;
        xianshi(ac);                                         //         显示DS18B20的温度数据
        if(p3_4==0){                                         //         切换温度显示方式C  F
                huan=~huan;
                while(!p3_4);
        }                                                                
        if(p3_0==0){                                                //调整上限增加
         bian=0;
         while(!p3_0){
          if(bian==200){
          shang++;
          bian=0;
          }
          bian++;
          xianshi(shang);
         }
        }
        if(p3_1==0){                                 //                调整上限减少
         bian=0;
         while(!p3_1){
          if(bian==200){
          shang--;
          bian=0;
          }
          bian++;
          xianshi(shang);
         }
        }
        if(p3_2==0){                                //          调整下限增加
         bian=0;
         while(!p3_2){
          if(bian==200){
          xia++;
          bian=0;
          }
          bian++;
          xianshi(xia);
         }
        }
        if(p3_3==0){                                 //           调整下限减少
         bian=0;
         while(!p3_3){
          if(bian==200){
          xia--;
          bian=0;
          }
          bian++;
          xianshi(xia);
         }
        }
        if(ac<xia||ac>shang)                   // 判断温度示数是否超上下限
                p1_0=1;
        else
                p1_0=0;
}

}

void yanshi(int a){
int b;
while(a--){
for(b=0;b<110;b++);
}

}

void jinyan(int a){
TH0=(65536-a)/256;
TL0=(65536-a)%256;
TR0=1;
while(!TF0);
TF0=0;
TR0=0;
}

void yan_us(uchar a){
while(a--);
}

bit chushi(void){
uchar a=0;
DQ=0;
yan_us(100);
DQ=1;
while(DQ){
if(a==200)
return 0;
a++;
}
a=0;
while(!DQ){
if(DQ==250)
return 0;
a++;
}
return 1;
}

void xie(uchar a){
char b;
bit c;
for(b=0;b<8;b++){
c=a&0x01;
if(c){
DQ=0;
_nop_();
_nop_();
DQ=1;
yan_us(13);
}
else  {
DQ=0;
yan_us(13);
DQ=1;
}
a=a>>1;
}
}

uint du(void){
uint a=0,b=0;
bit c=0;
char d;
for(d=0;d<16;d++){
DQ=0;
_nop_();
_nop_();
DQ=1;
_nop_();
_nop_();
_nop_();
c=DQ;
b=c;
b=b<<d;
a=a|b;
b=0;
yan_us(9);
}
DQ=0;
yanshi(2);
DQ=1;
return a;
}
float chuli(uint a){
float b;
if(a>=32768){
a=~a;
a++;
b=(float)a;
b=b/(-16);
}
else  {
b=(float)a;
b=b/16;
}
return b;
}
void xianshi(float a){
uint b,c;
if(!huan)
        a=32+a*1.8;
if(a<0){
        a=a*(-1);
        b=(uint)a;
        a=(a-b)*10;
        c=(uint)a;
        P2=0x00;
        P0=0x40;
        P0=0x00;
}
else{
        b=(uint)a;
        a=(a-b)*10;
        c=(uint)a;
}
P2=0x01;
P0=biao[b/100];
P0=0x00;
P2=0x02;
P0=biao[(b/10)%10];
P0=0x00;
P2=0x03;
P0=biao[b%10];
p0_7=1;
P0=0x00;
P2=0x04;
P0=biao[c];
P0=0x00;
P2=0x05;
if(huan)
        P0=biao[10];
else
        P0=biao[11];
P0=0x00;
}
仿真图:

  2021141223826.png [ 105.59 KB 1527×792 ] (缩略时请点击查看原图)

 

  2021141232726.png [ 105.26 KB 1509×795 ] (缩略时请点击查看原图)

 




「该帖子被 wujinlin 在 2021/1/4 12:48:01 编辑过」

这家伙很懒,什么也没有留下!
等级:VIP会员 参考IP地址:*.*.*.*
2021/1/4 12:04:17
Copyright © 2011 电子制作DIY. All rights reserved.电子制作DIY8028 Call, 1 Queries, Processed in 64.453 millisecond(2),