目的/效果
LCD1602显示温度传感器DS18B20的实时值。
一,STC单片机模块
二,温度传感器DS18B20
2.1 DS18B20简介
DS18B20是一种常见的数字温度传感器,其控制命令和数据都是以数字信号的方式输入输出,相比较于模拟温度传感器,具有功能强大、硬件简单、易扩展、抗干扰性强等特点
测温范围:-55°C 到 +125°C
通信接口:1-Wire(单总线)只需1个接口引脚即可通信
其它特征:可形成总线结构、内置温度报警功能、可寄生供电
2.2 位置和电路图
2.3 内部结构
64-BIT ROM:作为器件地址,用于总线通信的寻址
SCRATCHPAD(暂存器):用于总线的数据交互
EEPROM:用于保存温度触发阈值和配置参数
2.4 存储结构
高速暂存器由9个字节组成
字节0~1 是温度存储器,用来存储转换好的温度。第0个字节存储温度低8位,第一个字节存储温度高8位
字节2~3 是用户用来设置最高报警和最低报警值(TH和TL)。
字节4 是配置寄存器,用来配置转换精度,可以设置为9~12 位。
字节5~7 保留位。芯片内部使用
字节8 CRC校验位。是64位ROM中的前56位编码的校验码。由CRC发生器产生。
2.5 读取与计算
DS18B20采用16位补码的形式来存储温度数据,温度是摄氏度。当温度转换命令发布后,经转换所得的温度值以二字节补码形式存放在高速暂存存储器的第0和第1个字节。
2.3 单总线
2.3.1 线路规范
设备的DQ均要配置成开漏输出模式
DQ添加一个上拉电阻,阻值一般为4.7KΩ左右
若此总线的从机采取寄生供电,则主机还应配一个强上拉输出电路
2.3.2 初始化时序
初始化:主机将总线拉低至少480us,然后释放总线,等待15~60us后,存在的从机会拉低总线60~240us以响应主机,之后从机将释放总线
/**
* 函 数:单总线初始化
* 参 数:无
* 返 回 值:从机响应位,0为响应,1为未响应
*/
unsigned char OneWire_Init(void)
{
unsigned char i;
unsigned char AckBit;
EA=0;
OneWire_DQ=1;
OneWire_DQ=0;
i = 247;while (--i); //Delay 500us
OneWire_DQ=1;
i = 32;while (--i); //Delay 70us
AckBit=OneWire_DQ;
i = 247;while (--i); //Delay 500us
EA=1;
return AckBit;
}
2.3.3 发送一位时序
发送一位:主机将总线拉低60~120us,然后释放总线,表示发送0;主机将总线拉低1~15us,然后释放总线,表示发送1。从机将在总线拉低30us后(典型值)读取电平,整个时间片应大于60us
/**
* 函 数:单总线发送一位
* 参 数:Bit 要发送的位
* 返 回 值:无
*/
void OneWire_SendBit(unsigned char Bit)
{
unsigned char i;
EA=0;
OneWire_DQ=0;
i = 4;while (--i); //延时 10us
OneWire_DQ=Bit;
i = 24;while (--i); //延时 50us
OneWire_DQ=1;
EA=1;
}
2.3.4 接收一位时序
接收一位:主机将总线拉低1~15us,然后释放总线,并在拉低后15us内读取总线电平(尽量贴近15us的末尾),读取为低电平则为接收0,读取为高电平则为接收1 ,整个时间片应大于60us
/**
* 函 数:单总线接收一位
* 参 数:无
* 返 回 值:读取的位
*/
unsigned char OneWire_ReceiveBit(void)
{
unsigned char i;
unsigned char Bit;
EA=0;
OneWire_DQ=0;
i = 2;while (--i); //Delay 5us
OneWire_DQ=1;
i = 2;while (--i); //Delay 5us
Bit=OneWire_DQ;
i = 24;while (--i); //Delay 50us
EA=1;
return Bit;
}
2.3.5 发送一个字节时序
发送一个字节:连续调用8次发送一位的时序,依次发送一个字节的8位(低位在前)
/**
* 函 数:单总线发送一个字节
* 参 数:Byte 要发送的字节
* 返 回 值:无
*/
void OneWire_SendByte(unsigned char Byte)
{
unsigned char i;
for(i=0;i<8;i++)
{
OneWire_SendBit(Byte&(0x01<<i));
}
}
2.3.6 接收一个字节时序
接收一个字节:连续调用8次接收一位的时序,依次接收一个字节的8位(低位在前)
/**
* 函 数:单总线接收一个字节
* 参 数:无
* 返 回 值:接收的一个字节
*/
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;
}
2.4 DS18B20数据操作
2.4.1 初始化
初始化:从机复位,主机判断从机是否响应
2.4.2 温度变换
ROM操作:ROM指令+本指令需要的读写操作
功能操作:功能指令+本指令需要的读写操作
温度变换:初始化→跳过ROM →开始温度变换
//DS18B20指令
#define DS18B20_SKIP_ROM 0xCC
#define DS18B20_CONVERT_T 0x44
#define DS18B20_READ_SCRATCHPAD 0xBE
/**
* 函 数:DS18B20开始温度变换
* 参 数:无
* 返 回 值:无
*/
void DS18B20_ConvertT(void)
{
OneWire_Init();
OneWire_SendByte(DS18B20_SKIP_ROM);
OneWire_SendByte(DS18B20_CONVERT_T);
}
2.4.3 温度读取
温度读取:初始化→跳过ROM →读暂存器→连续的读操作
/**
* 函 数:DS18B20读取温度
* 参 数:无
* 返 回 值:温度数值
*/
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; //高位和低位组合为1个数
T=Temp/16.0; //低4位为小数 等同于Temp*0.0625
return T;
}
三,创建Keil项目
详细参考:51单片机STC89C52RC——创建Keil项目-CSDN博客
四,代码
#include <REGX52.H>
#include "LCD1602.h"
#include "DS18B20.h"
#include "Delay.h"
/**
* 函 数:主函数
* 参 数:无
* 返 回 值:无
*/
void main()
{
float T;
DS18B20_ConvertT(); //上电先转换一次温度,防止第一次读数据错误
Delay_ms(1000); //等待转换完成
LCD_Init();
LCD_ShowString(1,1,"Temper");
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);//显示温度小数部分
}
}
详细请参考 Gitee《STC89C52RC: 51单片机学习资料、代码 -13-1 温度传感器DS18B20》
五,代码编译、下载到51单片机
代码编译请参考
《51单片机STC89C52RC——代码编译-CSDN博客》
代码下载请参考
《51单片机STC89C52RC——STCAI-ISP代码下载-CSDN博客》