51单片机DS18B20(单总线)温度读取

一、DS18B20介绍

        DS18B20是一种常见的数字温度传感器,其控制命令和数据都是以数字信号的方式输入输出,相比较于模拟温度传感器,具有功能强大、硬件简单、易扩展、抗干扰性强等特点
        测温范围: -55°C 到+125°C .
        通信接口: 1-Wire (单 总线)
        其它特征:可形成总线结构、内置温度报警功能、可寄生供电

二、引脚及应用电路

VCC表示电路的意思,指的是接入电路的电压;VDD表示器件的意思,指的是器件内部的工作电压;VSS表示公共连接端的意思,指的是公共接地端电压的意思。

三、DS18B20内部结构框图

64-BT ROM:作为器件地址。用于总线通信的寻址
SCRATHPAD (暂存器)公用于总线的数据交互
EEPROM用于保存温度触发阚值和配置参数

64-BIT ROM 每个DS18B02都有一个ID号,用来寻址,相当于一个大门,当只有一个单总线设备时,可以选择跳过这个大门;

MEMORY CONTROL LOGIC 内存控制逻辑,相当于管家,操作底下的暂存器;

SCRATCHPAD 暂存器,属于RAM,用于总线上数据交互;

TEMPERATURE SENSOR 是温度传感器,直接将数据处理好放在暂存器中;

底下两个都是设置阈值的,用于报警;

第四个是配置寄存器,设置分辨率,默认最高分辨率0.0625,可以设置为0.5的分辨率,使得运算的更快一些;

第五个是校验寄存器;

四、存储器结构

        我们无法通过写数据直接给EEPROM写数据,只能写入到暂存器中,通过发送指令,再让暂存器中的数据复制到EEPROM。

五、单总线介绍

●单总线(1-Wire BUS) 是由Dallas公司开发的-种通用数据总线一根通信线: DQ 
●异步、半双工
●单总线只需要一根通信线即可实现数据的双向传输,当采用寄生供电时,还可以省去设备的VDD线路,此时,供电加通信只需要DQ和GND两根线

单总线应用其实并不是很广泛,可以说DS18B20撑起了单总线的天下;右边这个是温湿度传感器DHT11,虽然说他也是一根数据线进行传输的,但它的通信协议和单总线通信协议有很大的区别,他不能在总线上边挂在很多设备,但它说它是单总线设备。

 (一)单总线电路规范

设备的DQ均要配置成开漏输出模式
DQ添加一个上拉电阻,阻值一般为4.7KQ左右
若此总线的从机采取寄生供电,则主机还应配一个强上拉输出电路

 (二)单总线时序结构

①初始化

初始化: 主机将总线拉低至少480us,然后释放总线,等待15~60us后, 存在的从机会拉低总线60~ 240us以响应主机,之后从机将释放总线

 unsigned char OneWire_Init(void)
{
    unsigned char i;
    unsigned char AckBit;
    OneWire_DQ=1;    
    OneWire_DQ=0;
    i = 247;while (--i);//将总线拉低至少480us,这里我们拉低延时500us
    OneWire_DQ=1;    
    i = 32;while (--i);//延时70us,函数调用花费4us忽略掉
    AckBit=OneWire_DQ;//主机读取从机是否响应
    i = 247;while (--i);//延时500us
    return AckBit;
}

② 发送一位

发送一位:主机将总线拉低60~120us,然后释放总线,表示发送0;主机将总线拉低1~ 15us, 然后释放总线,表示发送1。从机将在总线拉低30us后(典型值)读取电平,整个时间片应大于60us 。

void OneWire_SendBit(unsigned char Bit)
{
    unsigned char i;
    OneWire_DQ=0;
    i = 4;while (--i);//延时14us,考虑到函数跳转需要4us,因此我们用isp时要多延时4us
    OneWire_DQ=Bit;//省去一个if判断,在14us后直接将需要发送的位放在单总线上,30us                                    //从机自行读取
    i = 24;while (--i);//延时50us,考虑函数跳转需要4us,另外加4us
    OneWire_DQ=1;    

③接收一位

接收一位:主机将总线拉低1~15us,然后释放总线,并在拉低后15us内读取总线电平(尽量贴近15us的末尾),读取为低电平则为接收0,读取为高电平则为接收1 ,整个时间片应大于60us 

unsigned char OneWire_ReceiveBit(void)
{
    unsigned char i;
    unsigned char Bit;
    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);//延时50us,考虑函数跳转需要4us,另外加4us
    return Bit;

 ④发送和接收一个字节

发送一个字节

void OneWire_SendByte(unsigned char Byte)
{
    unsigned char i;
    for(i=0;i<8;i++)
    {
        OneWire_SendBit(Byte&(0x01<<i));
    }

接收一个字节

 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;
}

 六、DS18B20操作流程

(1)

初始化:从机复位,主机判断从机是否响应

ROM操作:ROM指令+本指令需要的读写操作

功能操作:功能指令+本指令需要的读写操作,相当于RAM操作对暂存器的操作

 MATCH ROM[55h]  匹配ROM,相当于设备的地址

SKIP ROM[CCh] 跳过ROM,只有一个设备在总线上,因此可以直接跳过ROM(大门),进行通信

CONVERT T[44h]  温度传递指令,发送该指令,DS18B20中的温度传感器就将数据传送到暂存器当中

WRITE SCRATCHPAD[4Eh] 写暂存器指令,该指令是将EEPROM中的数据写到暂存器当中

READ SCRATCHPAD[BEh] 读暂存器指令,该指令是将暂存器当中的数据都读出来,但实际操作时我们只需要前两个温度的字节

COPY SCRATCHPAD[48h]  复制暂存器,将ROM中的数据写入到EEPROM中,如果想要实现掉电不丢失,就先把数据写入到ROM中,再通过调用该指令,写入到EEPROM中

RECALL E2[B8h] 覆盖暂存器指令,该指令是将EEPROM中的数据覆盖掉暂存器中的数据

(2)DS18B20数据帧

 (3)温度存储格式

 低四位表示小数,高五位表示符号,中间的才是整数部分

(4)代码

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);//将总线拉低至少480us,这里我们拉低延时500us
	OneWire_DQ=1;	
	i = 32;while (--i);//延时70us,函数调用花费4us忽略掉
	AckBit=OneWire_DQ;//主机读取从机是否响应
	i = 247;while (--i);//延时500us
	return AckBit;
}

/**
  * @brief  单总线发送一位
  * @param  Bit 要发送的位
  * @retval 无
  */
void OneWire_SendBit(unsigned char Bit)
{
	unsigned char i;
	OneWire_DQ=0;
	i = 4;while (--i);//Delay 10us,考虑到函数跳转需要4us,因此我们用isp时要多延时4us
	OneWire_DQ=Bit;
	i = 24;while (--i);//延时50us,考虑函数跳转需要4us,另外加4us
	OneWire_DQ=1;	
}

/**
  * @brief  单总线接收一位
  * @param  无
  * @retval 读取的位
  */
unsigned char OneWire_ReceiveBit(void)
{
	unsigned char i;
	unsigned char Bit;
	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);//延时50us,考虑函数跳转需要4us,另外加4us
	return 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;
}

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;//因为低四位表示的是小数部分,因此Temp直接读出来并不是实际的值,
	            //要把小数部分摘出来,除以16相当于把低四位给滤出来
	return T;
}

 main.c

#include <REGX52.H>
#include "LCD1602.h"
#include "OneWire.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)
		{
			LCD_ShowChar(2,1,'-');
			T=-T;
		}
		else
		{
			LCD_ShowChar(2,1,'+');
		}
		LCD_ShowNum(2,2,T,3);
		LCD_ShowChar(2,5,'.');
		LCD_ShowNum(2,6,(unsigned long)(T*10000)%10000,4);
	}
}

  • 23
    点赞
  • 186
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
51单片机可以使用DS18B20数字温度传感器进行单总线多点测温。以下是一个简单的设计思路: 1. 连接DS18B20传感器到51单片机的IO口。将传感器的VCC引脚连接到单片机的电源正极,将传感器的GND引脚连接到单片机的地线,将传感器的DQ引脚连接到单片机的IO口。 2. 在单片机上编写程序,使用1-Wire协议与DS18B20传感器进行通信。可以使用单总线库函数来简化通信过程。 3. 初始化单总线总线,搜索并识别连接的DS18B20传感器。可以使用搜索函数来自动识别传感器的存在。 4. 通过发送命令,读取DS18B20传感器的温度数据。可以使用读取函数来获取传感器的温度值。 5. 将获取的温度数据进行处理和显示。可以使用LED数码管模块来显示温度值,也可以使用串口或LCD显示模块进行显示。 6. 可以通过循环的方式,实现对多个DS18B20传感器的温度进行连续测量和显示。 下面是一个示例代码,演示了如何使用51单片机DS18B20传感器进行单总线多点测温: ```c #include <reg51.h> #include <ds18b20.h> sbit DQ = P1^0; // DS18B20传感器连接的IO口 void main() { unsigned char i; unsigned char count; unsigned char temp[9]; float temperature; while (1) { count = ds18b20_search(); // 搜索并识别连接的DS18B20传感器 for (i = 0; i < count; i++) { ds18b20_convert(); // 发送温度转换命令 ds18b20_read(temp); // 读取温度数据 temperature = ds18b20_temperature(temp); // 处理温度数据 // 在这里可以将温度值进行显示或其他处理 } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值