提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
DS18B20简介
DS18B20 是美信公司的一款温度传感器,单片机可以通过 1-Wire 协议与 DS18B20 进行通信,最终将温度读出。1-Wire 总线的硬件接口很简单,只需要把 DS18B20 的数据引脚和单片机的一个 IO 口接上就可以了。硬件的简单,随之而来的,就是软件时序的复杂。该温度传感器对时间的精确要求较高。我们所需要用到的功能不多……
DS18B20主要由4部分组成:64 位ROM、温度传感器、非挥发的温度报警触发器TH和TL、配置寄存器。ROM中的64位序列号是出厂前被光刻好的,它可以看作是该DS18B20的地址序列码,每个DS18B20的64位序列号均不相同。64位ROM的排的循环冗余校验码(CRC=X8+X5+X^4+1)。 ROM的作用是使每一个DS18B20都各不相同,这样就可以实现一根总线上挂接多个DS18B20的目的(单片机不需要进行ROM匹配)。
DS18B20采集完温度后,数据以2个字节的形式储存在寄存器中,其中S为符号位
要检测这条总线上是否存在 DS18B20这个器件。如果这条总线上存在 DS18B20,总线会根据时序要求返回一个低电平脉冲,如果不存在的话,也就不会返回脉冲,即总线保持为高电平,所以习惯上称之为检测存在脉冲。此外,获取存在脉冲不仅仅是检测是否存在 DS18B20,还要通过这个脉冲过程通知 DS18B20准备好,单片机要对它进行操作了。
实粗线是我们的单片机 IO 口拉低这个引脚,虚粗线是 DS18B20 拉低这个引脚,细线是单片机和 DS18B20 释放总线后,依靠上拉电阻的作用把 IO 口引脚拉上去。51 单片机释放总线就是给高电平。
具体操作时序为:单片机拉低IO口-----单片机拉高-----检测IO口是否有低电平返回
代码
onewire.h
代码如下:
#ifndef __ONEWIRE_H
#define __ONEWIRE_H
#include "reg52.h"
sbit DQ = P1^4; //单总线接口
unsigned char Read_DS18B20(void);
bit init_ds18b20(void);
void Write_DS18B20(unsigned char dat);
unsigned int temper_change();
#endif
onewire.c
代码如下:
#include "onewire.h"
//单总线延时函数
void Delay_OneWire(unsigned int t) //STC89C52RC
{
while(t--);
}
//通过单总线向DS18B20写一个字节
void Write_DS18B20(unsigned char dat)
{
unsigned char i;
for(i=0;i<8;i++)
{
DQ = 0;
DQ = dat&0x01;
Delay_OneWire(5);
DQ = 1;
dat >>= 1;
}
Delay_OneWire(5);
}
//从DS18B20读取一个字节
unsigned char Read_DS18B20(void)
{
unsigned char i;
unsigned char dat;
for(i=0;i<8;i++)
{
DQ = 0;
dat >>= 1;
DQ = 1;
if(DQ)
{
dat |= 0x80;
}
Delay_OneWire(5);
}
return dat;
}
//DS18B20设备初始化
bit init_ds18b20(void)
{
bit initflag = 0;
DQ = 1;
Delay_OneWire(12);
DQ = 0;
Delay_OneWire(80);
DQ = 1;
Delay_OneWire(10);
initflag = DQ;
Delay_OneWire(5);
return initflag;
}
需要我们自己写一个读取数值以及处理数值的函数
//读取温度的集体操作
unsigned int temper_change()
{
unsigned char TH,TL,Temp;
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0x44);
init_ds18b20();
Write_DS18B20(0xcc);
Write_DS18B20(0xbe);
TL=Read_DS18B20();
TH=Read_DS18B20();
Temp=(TH<<4)|(TL>>4);
return Temp;
}
总结
在main函数中进行调用就可以了temp = temper_change();