51单片机系列——单总线通信方式——DS18B20温度检测的设计

发布者:花开堂前最新更新时间:2021-12-24 来源: eefocus关键字:51单片机系列  单总线  通信方式  DS18B20  温度检测 手机看文章 扫描二维码
随时随地手机看文章

这个电路仿真的原理是因为:根据普中科技上的编程(一模一样),但用proteus7.8仿真的时候却仿真不出来,经过小编的一段时间的思考解决了用软件仿真DS18B20温度检测的电路。我先讲仿真电路图与源码分享给大家。


仿真电路图:
图1

temp.h //温度检测模块头文件


#ifndef __TEMP_H_

#define __TEMP_H_


#include

//---重定义关键词---//

#ifndef uchar

#define uchar unsigned char

#endif


#ifndef uint 

#define uint unsigned int

#endif


//--定义使用的IO口--//

sbit DSPORT=P3^7;


//--声明全局函数--//

void Delay1ms(uint );

uchar Ds18b20Init();

void Ds18b20WriteByte(uchar com);

uchar Ds18b20ReadByte();

void  Ds18b20ChangTemp();

void  Ds18b20ReadTempCom();

int Ds18b20ReadTemp();


#endif


temp.c //温度检测模块的驱动函数库文件


#include"temp.h"

#include


/*******************************************************************************

* 函 数 名         : Delay1ms

* 函数功能     : 延时函数

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/

void Delay1ms(uint y)  

{

 uint x;

 for( ; y>0; y--)

 {

  for(x=110; x>0; x--);

 }

}

/*延时500us函数*/

void delay500us(void)   //误差 0us

{

    unsigned char a,b;

    for(b=71;b>0;b--)

        for(a=2;a>0;a--);

}

/*延时80us函数*/

void delay80us(void)   //误差 0us

{

    unsigned char a,b;

    for(b=11;b>0;b--)

        for(a=2;a>0;a--);

}

/*延时48us函数*/

void delay48us(void)   //误差 0us

{

    unsigned char a,b;

    for(b=9;b>0;b--)

        for(a=1;a>0;a--);

}

/*延时6us函数*/

void delay6us(void)   //误差 0us

{

    unsigned char a;

    for(a=1;a>0;a--);

    _nop_();  //if Keil,require use intrins.h

}



/*******************************************************************************

* 函 数 名         : Ds18b20Init

* 函数功能     : 初始化

* 输    入         : 无

* 输    出         : 初始化成功返回1,失败返回0

*******************************************************************************/

uchar Ds18b20Init()

{

 uchar i;

 DSPORT = 0;    //将总线拉低480us~960us

    delay500us();

 DSPORT = 1;   //然后拉高总线,如果DS18B20做出反应会将在15us~60us后总线拉低

 i = 0;

 while(DSPORT) //等待DS18B20拉低总线

 {

  delay80us();

  i++;

  if(i>5)//等待>5MS

  {

   return 0;//初始化失败

  }

 

 }

 return 1;//初始化成功

}


/*******************************************************************************

* 函 数 名         : Ds18b20WriteByte

* 函数功能     : 向18B20写入一个字节

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/

void Ds18b20WriteByte(uchar dat)

{

 uint i, j;

 for(j=0; j<8; j++)

 {

  DSPORT = 0;         //每写入一位数据之前先把总线拉低1us

  i++;

  DSPORT = dat & 0x01;  //然后写入一个数据,从最低位开始

  delay80us();

  DSPORT = 1; //然后释放总线,至少1us给总线恢复时间才能接着写入第二个数值

  dat >>= 1;

 }

}


/*******************************************************************************

* 函 数 名         : Ds18b20ReadByte

* 函数功能     : 读取一个字节

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/

uchar Ds18b20ReadByte()

{

 uchar byte, bi;

 uint i, j; 

 for(j=8; j>0; j--)

 {

  DSPORT = 0;//先将总线拉低1us

  i++;

  DSPORT = 1;//然后释放总线

     delay6us();   //误差 0us

  bi = DSPORT;  //读取数据,从最低位开始读取

  /*将byte左移一位,然后与上右移7位后的bi,注意移动之后移掉那位补0。*/

  byte = (byte >> 1) | (bi << 7);        

  delay48us();   //误差 0us

  DSPORT = 1;

 }    

 return byte;

}


/*******************************************************************************

* 函 数 名         : Ds18b20ChangTemp

* 函数功能     : 让18b20开始转换温度

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/

void  Ds18b20ChangTemp()

{

 Ds18b20Init();

 Delay1ms(1);

 Ds18b20WriteByte(0xcc);  //跳过ROM操作命令   

 Ds18b20WriteByte(0x44);     //温度转换命令

 //Delay1ms(100); //等待转换成功,而如果你是一直刷着的话,就不用这个延时了  

}


/*******************************************************************************

* 函 数 名         : Ds18b20ReadTempCom

* 函数功能     : 发送读取温度命令

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/

void  Ds18b20ReadTempCom()

 Ds18b20Init();

 Delay1ms(1);

 Ds18b20WriteByte(0xcc);  //跳过ROM操作命令

 Ds18b20WriteByte(0xbe);  //发送读取温度命令

}


/*******************************************************************************

* 函 数 名         : Ds18b20ReadTemp

* 函数功能     : 读取温度

* 输    入         : 无

* 输    出         : 无

*******************************************************************************/

int Ds18b20ReadTemp()

{

 int temp = 0;

 uchar tmh, tml;

 Ds18b20ChangTemp();     //先写入转换命令

 Ds18b20ReadTempCom();   //然后等待转换完后发送读取温度命令

 tml = Ds18b20ReadByte();  //读取温度值共16位,先读低字节

 tmh = Ds18b20ReadByte();  //再读高字节

 temp = tmh;

 temp <<= 8;

 temp |= tml;

 return temp;

}


main.c //主函数


/**************************************************************************************

*                DS18B20温度传感器实验              *

实现现象:下载程序后,在温度传感器接口处,按照丝印方向插好温度传感器,数码管就会显示

   检测的温度值,

注意事项:                      

***************************************************************************************/


#include "reg52.h"    //此文件中定义了单片机的一些特殊功能寄存器

#include"temp.h" 


typedef unsigned int u16;   //对数据类型进行声明定义

typedef unsigned char u8;


sbit LSA=P2^2;

sbit LSB=P2^3;

sbit LSC=P2^4;


char num=0;

u8 DisplayData[8];

u8 code smgduan[10]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};


/*******************************************************************************

* 函 数 名         : delay

* 函数功能     : 延时函数,i=1时,大约延时10us

*******************************************************************************/

void delay(u16 i)

{

 while(i--); 

}


/*******************************************************************************

* 函 数 名         : datapros()

* 函数功能     : 温度读取处理转换函数

* 输    入         : temp

* 输    出         : 无

*******************************************************************************/

void datapros(int temp)   

{

    float tp;  

 if(temp< 0)    //当温度值为负数

   {

  DisplayData[0] = 0x40;    //   -

  //因为读取的温度是实际温度的补码,所以减1,再取反求出原码

  temp=temp-1;

  temp=~temp;

  tp=temp;

  temp=tp*0.0625*100+0.5; 

  //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点

  //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就

  //算加上0.5,还是在小数点后面。

 

   }

  else

   {   

  DisplayData[0] = 0x00;

  tp=temp;//因为数据处理有小数点所以将温度赋给一个浮点型变量

  //如果温度是正的那么,那么正数的原码就是补码它本身

  temp=tp*0.0625*100+0.5; 

  //留两个小数点就*100,+0.5是四舍五入,因为C语言浮点数转换为整型的时候把小数点

  //后面的数自动去掉,不管是否大于0.5,而+0.5之后大于0.5的就是进1了,小于0.5的就

  //算加上0.5,还是在小数点后面。

 }                

 DisplayData[1] = smgduan[temp / 10000];

 DisplayData[2] = smgduan[temp % 10000 / 1000];

 DisplayData[3] = smgduan[temp % 1000 / 100] | 0x80;

 DisplayData[4] = smgduan[temp % 100 / 10];

 DisplayData[5] = smgduan[temp % 10];

}


/*******************************************************************************

* 函数名         :DigDisplay()

* 函数功能   :数码管显示函数

* 输入           : 无

* 输出           : 无

*******************************************************************************/

void DigDisplay()

{

 u8 i;

 for(i=0;i<6;i++)

 {

  switch(i)  //位选,选择点亮的数码管,

  {

   case(0):

    LSA=0;LSB=0;LSC=0; break;//显示第0位

   case(1):

    LSA=1;LSB=0;LSC=0; break;//显示第1位

   case(2):

    LSA=0;LSB=1;LSC=0; break;//显示第2位

   case(3):

    LSA=1;LSB=1;LSC=0; break;//显示第3位

   case(4):

    LSA=0;LSB=0;LSC=1; break;//显示第4位

   case(5):

    LSA=1;LSB=0;LSC=1; break;//显示第5位 

  }

  P0=DisplayData[5-i];//发送数据

  delay(100); //间隔一段时间扫描 

  P0=0x00;//消隐

 }  

}


/*******************************************************************************

* 函 数 名       : main

* 函数功能   : 主函数

* 输    入       : 无

* 输    出      : 无

*******************************************************************************/

void main()

 while(1)

 {

  datapros(Ds18b20ReadTemp());  //数据处理函数

  DigDisplay();//数码管显示函数  

 }  

}


仿真后的结果:下图分别是显示正数/负数温度:

图2
图3

为什么用普中科技的程序在仿真软件上显示的结果就不理想呢?
小编经过反复的软件仿真验证发现:软件仿真时对时序的要求极高,例如在编程DS18B20的读写函数和初始化函数时,它们的时序应满足下图:
图4
图5
图6

从三张图中看出需要延时函数的处理。


**结论:**普中科技在编写读写和初始化函数时,延时大都通过while(i){i–;}或几个i++,来完成延时的,如果你尝试使用一下Debug调试一下,会发现这种延时并不准确,相差还很大。在硬件实战时这种不准确的延时也许影响不大(有时候可能还需要这样的做)。

[1] [2]
关键字:51单片机系列  单总线  通信方式  DS18B20  温度检测 引用地址:51单片机系列——单总线通信方式——DS18B20温度检测的设计

上一篇:51单片机系列——I2C通信方式——24C02(E2PROM)的应用
下一篇:51单片机实验1——数码管显示串行口接收的字符的ASCII码

推荐阅读最新更新时间:2024-11-20 15:43

基于GSM的远程智能温控系统
    本系统是根据日常生活汽车用户反应,当夏天太阳猛烈时,停放于太阳之下的汽车车内温度过高,致使车主进入车内驾驶时感觉车内空气闷热所设计的。该系统利用GSM远程通信系统控制车内空调等器械运作。用户通过短信形式达到人机互动,克服红外线、无线等远程控制距离短的问题,还可以实现实时监控汽车的状态,为车主提供便利。 1 系统原理与结构 1.1 系统功能介绍     本系统能以10次/s的速度自动采集现场的环境温度和光照强度、采集空调和窗帘的开闭状态,并通过LCD液晶屏实时地显示出来。温度的感应范围-55~+125℃,精度为±0.5℃。光强的强度范围分为强、较强、中、较弱、弱5档。空调和窗帘的状态为开或者关。     用户可以通过手机或者小
[嵌入式]
51单片机系列之串口
---------------------------------------------------- 名称:51单片机自带串口 平台:Keil 4, Ly-51S学习板 引脚定义如下:RXD TXD MAX232与51连接:TXD-T1IN RXD-R1OUT -----------------------------------------------------*/ #include reg52.h /*串口初始化*/ void UART_init() { SCON = 0x50; // SCON: 模式 1, 8-bit UART, 使能接收 TMOD |= 0x20;
[单片机]
基于NTC热敏电阻的LED闪光基板的温度检测
NTC热敏电阻是一种热阻元件,其阻值会随温度升高而急剧下降。利用这一特性,它除了可以被设计为温度传感器以外,还被用作温度保护元件以防止电路过热。通过将NTC热敏电阻安装在靠近热源的位置上,可以准确检测热源温度。但由于基板尺寸和PCB布线等限制,有时也需要将其安装在远离热源的位置。 本期推文中,我们假设了一种LED和NTC热敏电阻安装位置不同而导致的测量温差的情况,并确认了基板厚度的影响,然后对其结果进行说明。 通过将NTC热敏电阻安装在靠近热源的位置,可实现精确的热源温度检测。但由于基板尺寸和PCB布线等限制,有时也需要将其安装在远离热源的位置。我们使用发热模拟软件,假设了将LED闪烁灯基板的LED作为热源来确认由于LED
[测试测量]
基于NTC热敏电阻的LED闪光基板的<font color='red'>温度检测</font>
单总线单片机多机通讯系统设计
    摘要: 提出了用单总线完成单片机通讯的方法。结合系统既传输数字信号又传输模拟信号的特点,提出用消侧音电路解决模拟信号的方案,并给出了详细的技术解决方案。     关键词: 单总线 单片机 电源隔离 消侧音 传统的多机通讯系统一般需要四条线完成:1.电源线;2.地线;3.发送信号线;4.接收信号线。然而,对于主机和分机距离较远、分机台数较多的系统,采用四线制的经费投入较大,安装起来也颇困难。基于这一问题,本文结合为某医院研制的既有模拟信号(语音)又有数字信号的传输呼叫系统,提出用单总线实现多机通讯,并给出了一个完整的技术方案。 1 单总线制多机通讯系统的总线设计方案 本设计实现的多机呼叫系
[应用]
通信开关电源整流器几种常用散热方式
  通信开关电源冷却技术的设计首先要是满足行业各项技术性能要求。为更加适应通信机房的特殊环境使用环境,要求其冷却方式对环境温度变化适应性强。目前整流器常用的冷却方式有自然冷却、纯风扇冷却、自然冷却和风扇冷却相结合三种。自然冷却具有无机械故障,可靠性高;无空气流动,灰尘少,有利于散热;无噪音等特点。纯风扇冷却具有设备重量轻,成本低。风扇和自然冷却相结合的技术具有有效减小设备体积和重量,风扇的使用寿命高,风扇故障自适应能力强等特点。   1、自然冷却   自然冷却方式是开关电源早期的传统冷却方式,这种方式主要是依靠大的金属散热器来进行直接的热传导式散热。换热量Q=KA△t(K换热系数,A换热面积,△t温度差)。当整流器输出功率增大
[电源管理]
DS18B20的使用程序PIC单片机
#include pic.h __CONFIG(0x1832); //芯片配置字,看门狗关,上电延时开,掉电检测关,低压编程关,加密,4M晶体HS振荡 #define uch unsigned char //给unsigned char起别名 uch # define DQ RA2 //定义18B20数据端口 # define DQ_DIR TRISA2 //定义18B20D口方向寄存器 # define DQ_HIGH() DQ_DIR =1 //设置数据口为输入 # define DQ_LOW() DQ = 0; D
[单片机]
AVR M16 8M 的DS18B20头文件
只需调用gettemp();就可以了!出口参数wmh是显示的高位,wml使显示的低位,然后调用你的显示程序就可以了! /************************************************************************* ds18b20头文件 M16 内部8M *************************************************************************/ #define CLR_DIR_1WIRE DDRC&=~BIT(2) //只要修改这里的参数就可以了!呵呵! #define SET_DIR_1WIRE
[单片机]
基于单总线数字温度传感器DS18B20的测温系统设计
0 引言 温度是基本物理量之一,是工农业生产和日常生活中经常需要测试的重要参数,温度测量亦是应用频率最高的技术之一,在粮食仓库存储、环境监测、过程温度监测、中央空调监测、医学体温检测等领域有着广泛应用。传统的温度检测方式一般采用热电偶或热敏电阻,输出模拟信号,经A/D转换后才能送入单片机处理器,检测电路复杂。 因此,本文采用单总线智能型数字温度传感器DS18B20,以AT89C51单片机为核心处理器,进行测温系统设计,在Proteus环境中进行系统硬件设计,并结合软件进行了仿真,降低了开发成本,提高了开发效率。 1 DS18B20传感器特性与控制时序 DS18B20是美国DALLAS半导体公司的单总线智能型数字温度传
[单片机]
基于<font color='red'>单总线</font>数字温度传感器<font color='red'>DS18B20</font>的测温系统设计
小广播
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved