DS18B20温度传感器(STM32F103C8T6)

一、前言

        使用LCD1602实时显示DS18B20传感器捕抓的环境温度(学习笔记整理)。

二、概述

(一)传感器说明

        DS18B20数字温度计提供9位温度读数。信息经过单线接口送入或送出DS18B20传感器,因此从中央处理器到DS18B20仅需要提供电源以及一根数据线,就可以工作。

(二)DS18B20的ROM指令表

ROM 指令表
指令 约定代码 功能
读ROM 33H 读取DS18B20温度传感器ROM中的编码(即64位地址)
符合ROM 55H 发送此命令之后,接着发出64位ROM编码,访问单总线上与该编码相对应的DS18B20使用之作出响应,为下一步对该DS18B20的读写作准备
搜索ROM F0H 用于确定挂接在同一总线上DS18B20的个数和识别64位ROM地址,为操作各器件作好准备
跳过ROM C0H 忽略64位ROM地址,直接向DS18B20发温度变换命令,适用于单片工作。
告警搜索 ECH 执行后只有温度超过设定值上限或下限才能做出响应

(三)DS18B20的RAM指令表

RAM 指令表
指令 约定代码 功能
温度变换 44H 启动DS18B20进行温度转换
读暂存器 BEH 读内部RAM中9字节的内容
写暂存器 4EH 发出向内部RAM的3、4字节写上、下限温度数据命令,紧跟该命令后,是传送两字节的数据
复制暂存器 48H

将RAM中的第3、4字节的内容复制到EEPROM中

重调EEPROM E8H 将EEPROM中内容恢复到RAM中的第3、4字节
读供电方式 B4H 读DS18B20供电模式,寄生供电时为‘0’,外接电源供电时为’1‘

三、DS18B20单总线协议

1、DS18B20初始化

DS18B20温度传感器(STM32F103C8T6)_第1张图片

(1) 数据线拉到低电平“0”。

(2) 延时480微妙(该时间的时间范围可以从480到960微妙)。

(3) 数据线拉到高电平“1”。

(4) 延时等待80微妙。如果初始化成功则在15到60微妙时间内产生一个由DS18B20所返回的低电平“0”.根据该状态可以来确定它的存在,但是应注意不能无限的进行等待,不然会使程序进入死循环,所以要进行超时判断。

(5) 若CPU读到了数据线上的低电平“0”后,还要做延时,其延时的时间从发出的高电平算起(第3步的时间算起)最少要480微妙。

2、读时序

DS18B20温度传感器(STM32F103C8T6)_第2张图片

(1) 将数据线拉低“0”。

(2) 延时1微妙。

(3) 将数据线拉高“1”,释放总线准备读数据。

(4) 延时10微妙。 //等待数据稳定

(5) 读数据线的状态得到1个状态位,并进行数据处理。

(6) 延时45微妙。

(7) 重复1~7步骤,直到读完一个字节。

3、写时序

DS18B20温度传感器(STM32F103C8T6)_第3张图片

(1) 数据线先置低电平“0”

(2) 延时15微妙。

(3) 按从低位到高位的顺序发送数据(一次只发送一位)。

(4) 延时60微妙。

(5) 将数据线拉到高电平。

(6) 重复1~5步骤,直到发送完整的字节。

(7) 最后将数据线拉高。

四、硬件连接

DS18B20温度传感器(STM32F103C8T6)_第4张图片

五、程序例程

1、DS18B20.c文件

#include "ds18b20.h"

/*******************************************************************************
* 函 数 名         : DS18B20_IO_IN
* 函数功能		   : DS18B20_IO输入配置	   
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void DS18B20_IO_IN(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Pin=DS18B20_PIN;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IPU;
	GPIO_Init(DS18B20_PORT,&GPIO_InitStructure);
}

/*******************************************************************************
* 函 数 名         : DS18B20_IO_OUT
* 函数功能		   : DS18B20_IO输出配置	   
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void DS18B20_IO_OUT(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;
	
	GPIO_InitStructure.GPIO_Pin=DS18B20_PIN;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_Init(DS18B20_PORT,&GPIO_InitStructure);
}

/*******************************************************************************
* 函 数 名         : DS18B20_Reset
* 函数功能		   : 复位DS18B20  
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void DS18B20_Reset(void)	   
{                 
	DS18B20_IO_OUT(); //SET PG11 OUTPUT
	DS18B20_DQ_OUT=0; //拉低DQ
	delay_us(750);    //拉低750us
	DS18B20_DQ_OUT=1; //DQ=1 
	delay_us(15);     //15US
}

/*******************************************************************************
* 函 数 名         : DS18B20_Check
* 函数功能		   : 检测DS18B20是否存在
* 输    入         : 无
* 输    出         : 1:未检测到DS18B20的存在,0:存在
*******************************************************************************/
u8 DS18B20_Check(void) 	   
{   
	u8 retry=0;
	DS18B20_IO_IN();//SET PG11 INPUT	 
	
	while (DS18B20_DQ_IN&&retry<200)
	{
		retry++;
		delay_us(1);
	};
	
	if(retry>=200)
		return 1;
	else 
		retry=0;
	
	while (!DS18B20_DQ_IN&&retry<240)
	{
		retry++;
		delay_us(1);
	};
	if(retry>=240)
		return 1;	 
	
	return 0;
}

/*******************************************************************************
* 函 数 名         : DS18B20_Read_Bit
* 函数功能		   : 从DS18B20读取一个位
* 输    入         : 无
* 输    出         : 1/0
*******************************************************************************/
u8 DS18B20_Read_Bit(void) 			 // read one bit
{
	u8 data;
	DS18B20_IO_OUT();//SET PG11 OUTPUT
	DS18B20_DQ_OUT=0; 
	delay_us(2);
	DS18B20_DQ_OUT=1; 
	DS18B20_IO_IN();//SET PG11 INPUT
	delay_us(12);
	
	if(DS18B20_DQ_IN)
		data=1;
	else 
		data=0;	 
	
	delay_us(50);  
	
	return data;
}

/*******************************************************************************
* 函 数 名         : DS18B20_Read_Byte
* 函数功能		   : 从DS18B20读取一个字节
* 输    入         : 无
* 输    出         : 一个字节数据
*******************************************************************************/
u8 DS18B20_Read_Byte(void)    // read one byte
{        
	u8 i,j,dat;
	dat=0;
	for (i=1;i<=8;i++) 
	{
		j=DS18B20_Read_Bit();
		dat=(j<<7)|(dat>>1);
	}						    
	return dat;
}

/*******************************************************************************
* 函 数 名         : DS18B20_Write_Byte
* 函数功能		   : 写一个字节到DS18B20
* 输    入         : dat:要写入的字节
* 输    出         : 无
*******************************************************************************/
void DS18B20_Write_Byte(u8 dat)     
{             
	u8 j;
	u8 testb;
	DS18B20_IO_OUT();//SET PG11 OUTPUT;
	for (j=1;j<=8;j++) 
	{
		testb=dat&0x01;
		dat=dat>>1;
		if (testb) 
		{
			DS18B20_DQ_OUT=0;// Write 1
			delay_us(2);                            
			DS18B20_DQ_OUT=1;
			delay_us(60);             
		}
		else 
		{
			DS18B20_DQ_OUT=0;// Write 0
			delay_us(60);             
			DS18B20_DQ_OUT=1;
			delay_us(2);                          
		}
	}
}

/*******************************************************************************
* 函 数 名         : DS18B20_Start
* 函数功能		   : 开始温度转换
* 输    入         : 无
* 输    出         : 无
*******************************************************************************/
void DS18B20_Start(void)// ds1820 start convert
{   						               
	DS18B20_Reset();	   
	DS18B20_Check();	 
	DS18B20_Write_Byte(0xcc);// skip rom
	DS18B20_Write_Byte(0x44);// convert
} 

/*******************************************************************************
* 函 数 名         : DS18B20_Init
* 函数功能		   : 初始化DS18B20的IO口 DQ 同时检测DS的存在
* 输    入         : 无
* 输    出         : 1:不存在,0:存在
*******************************************************************************/   	 
u8 DS18B20_Init(void)
{
	GPIO_InitTypeDef  GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(DS18B20_PORT_RCC,ENABLE);
	
	GPIO_PinRemapConfig(GPIO_Remap_SWJ_Disable,ENABLE);
	
	GPIO_InitStructure.GPIO_Pin=DS18B20_PIN;
	GPIO_InitStructure.GPIO_Speed=GPIO_Speed_50MHz;
	GPIO_InitStructure.GPIO_Mode=GPIO_Mode_Out_PP;
	GPIO_Init(DS18B20_PORT,&GPIO_InitStructure);
 
 	DS18B20_Reset();
	return DS18B20_Check();
}  

/*******************************************************************************
* 函 数 名         : DS18B20_GetTemperture
* 函数功能		   : 从ds18b20得到温度值
* 输    入         : 无
* 输    出         : 温度数据
*******************************************************************************/ 
float DS18B20_GetTemperture(void)
{
	u16 temp;
	u8 a,b;
	float value;
	
	DS18B20_Start();                    // ds1820 start convert
	DS18B20_Reset();
	DS18B20_Check();	 
	DS18B20_Write_Byte(0xcc);// skip rom
	DS18B20_Write_Byte(0xbe);// convert	    
	a=DS18B20_Read_Byte(); // LSB   
	b=DS18B20_Read_Byte(); // MSB   
	temp=b;
	temp=(temp<<8)+a;
	
	if((temp&0xf800)==0xf800)
	{
		temp=(~temp)+1;
		value=temp*(-0.0625);
	}
	else
	{
		value=temp*0.0625;	
	}
	return value;    
}

2、主函数


int main(void)
{
	float temper = 0.0;
	char display_temp[20] = {0};
	
	Usart1_Pin_Init(115200);
	printf("初始化成功\r\n");
	
	Sys_Delay_Init();
	Lcd1602_Init();
	DS18B20_Init();
	delay_ms(50);
	while(1)
	{
		temper=DS18B20_GetTemperture();
		if(temper<0)
		{
			printf("检测的温度为:-");
		}
		else
		{
			printf("检测的温度为: ");
		}
		printf("%.2f°C\r\n",temper);
		sprintf(display_temp,"TEMP:%.3f",temper);
		Lcd1602_DisplayString(1,1,(u8 *)display_temp); //显示温度值
	}
}

六、实验结果

DS18B20温度传感器(STM32F103C8T6)_第5张图片

相关程序和资料,有需要者自行下载

网盘链接:

        链接:https://pan.baidu.com/s/1kW9866jJ9AQYM4YLc1kEUw 
        提取码:o3m4

 如有什么问题欢迎指出来,有什么模块可以联系博主,博主会查询资料分享出来。

你可能感兴趣的:(stm32,stm32,DS18B20)