温度传感器---DS18B20
1. DS18B20是一种常见的数字温度传感器,具有功能强大、硬件简单、易扩展、抗干扰性强等特点;
测温范围:-55℃------+125℃ 通讯接口:1-Wire(单总线) 特点:可形成总线结构、内置温度报警功能、可寄生供电;
2.单总线协议:1-Wire
设备的DQ均要配置成开漏输出模式;DQ添加一个上拉电阻,阻值一般为4.7K左右;(同I2C协议)
初始化:主机拉低,然后释放总线,等待15-60us,从机响应,从机拉低,然后释放总线(因为是单总线协议,所以不 能用I2C的高低电平来表示)
发送一位:主机将总线拉低60-120us,然后释放总线,表示发送0;主机将总线拉低1-15us,然后释放总线,表示发送1;从机将在主机拉低30us(典型值)以后读取电平,整个时间片应大于60us;
接收一位:主机将总线拉低1-15us,然后释放总线, 并在拉低后15us内读取总线电平,读取为低电平则为0,读取为高电平则为1,整个时间片应大于60us;
发送一个字节:连续调用8次发送一位的时序,依次发送一个字节的8位(低位在前-----区分I2C总线高位在前)
接收一个字节:连续调用8次接收一位的时序,依次接收一个字节的8位(低位在前)
温度存储格式: 高位前5位是符号位,0表示正数,1表示负数;中间位是温度的表示方法,最后四位是小数,BIT3=0.5,BIT2=0.25,BIT1=0.125,BIT0=0.0625;
功能指令:
温度读取:
main.c
#include <REGX52.H>
#include "LCD1602.h"
#include "DS18B20.h"
#include "Delay.h"float T;void main()
{DS18B20_ConvertT(); //上电先转换一次温度,防止第一次读数据错误Delay(1000); //等待转换完成LCD_Init();LCD_ShowString(1,1,"Temperature:");while(1){DS18B20_ConvertT(); //转换温度T=DS18B20_ReadT(); //读取温度if(T<0) //如果温度小于0{LCD_ShowChar(2,1,'-'); //显示负号T=-T; //将温度变为正数}else //如果温度大于等于0{LCD_ShowChar(2,1,'+'); //显示正号}LCD_ShowNum(2,2,T,3); //显示温度整数部分LCD_ShowChar(2,5,'.'); //显示小数点LCD_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);//显示温度小数部分}
}
DS18B20.c
#include <REGX52.H>
#include "OneWire.h"//DS18B20指令
#define DS18B20_SKIP_ROM 0xCC
#define DS18B20_CONVERT_T 0x44
#define DS18B20_READ_SCRATCHPAD 0xBE/*** @brief DS18B20开始温度变换* @param 无* @retval 无*/
void DS18B20_ConvertT(void)
{OneWire_Init();OneWire_SendByte(DS18B20_SKIP_ROM);OneWire_SendByte(DS18B20_CONVERT_T);
}/*** @brief DS18B20读取温度* @param 无* @retval 温度数值*/
float DS18B20_ReadT(void)
{unsigned char TLSB,TMSB;int Temp;float T;OneWire_Init();OneWire_SendByte(DS18B20_SKIP_ROM);OneWire_SendByte(DS18B20_READ_SCRATCHPAD);TLSB=OneWire_ReceiveByte();TMSB=OneWire_ReceiveByte();Temp=(TMSB<<8)|TLSB;T=Temp/16.0;return T;
}
DS18B20.h
#ifndef __DS18B20_H__
#define __DS18B20_H__void DS18B20_ConvertT(void);
float DS18B20_ReadT(void);#endif
Onewire.c
#include <REGX52.H>//引脚定义
sbit OneWire_DQ=P3^7;/*** @brief 单总线初始化* @param 无* @retval 从机响应位,0为响应,1为未响应*/
unsigned char OneWire_Init(void)
{unsigned char i;unsigned char AckBit;OneWire_DQ=1;OneWire_DQ=0;i = 247;while (--i); //Delay 500usOneWire_DQ=1;i = 32;while (--i); //Delay 70usAckBit=OneWire_DQ;i = 247;while (--i); //Delay 500usreturn AckBit;
}/*** @brief 单总线发送一位* @param Bit 要发送的位* @retval 无*/
void OneWire_SendBit(unsigned char Bit)
{unsigned char i;OneWire_DQ=0;i = 4;while (--i); //Delay 10usOneWire_DQ=Bit;i = 24;while (--i); //Delay 50usOneWire_DQ=1;
}/*** @brief 单总线接收一位* @param 无* @retval 读取的位*/
unsigned char OneWire_ReceiveBit(void)
{unsigned char i;unsigned char Bit;OneWire_DQ=0;i = 2;while (--i); //Delay 5usOneWire_DQ=1;i = 2;while (--i); //Delay 5usBit=OneWire_DQ;i = 24;while (--i); //Delay 50usreturn Bit;
}/*** @brief 单总线发送一个字节* @param Byte 要发送的字节* @retval 无*/
void OneWire_SendByte(unsigned char Byte)
{unsigned char i;for(i=0;i<8;i++){OneWire_SendBit(Byte&(0x01<<i));}
}/*** @brief 单总线接收一个字节* @param 无* @retval 接收的一个字节*/
unsigned char OneWire_ReceiveByte(void)
{unsigned char i;unsigned char Byte=0x00;for(i=0;i<8;i++){if(OneWire_ReceiveBit()){Byte|=(0x01<<i);}}return Byte;
}
Onewire.h
#ifndef __ONEWIRE_H__
#define __ONEWIRE_H__unsigned char OneWire_Init(void);
void OneWire_SendBit(unsigned char Bit);
unsigned char OneWire_ReceiveBit(void);
void OneWire_SendByte(unsigned char Byte);
unsigned char OneWire_ReceiveByte(void);#endif