问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

51单片机STC89C52RC与DS18B20温度传感器的详细教程

创作时间:
作者:
@小白创作中心

51单片机STC89C52RC与DS18B20温度传感器的详细教程

引用
CSDN
1.
https://m.blog.csdn.net/oopxiajun2011/article/details/140076286

本教程将详细介绍如何使用51单片机STC89C52RC与DS18B20温度传感器进行温度检测,并通过LCD1602显示屏实时显示温度值。

一、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,然后释放总线,等待1560us后,存在的从机会拉低总线60240us以响应主机,之后从机将释放总线

/**
 * 函    数:单总线初始化
 * 参    数:无
 * 返 回 值:从机响应位,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 发送一位时序

发送一位:主机将总线拉低60120us,然后释放总线,表示发送0;主机将总线拉低115us,然后释放总线,表示发送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博客》

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号