打印

基于DS18B20的多点温度测试系统

[复制链接]
1652|27
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
jerow|  楼主 | 2020-3-30 21:54 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式
一、简介:

图示有字的一面,注意GND和VCC不要接反。工作电压3.0v~5.5V,采集温度-55度到正125度,可编程温度9-12位,精度分别是0.5度,0.25度,0.125度0.0625度,默认都是12位,12位转换时间是750ms,9位是93.75ms,电压负压特性(不会因电源接反发热烧坏)。



使用特权

评论回复
沙发
jerow|  楼主 | 2020-3-30 21:54 | 只看该作者
二、电路连接:

接一个上拉电阻。


使用特权

评论回复
板凳
jerow|  楼主 | 2020-3-30 21:55 | 只看该作者
三、通信方式:
单总线通信:
单总线是一种具有一个总线主机和一个或若干个从机的系统。严格按照器件的时间要求进行复位,写命令,读写数据等。整个过程在一条线上进行。


使用特权

评论回复
地板
jerow|  楼主 | 2020-3-30 21:56 | 只看该作者
四、DS18B20的内部结构:

64位光刻ROM,温度传感器,非易失性的温度报警触发器TH和TL,配置寄存器。出厂前ROM的排列是:开始8位产品类型标号(28H),接着48位是DS18B20全球唯一序列号,最后8位是前面56位的循环冗余校验码。
DS18B20存储器:

Byte0和Byte1分别存储温度寄存器的低字节和高字节,这两个字节是只读的。我们一般只操作这两个字节。



使用特权

评论回复
5
jerow|  楼主 | 2020-3-30 21:57 | 只看该作者
五、DS18B20的指令:
命令有两种,一种ROM的指令,一种暂存器的指令。


使用特权

评论回复
6
jerow|  楼主 | 2020-3-30 21:57 | 只看该作者
六、操作时序:
分为4个步骤:
1.复位:单片机发一个低电平给DS18B20,DS18B20返回一个低电平给单片机,完成唤醒握手。
2.发送ROM命令
3.发送暂存器指令
4.发送数据或接受数据

使用特权

评论回复
7
jerow|  楼主 | 2020-3-30 21:58 | 只看该作者
单个温度测试代码:
#include<All.h>
uchar xdata DS18B20_Buffer[2]=0;//保存温度的数据
void Delay500us()                //@24.000MHz
{
        unsigned char i, j;
        i = 16;
        j = 147;
        do
        {
                while (--j);
        } while (--i);
}
void Delay80us()                //@24.000MHz
{
        unsigned char i, j;
        _nop_();
        _nop_();
        i = 3;
        j = 123;
        do
        {
                while (--j);
        } while (--i);
}
void Delay60us()                //@24.000MHz
{
        unsigned char i, j;
        _nop_();
        i = 2;
        j = 220;
        do
        {
                while (--j);
        } while (--i);
}
void Delay10us()                //@24.000MHz
{
        unsigned char i;
        i = 78;
        while (--i);
}
void Delay2us()                //@24.000MHz
{
        unsigned char i;
        i = 14;
        while (--i);
}
/*********************************
* @函数名:DS18B20_Reset
* @描   述:复位
* @说   明:
* @参   数:无
* @返回值:无
*********************************/
void DS18B20_Reset()
{
    DS18B20_DQ=0;//总线拉低
        Delay500us();//保持500us
        DS18B20_DQ=1;//短暂拉高
        Delay80us();//80us

        //等待拉低
        Delay500us();//返回一个106us的低电平
        DS18B20_DQ=1;
        _nop_();//短暂拉高
        _nop_();
}
/*********************************
* @函数名:DS18B20_Write_Com
* @描   述:写寄存器指令
* @说   明:
* @参   数:dat 要写入的数据
* @返回值:无
*********************************/
void DS18B20_Write_Com(uchar com)
{
        uchar idata i;
        for(i=0;i<8;i++)
        {
      DS18B20_DQ=0;
           Delay10us();//先拉低15us
                _nop_();
                DS18B20_DQ=(bit)(com&0x01);//先发低位
                com>>=1;//移位
                Delay60us();//继续拉低15us
                DS18B20_DQ=1;//短暂拉高
                Delay2us();
        }
}
/*********************************
* @函数名:DS18B20_Read_Data
* @描   述:读数据
* @说   明:
* @参   数:无
* @返回值:dat  读出的数据
*********************************/
uchar DS18B20_Read_Data()
{
        uchar idata i,value;
        for(i=0;i<8;i++)
        {
         DS18B20_DQ=0;
                Delay10us();
                value>>=1;
         DS18B20_DQ=1;
                //Ds18B20会返回值。,无论是0还是1,都延迟15us
         Delay2us();
        //        Delay15us();//先拉低15us
                if(DS18B20_DQ)//是1
                        value|=0x80;//最低位
                Delay60us();
        }
return value;
}
/*********************************
* @函数名:DS18B20_Handle
* @描   述:温度处理
* @说   明:1. 复位 2.发送ROM命令 3.发送暂存器指令 读RAM 4.数据
* @参   数:无
* @返回值:无
*********************************/
void DS18B20_Handle()
{
        uchar xdata value_High,value_Low;
        float num;//保存小数
    DS18B20_Reset();//复位
        DS18B20_Write_Com(0xcc);//发送指令CCH,跳过ROM操作
        //DS18B20_Write_Com(0x33);//读64位ROM
        DS18B20_Write_Com(0x44);//发送指令44H,启动温度转换
        Delay10us();
        DS18B20_Reset();//复位
        DS18B20_Write_Com(0xcc);//发送指令CCH,跳过ROM操作
        DS18B20_Write_Com(0xbe);//发送指令BEH,读取9字节RAM数据的前两个数据
        Delay10us();
        value_Low=DS18B20_Read_Data();//先读低字节Byte0
        value_High=DS18B20_Read_Data();//高字节Byte1
       
        value_High<<=4;//整数的高3位
        value_High+=(value_Low&0xf0)>>4;//整数的低4位
        DS18B20_Buffer[0]=value_High;//整数
        num=(value_Low&0x0f)*0.0625;//小数
        DS18B20_Buffer[1]=(uchar)(num*100);//小数
}

使用特权

评论回复
8
jerow|  楼主 | 2020-3-30 22:00 | 只看该作者
多点测试:(两个)
步骤:
1.先读出每个传感器的唯一ROM序列;
/*********************************
* @函数名:DS18B20_Read_64Rom
* @描   述:读64位的ROM 唯一标识
* @说   明:
* @参   数:*buffer 读出的8个字节的数据
* @返回值:无
*********************************/
void DS18B20_Read_64Rom(uchar *buffer)
{
          uchar i;
    DS18B20_Reset();//复位
        DS18B20_Write_Com(0x33);//读64位ROM
        for(i=0;i<8;i++) //读取64个字节
         buffer[i]=DS18B20_Read_Data();
}

2.用两个数组存读出来的序列号:

3.写入ROm序列号,并启动转换温度:
/*********************************
* @函数名:DS18B20_Write_Rom
* @描   述:写64ROM
* @说   明:发送匹配ROM命令 0x55再写入8字节的ROM
* @参   数:*buffer 要发送的存放ROM的数组
* @返回值:无
*********************************/
void DS18B20_Write_Rom(uchar *buffer)
{
        uchar i;
   DS18B20_Write_Com(0x55); //ROM匹配
        for(i = 0;i < 8;i++)
        DS18B20_Write_Com(buffer[i]); //写入8个字节的ROM
}
/*********************************
* @函数名:DS18B20_Handle
* @描   述:温度处理
* @说   明:1. 复位 2.发送ROM命令 3.发送暂存器指令 读RAM 4.数据
* @参   数:无
* @返回值:无
*********************************/
void DS18B20_Handle(uchar *buffer)
{
        uchar xdata value_High,value_Low;
        float num;//保存小数
    DS18B20_Reset();//复位
        //DS18B20_Write_Com(0xcc);//发送指令CCH,跳过ROM操作
        //DS18B20_Write_Com(0x33);//读64位ROM
    DS18B20_Write_Rom(buffer); //匹配ROM 并写入64ROM
        DS18B20_Write_Com(0x44);//发送指令44H,启动温度转换
        Delay10us();
        DS18B20_Reset();//复位
         DS18B20_Write_Rom(buffer); //匹配ROM 并写入64ROM
        DS18B20_Write_Com(0xbe);//发送指令BEH,读取9字节RAM数据的前两个数据
        Delay10us();
        value_Low=DS18B20_Read_Data();//先读低字节Byte0
        value_High=DS18B20_Read_Data();//高字节Byte1
       
        value_High<<=4;//整数的高3位
        value_High+=(value_Low&0xf0)>>4;//整数的低4位
        DS18B20_Buffer[0]=value_High;//整数
        num=(value_Low&0x0f)*0.0625;//小数
        DS18B20_Buffer[1]=(uchar)(num*100);//小数
}


使用特权

评论回复
9
jerow|  楼主 | 2020-3-30 22:02 | 只看该作者
其他的都和单个测试是一样的。
测试结果:

另外附上主函数:
/*********************************
* @函数名:main
* @描   述:main函数,程序入口
* @说   明:
* @参   数:无
* @返回值:无
*********************************/
void main()
{
        //uchar a[8];//存放读出来的ROM
        Uart1_Init();//串口初始化
        Send_String("多点温度测试:\n");
  while(1)
        {
            DS18B20_Handle(DS18B20_Rom1);
                printf("温度1:%bd.%bd",DS18B20_Buffer[0],DS18B20_Buffer[1]);//串口打印温度
        putchar_End();//换行
//                DS18B20_Read_64Rom(a);
//                Send_String(a);
            Delay1000ms();
                DS18B20_Handle(DS18B20_Rom2);
                printf("温度2:%bd.%bd",DS18B20_Buffer[0],DS18B20_Buffer[1]);//串口打印温度
                Delay1000ms();
                 putchar_End();//换行
        }
}

使用特权

评论回复
10
paotangsan| | 2020-4-7 14:12 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
11
renzheshengui| | 2020-4-7 14:12 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
12
wakayi| | 2020-4-7 14:12 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
13
wowu| | 2020-4-7 14:12 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
14
xiaoqizi| | 2020-4-7 14:12 | 只看该作者
非常感谢楼主分享

使用特权

评论回复
15
iot123| | 2020-12-17 17:14 | 只看该作者
请问楼主的程序是在什么硬件和软件环境下运行的?

使用特权

评论回复
16
ktdm1314| | 2022-3-16 13:50 | 只看该作者
value值?
从哪来的?

使用特权

评论回复
17
billzhang331| | 2022-3-18 12:05 | 只看该作者
本帖最后由 billzhang331 于 2022-3-18 12:07 编辑

有个问题,如果多个18B20接入同一网络,如何识别?
如果需要接入前单个读出ID,再修改主站程序,是否太麻烦?客户更换备品备件时操作步骤太多了

使用特权

评论回复
18
天意无罪| | 2022-3-19 18:10 | 只看该作者
这年头还有用DS1302来测温得吗?现在主要都是硅基传感器测温了.

使用特权

评论回复
19
sparrow054| | 2022-4-1 15:15 | 只看该作者
不知道一致性和可靠性怎么样

使用特权

评论回复
20
zps136631| | 2022-4-2 16:20 | 只看该作者
多谢分享!

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

72

主题

520

帖子

3

粉丝