使用STM32控制DS18B20温度传感器

目录


前言

网上关于DS18B20 传感器资料很多,但是代码部分说的畏畏缩缩,好像怕我们学会一样,在我写成功后,于是在此进行分享。本篇只针对没写过DS18B20的新手,且是单个传感器。多个传感器本篇没有任何介绍。


一、初始化

1.逻辑

1.主机(控制器STM32,下同)拉低电平,持续480us-960us,然后释放(拉高电平,下同)

2.等待15us-60us(在程序中给了30)//第一和第二步均为输出,但是第二部后要切换为输入模式

3.从机(DS18B20 传感器,下同)会低电平,持续时间60us-240us,//这一步是检测传感器在不在的关键一步,加上第二步释放后的时间,所以我们要在90us(30+60)-270us(30+240)内检测电平高低来判断传感器是否存在。在此时应为输入模式。

4.主机接收至少480us,所以我们检测完后还需等待时序结束,时间=480us-释放后到检测时时间

返回数值。

代码:

1.初始化代码

#include "stm32f10x.h"                  // Device header
#include "main.h"		//这里面没什么(除了delay函数)

#define DS18B20 GPIO_Pin_15			//如果复制使用,只需改这行Pin口和下行通道还开启有时钟
#define DS18B20_PROT GPIOB			//其他代码不用更改,只需补全delay和显示函数就行
#define DS18B20_LOW GPIO_ResetBits(DS18B20_PROT,DS18B20)
#define DS18B20_HIGH GPIO_SetBits(DS18B20_PROT,DS18B20)

void DS18B20_Init(void)	//初始化函数
{
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);    //开启对应通道时钟
	
	GPIO_InitTypeDef GPIO_InitStruct;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Pin = DS18B20;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(DS18B20_PROT,&GPIO_InitStruct);
}

2.模式切换函数,1为写/输出模式,0为读/输入模式

void DS18B20_Output_Input(u8 cmd)  //输入输出模式切换,1输出,0输入/读取
{
	GPIO_InitTypeDef GPIO_InitStruct;
	
	if(cmd)	//为1 是输出模式
	{
		GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
		GPIO_InitStruct.GPIO_Pin = DS18B20;
		GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
		
	}
	else	//为0,输入模式
	{
		GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
		GPIO_InitStruct.GPIO_Pin = DS18B20;
		GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;

	}
	GPIO_Init(DS18B20_PROT,&GPIO_InitStruct);
}

3. 初始化代码

u8 DS18B20_Starup(void)	//判断DS18B20 是否存在的一个函数
{
	u8 data;
	
	DS18B20_Output_Input(1);	//为输出模式
	DS18B20_LOW;				//拉低电平
	Delay_us(480);		//delay函数,需要自己写,网上资料很多,保证时间准确就行
	DS18B20_HIGH;		//拉高电平,也是 释放总线
	Delay_us(100);
	
	DS18B20_Output_Input(0);	//为输入模式
	data = GPIO_ReadInputDataBit(DS18B20_PROT,DS18B20);	//根据时序存在返回0,不存在是1
	Delay_us(380);
	
	return data;
}

4.此时我们需要验证下,在main函数里进行数据显示

int main(void)
{
	OLED_Init();
	DS18B20_Init();

	while (1)
	{
		OLED_ShowNum(2, 5, DS18B20_Starup(), 1);//用自己的方式验证,存在为0,否则为1
    }
}

 如果显示0,在拔下传感器的数据线后显示为1,插入后为0.则以上代码和传感器没有问题

二、写数据和读数据

1.写时序函数

DS18B20对时序要求非常高,所以delay函数一定要精准

代码

void DS18B20_Write_Byte(u8 data)	//写数据
{
	for(u8 i=0;i<8;i++)
	{
		DS18B20_Output_Input(1);
		DS18B20_LOW;
		Delay_us(2);	//拉低2us进入书写时序
		(data&0x01) ? DS18B20_HIGH:DS18B20_LOW;//从低位往高位写移位7次后将是最高位
		Delay_us(45);	//延时45us
		DS18B20_HIGH;	//释放总线
		
		data >>=1;		
	}
}

2.读函数

代码:

u8  DS18B20_Read_Byte(void)	//读程序
{
	u8 data=0;
	for(u8 i=0;i<8;i++)
	{
		data >>=1;
		DS18B20_Output_Input(1);	//写时序,拉低2us后释放
		DS18B20_LOW;
		Delay_us(2);	//拉低2us进入读时序
		DS18B20_HIGH;
		
		DS18B20_Output_Input(0);		//进入读时序
		if((GPIO_ReadInputDataBit(DS18B20_PROT,DS18B20)) == SET)
		{		
			data |= 0x80;
		}
		Delay_us(45);
	}
	return data;
}

三 、读取温度

  1. 逻辑:1.初始化
  2. 跳过匹配命令(0XCC)
  3. 温度转换命令(0X44)
  4. delay750ms        //注意时间单位毫秒
  5. 初始化
  6. 跳过匹配命令(0XCC)
  7. 温度读取命令(0XBE)
  8. 先读取的低8位
  9. 再读取的高8位
  10. 数据转换,二进制转换成10进制

代码:最后的代码*10,为方便显示小数

void DS18B20_Read_Temp(u16 *data)
{
	u8 LSB=0,HSB=0;u16 Temp=0;	//LSB 低位的8位数据
	
	DS18B20_Starup();
	DS18B20_Write_Byte(0xCC);	//跳过匹配步骤
	DS18B20_Write_Byte(0x44);	//温度转换,12位时间为750ms,注意时间单位
	Delay_ms(750);
	DS18B20_Starup();
	DS18B20_Write_Byte(0xCC);	
	DS18B20_Write_Byte(0xBE);	//进行数据读写
	
	LSB = DS18B20_Read_Byte();	//先读取的低8位
	HSB = DS18B20_Read_Byte();	//再读取的高8位

	Temp = (HSB<<8) | LSB;
	
	if((Temp&0xF800)==0xF800)	//S=1为真否则位0
	{
		*data = (((~Temp + 0x01)*-0.0625))*10;//为负温度
	
	}
	else
	{
		*data = (Temp*0.0625)*10;    //正温度
	}	
}

四 ,显示数据

在main里进行显示,需要取地址操作

代码:

u16 Temp=0;	//u16 类型值

int main(void)
{	
	OLED_Init();
	DS18B20_Init();

	while (1)
	{
		DS18B20_Read_Temp(&Temp);	//取值
		OLED_ShowSignedNum(2, 1, (Temp/10), 2);	//整数位
		OLED_ShowString(2, 4, ".");
		OLED_ShowNum(2, 5, (Temp%10), 1);//小数位一位
    }
}


总结

关于delay和显示函数,用的是江科大的代码。需要的话我有空也贴出来。

还有我觉得CSDN一些博主写内容故意挖坑是很不好的行为,不限于代码故意写错,内容故意颠倒顺序,注释故意于内容不符。想教就认真写,想藏私就别写。

代码出错谁都不能避免,但是故意就很恶心。

最后感谢对于知识无私分享的人(不含我)。

作者:2301_80596293

物联沃分享整理
物联沃-IOTWORD物联网 » 使用STM32控制DS18B20温度传感器

发表评论