DS18B20数字温度计是DALLAS公司生产的1-Wire,即单总线器件,具有线路简单,体积小的特点。因此用它来组成一个测温系统,具有线路简单,在一根通信线,可以挂很多这样的数字温度计,十分方便。
1.DS18B20产品的特点
(1)只要求一个端口即可实现通信。
(2)在DS18B20中的每个器件都有独一无二的序列号。
(3)实际应用中不需要外部任何元器件即可实现测温。
(4)测量温度范围在-55℃到+125℃之间。
(5)数字温度计的分辨率用户可以从9位到12位选择。
(6)内部有温度上、下限告警设置。
由于DS18B20是在一根I/O线上读写数据,因此,对读写的数据位有着严格的时序要求。
DS18B20有严格的通信协议来保证各位数据传输的正确性和完整性。该协议定义了几种信号的时序:初始化时序、读时序、写时序。
所有时序都是将主机作为主设备,单总线器件作为从设备。而每一次命令和数据的传输都是从主机主动启动写时序开始,如果要求单总线器件回送数据,在进行写命令后,主机需启动读时序完成数据接收。
数据和命令的传输都是地位在线。
1、复位时序
2、写时序
对于DS18B20的写时序仍然分为写0时序和写1时序两个过程。对于DS18B20写0时序和写1时序的要求不同:
当要求写0时序时,单总线要被拉低至少60us,保证DS18B20能够在15us到45us之间能够正确地采用IO总线上的“0”电平;
当要写1时序时,单总线被拉低之后,在15us之内就得释放单总线。
3、读时序
对于DS18B20的读时序分为读0时序和读1时序两个过程。
对于DS18B20的读间隙是从主机把单总线拉低之后,在15秒之内就得释放单总线,以让DS18B20把数据传输到单总线上。DS18B20在完成一个读时序过程,至少需要60us才能完成。
4、操作程序
延时与复位实例
延时实例 | 复位实例 |
读位与写位实例
读位实例 | 写位实例 |
读字节与写字节实例
读字节实例 | 写字节实例 |
#实验
代码
* 【课程20】 ****DS18B20温度的读取***********
*
* 【说 明】 ****
*
* 【描 述】 ****读取环境温度
*
******************************************************************/
#include<reg51.h>
#include <intrins.h>
//---------常用的两个宏定义--------------
#define uint8 unsigned char
#define uint16 unsigned int
//--------1602的控制引脚定义-------------
sbit RS = P2^0;
sbit RW = P2^1;
sbit EN = P2^2;
sbit DQ = P3^3;
//----------液晶模块的声明---------------
bit BUSY(void);
void Write_cmd(uint8 cmd);
void Write_dat(uint8 dat);
void LCD_Init(void);
//---------DS18B20的函数声明-----------
void DelayUs(uint16 time);
void Init_Ds18b20(void);
void WriteByte(uint8 date);
uint8 ReadTemperature(void);
//-----------函数的声明------------------
void DelayMS(uint16 dly);
//------------------------------------
void main(void)
{
uint8 temp,temp1,temp2;
LCD_Init();
Init_Ds18b20();
while(1)
{
temp = ReadTemperature();
temp1 = temp/10;
temp2 = temp%10;
Write_cmd(0x80);
Write_dat(temp1+0x30);
Write_dat(temp2+0x30);
Write_dat(0xdf);
Write_dat(0x43);
}
}
/********************************************************
** 名称 :void DelayMS(uint16 dly)
** 功能 :毫秒级延时(12M的晶振)
** 入口参数 :dly
用户的延时参数
** 出口参数 :无
*********************************************************/
void DelayMS(uint16 dly)
{
uint16 x,y;
for(x=dly;x>0;x--)
for(y=124;y>0;y--);
}
/********************************************************
** 名称 :bit BUSY(void)
** 功能 :检测LCD1602是否处于忙状态;
** 入口参数 :无
** 出口参数 :bit Bit
返回1,则BUSY
返回0,则OK
*********************************************************/
bit BUSY(void)
{
bit Bit;
RS = 0;
RW = 1;
EN = 1;
DelayMS(1);
Bit = (bit)(P0 & 0x80); //最高位为忙信号位
EN = 0;
return Bit;
}
/********************************************************
** 名称 :void Write_cmd(uint8 cmd)
** 功能 :写命令
** 入口参数 :cmd
控制命令
** 出口参数 :无
*********************************************************/
void Write_cmd(uint8 cmd)
{
while(BUSY()); //测忙
RS = 0;
RW = 0;
EN = 0;
P0 = cmd;
EN = 1;
DelayMS(1);
EN = 0;
}
/********************************************************
** 名称 :void Write_dat(uint8 dat)
** 功能 :写数据
** 入口参数 :dat
要显示的数据
** 出口参数 :无
*********************************************************/
void Write_dat(uint8 dat)
{
while(BUSY()); //测忙
RS = 1;
RW = 0;
EN = 0;
P0 = dat;
EN = 1;
DelayMS(1);
EN = 0;
}
/********************************************************
** 名称 :void LCD_Init(void)
** 功能 :液晶的初始化
** 入口参数 :无
** 出口参数 :无
*********************************************************/
void LCD_Init(void)
{
Write_cmd(0x38); //功能设置
DelayMS(1);
Write_cmd(0x0c); //显示开关控制
DelayMS(1);
Write_cmd(0x06); //输入方式设置
DelayMS(1);
Write_cmd(0x01); //清除LCD的显示内容
DelayMS(1);
}
/**************************************
**Function Name:void DelayUs(uint time)
**Description:delay US
**Input:Time
**Output:None
**Return: None
**************************************/
void DelayUs(uint16 time)
{
while(time--);
}
/**************************************
**Function Name:void Init_Ds18b20(void)
**Description:DS18B20的初始化
**Input :None
**Output:None
**Return: None
**************************************/
void Init_Ds18b20(void)
{
uint8 i;
DQ=1; //首先DQ是高电平
DelayUs(15); //延时,等DQ稳定
DQ=0; //拉低
DelayUs(75); //延时大概600US
DQ=1; //拉高(释放)
DelayUs(15); //15US左右
i=DQ; //开始采样
DelayUs(7); //延时 (这个延时在仿真时很重要)
// return i //返回0, 说明总线上有器件响应
//返回1, 说明总线上没有器件响应
}
/**************************************
**Fuction Name:void WriteByte(uchar date)
**Description:写一个字节
**Input:Write Data Byte
**Output:None
**Return: None
**************************************/
void WriteByte(uint8 date)
{
uint8 i;
for(i=0;i<8;i++)
{
DQ=0;
DQ=date&0x01;
DelayUs(7);
DQ=1;
date>>=1;
}
DelayUs(7);
}
/**************************************
**Function Name:uchar ReadByte(void)
**Description:读一个字节
**Input:None
**Output:Read Data Byte
**Return: Read Data Byte
**************************************/
uint8 ReadByte(void)
{
uint8 i,value;
for(i=0;i<8;i++)
{
DQ=0;
value>>=1;
DQ=1;
if(DQ)
{
value|=0x80;
}
DelayUs(7);
}
return value;
}
/**************************************
**Function Name:uchar ReadTemperature(void)
**Description:读出温度值
**Input:None
**Output:Read Temperature
**Return: Read Temperature
**************************************/
uint8 ReadTemperature(void)
{
uint8 a,b;
Init_Ds18b20(); //初始化
WriteByte(0xcc); //跳过ROM
WriteByte(0x44); //启动转换
DelayUs(350);
Init_Ds18b20(); //初始化
WriteByte(0xcc); //跳过ROM
WriteByte(0xbe); //准备读取
a=ReadByte();
b=ReadByte();
b<<=4; //读温度的整数部分
b+=(a&0xf0)>>4;
return b;
}