通过stm32读取DS18B20并在显示屏上显示温度值(附源码)

这篇具有很好参考价值的文章主要介绍了通过stm32读取DS18B20并在显示屏上显示温度值(附源码)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一、前言

使用stm32f103c8t6的芯片,在OLED显示屏上显示DS18B20的温度值。

二、传感器概述

DS18B20 数字温度计提供 9 位温度读数,指示器件的温度信息经过单线接口送入 DS18B20 或从 DS18B20 送出, 因此从中央处理器到 DS18B20 仅需连接一条线。 读、写和完成温度变换所需的电源可以由数据线本身提供而不需要外部电源。
stm32ds18b20,stm32,单片机,嵌入式硬件stm32ds18b20,stm32,单片机,嵌入式硬件

 读时序:

stm32ds18b20,stm32,单片机,嵌入式硬件

写时序:

stm32ds18b20,stm32,单片机,嵌入式硬件

以下是DS18B20的特性:

1.独特的单线接口 ,只需 1 个接口引脚即可通信。
2.每个设备的内部ROM上都烧写了一个独一无二的64位序列号。
3无需外部元件。
4.能够采用数据线供电,供电范围为3.0V至5.5V。
5.温度可测量范围为:-55℃至+125℃(-67℉至+257℉)。
6.温度范围超过-10℃至85℃之外时测温分辨率0.5℃。
7.以 9 位数字值方式读出温度。
8.在 1 秒( 典型值 )内把温度变换为数字。
9.用户可定义的 非易失性的温度告警设置。
10.告警搜索命令识别和寻址温度在编定的极限之外的器件(温度告警情况)。
11.应用范围包括恒温控制 工业系统 消费类产品 温度计或任何热敏系统。

相关电气特性:
stm32ds18b20,stm32,单片机,嵌入式硬件

三、接线说明

stm32ds18b20,stm32,单片机,嵌入式硬件

本文使用的是stm32f103c8的芯片,VCC接3.3V,信号线接PB12 引脚。

四、程序编写

1.DS18B20.C

#include "ds18b20.h"
#include "stm32f10x.h"

 /**************************************************************************************
 * 描  述 : 配置DS18B20用到的I/O口
 * 入  参 : 无
 * 返回值 : 无
 **************************************************************************************/
static void DS18B20_GPIO_Config(void)
{		
	GPIO_InitTypeDef GPIO_InitStructure;

	RCC_APB2PeriphClockCmd(DS18B20_CLK, ENABLE); 
															   
  GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;	
  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //推挽输出  
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; 
  GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
	
	GPIO_SetBits(DS18B20_PORT, DS18B20_PIN);	 //DS18B20数据引脚初始化配置为高电平输出
}

 /**************************************************************************************
 * 描  述 : 配置使DS18B20-DATA引脚变为输入模式
 * 入  参 : 无
 * 返回值 : 无
 **************************************************************************************/
static void DS18B20_Mode_IPU(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-DATA引脚变为输出模式
 * 入  参 : 无
 * 返回值 : 无
 **************************************************************************************/
static void DS18B20_Mode_Out_PP(void)
{
 	GPIO_InitTypeDef GPIO_InitStructure;
															   
  GPIO_InitStructure.GPIO_Pin = DS18B20_PIN;	

  GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   //推挽输出   
  GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_Init(DS18B20_PORT, &GPIO_InitStructure);
}

 /**************************************************************************************
 * 描  述 : 主机给从机发送复位脉冲
 * 入  参 : 无
 * 返回值 : 无
 **************************************************************************************/
static void DS18B20_Rst(void)
{
	DS18B20_Mode_Out_PP();     //主机设置为推挽输出 
	
	DS18B20_DATA_OUT(LOW);     //主机至少产生480us的低电平复位信号
	Delay_us(750);
	DS18B20_DATA_OUT(HIGH);   //主机在产生复位信号后,需将总线拉高
	Delay_us(15);   //从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
}

 /**************************************************************************************
 * 描  述 : 检测从机给主机返回的存在脉冲
 * 入  参 : 无
 * 返回值 : 0:成功   1:失败  
 **************************************************************************************/
static u8 DS18B20_Presence(void)
{
	u8 pulse_time = 0;
	
	DS18B20_Mode_IPU();    //主机设置为上拉输入
	
	/* 等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号 
	 * 如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
	 */
	while( DS18B20_DATA_IN() && pulse_time<100 )
	{
		pulse_time++;
		Delay_us(1);
	}	

	if( pulse_time >=100 )  //经过100us后,存在脉冲都还没有到来
		return 1;             //读取失败
	else                 //经过100us后,存在脉冲到来
		pulse_time = 0;    //清零计时变量
	
	while( !DS18B20_DATA_IN() && pulse_time<240 )  // 存在脉冲到来,且存在的时间不能超过240us
	{
		pulse_time++;
		Delay_us(1);
	}	
	if( pulse_time >=240 ) // 存在脉冲到来,且存在的时间超过了240us
		return 1;        //读取失败
	else
		return 0;
}

 /**************************************************************************************
 * 描  述 : 从DS18B20读取一个bit
 * 入  参 : 无
 * 返回值 : u8 
 **************************************************************************************/
static u8 DS18B20_Read_Bit(void)
{
	u8 dat;
	
	/* 读0和读1的时间至少要大于60us */	
	DS18B20_Mode_Out_PP();
	/* 读时间的起始:必须由主机产生 >1us <15us 的低电平信号 */
	DS18B20_DATA_OUT(LOW);
	Delay_us(10);
	
	/* 设置成输入,释放总线,由外部上拉电阻将总线拉高 */
	DS18B20_Mode_IPU();
	
	if( DS18B20_DATA_IN() == SET )
		dat = 1;
	else
		dat = 0;
	
	/* 这个延时参数请参考时序图 */
	Delay_us(45);
	
	return dat;
}

 /**************************************************************************************
 * 描  述 : 从DS18B20读一个字节,低位先行
 * 入  参 : 无
 * 返回值 : u8  
 **************************************************************************************/
u8 DS18B20_Read_Byte(void)
{
	u8 i, j, dat = 0;	
	
	for(i=0; i<8; i++) 
	{
		j = DS18B20_Read_Bit();		//从DS18B20读取一个bit
		dat = (dat) | (j<<i);
	}
	
	return dat;																																																																																
}

 /**************************************************************************************
 * 描  述 : 写一个字节到DS18B20,低位先行
 * 入  参 : u8
 * 返回值 : 无  
 **************************************************************************************/
void DS18B20_Write_Byte(u8 dat)
{
	u8 i, testb;
	DS18B20_Mode_Out_PP();
	
	for( i=0; i<8; i++ )
	{
		testb = dat&0x01;
		dat = dat>>1;		
		/* 写0和写1的时间至少要大于60us */
		if (testb)
		{			
			DS18B20_DATA_OUT(LOW);
			Delay_us(8);   //1us < 这个延时 < 15us
			
			DS18B20_DATA_OUT(HIGH);
			Delay_us(58);    //58us+8us>60us
		}		
		else
		{			
			DS18B20_DATA_OUT(LOW);  
			/* 60us < Tx 0 < 120us */
			Delay_us(70);
			
			DS18B20_DATA_OUT(HIGH);			
			/* 1us < Trec(恢复时间) < 无穷大*/
			Delay_us(2);
		}
	}
}

 /**************************************************************************************
 * 描  述 : 起始DS18B20
 * 入  参 : 无
 * 返回值 : 无  
 **************************************************************************************/
void DS18B20_Start(void)
{
	DS18B20_Rst();	           //主机给从机发送复位脉冲
	DS18B20_Presence();	       //检测从机给主机返回的存在脉冲
	DS18B20_Write_Byte(0XCC);		 // 跳过 ROM 
	DS18B20_Write_Byte(0X44);		 // 开始转换 
}

 /**************************************************************************************
 * 描  述 : DS18B20初始化函数
 * 入  参 : 无
 * 返回值 : u8
 **************************************************************************************/
u8 DS18B20_Init(void)
{
	DS18B20_GPIO_Config();   
	DS18B20_Rst();
	
	return DS18B20_Presence();
}

 /**************************************************************************************
 * 描  述 : 从DS18B20读取温度值
 * 入  参 : 无  
 * 返回值 : float 
 **************************************************************************************/
float DS18B20_Get_Temp(void)
{
	u8 tpmsb, tplsb;
	short s_tem;
	float f_tem;
	
	DS18B20_Rst();	   
	DS18B20_Presence();	 
	DS18B20_Write_Byte(0XCC);				/* 跳过 ROM */
	DS18B20_Write_Byte(0X44);				/* 开始转换 */
	
	DS18B20_Rst();
  DS18B20_Presence();
	DS18B20_Write_Byte(0XCC);				/* 跳过 ROM */
  DS18B20_Write_Byte(0XBE);				/* 读温度值 */
	
	tplsb = DS18B20_Read_Byte();		 
	tpmsb = DS18B20_Read_Byte(); 
	
	s_tem = tpmsb<<8;
	s_tem = s_tem | tplsb;
	
	if( s_tem < 0 )		/* 负温度 */
		f_tem = (~s_tem+1) * 0.0625;	
	else
		f_tem = (s_tem * 0.0625);
	  
																	//这样做的目的将小数点后第一位也转换为可显示数字
																	//同时进行一个四舍五入操作。
	  
	return f_tem; 	
}


/*************************************END OF FILE******************************/

2.DS18B20.H

#ifndef __DS18B20_H
#define	__DS18B20_H

#include "stm32f10x.h"
#include "delay.h"

#define HIGH  1
#define LOW   0

#define DS18B20_CLK     RCC_APB2Periph_GPIOB
#define DS18B20_PIN     GPIO_Pin_12                  
#define DS18B20_PORT		GPIOB 

//带参宏,可以像内联函数一样使用,输出高电平或低电平
#define DS18B20_DATA_OUT(a)	if (a)	\
					GPIO_SetBits(GPIOB,GPIO_Pin_12);\
					else		\
					GPIO_ResetBits(GPIOB,GPIO_Pin_12)
 //读取引脚的电平
#define  DS18B20_DATA_IN()	   GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_12)

typedef struct
{
	u8  humi_int;		//湿度的整数部分
	u8  humi_deci;	 	//湿度的小数部分
	u8  temp_int;	 	//温度的整数部分
	u8  temp_deci;	 	//温度的小数部分
	u8  check_sum;	 	//校验和
		                 
}DS18B20_Data_TypeDef;

u8 DS18B20_Init(void);
float DS18B20_Get_Temp(void);
#endif /* __DS18B20_H */

3.读取DS8B20温度值并显示在OLED显示屏上。

void TEMP_Value_Conversion()
{
	temp_data=DS18B20_Get_Temp();
	temp_data1=temp_data;
	

	sprintf((char*)ucbuf,"%4.2f",temp_data1);
  OLED_ShowString(72,48,(uint8_t*)ucbuf,16,1);
  OLED_ShowChinese(0,48,0,16,1);
	OLED_ShowChinese(16,48,1,16,1);
	OLED_ShowChinese(32,48,2,16,1);
	OLED_ShowChinese(48,48,3,16,1);
	OLED_ShowChar(64,48,':',16,1);
	OLED_ShowChinese(112,48,4,16,1);
	  
}

4.main函数代码:

main (void)
{
	/* 配置系统时钟为72M */
	SystemInit();
  

	DS18B20_Init();
	OLED_Init();
	OLED_ColorTurn(0);//0正常显示,1 反色显示
  OLED_DisplayTurn(0);//0正常显示 1 屏幕翻转显示
	OLED_ShowChinese(48,16,3,16,1);
	while(1)
	{
		OLED_Refresh();
		
		TEMP_Value_Conversion();
		Delay_ms(500);  
	}
}

其中OLED的配置程序及接线参考之前的文章https://blog.csdn.net/qq_50749196/article/details/131022176

五、最终效果

我这里使用的是贴片式DS18B20温度传感器(图片上方蓝色线头),OLED显示的温度保留小数点后两位数字。

stm32ds18b20,stm32,单片机,嵌入式硬件

完整程序已上传,有需要者自行下载:

链接:https://pan.baidu.com/s/1KbtNQGjrHjWSbZUC1efnSA?pwd=ydlz 
提取码:ydlz文章来源地址https://www.toymoban.com/news/detail-610825.html

到了这里,关于通过stm32读取DS18B20并在显示屏上显示温度值(附源码)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32使用HAL库驱动DS18B20

    因为DS18B20是单总线,数据接收发送都是这根线,所以单片机配置为开漏上拉输出。 因为DS18B20对时序要求比较严格,建议用定时器延时获得微秒延时函数。 总线为48M,分频48,获得1us定时时基。 使用“void DS18B20_StartConv(void)”函数启动转换,因为转换时间需要750ms(12Bit精度)

    2024年02月07日
    浏览(39)
  • STM32F1使用HAL库驱动DS18B20

    目录 DS18B20概述 工程配置  命令手册 单总线协议  初始化时序  写时序 读时序 读取温度 驱动附录  DS18B20是一款单总线(one wire)芯片,因此其DQ引脚与单片机相连的IO口既要是输入也要是输出,cubeMX的初始化引脚设置只能选择其一,这里我们使用手动配置引脚。 先用cubeMX生

    2024年02月04日
    浏览(40)
  • STM32 Proteus仿真水箱水塔水位温度控制系统DS18B20 -0065

    STM32 Proteus仿真水箱水塔水位温度控制系统DS18B20 -0065 Proteus 仿真小实验: STM32 Proteus仿真水箱水塔水位温度控制系统DS18B20 -0065 功能: 硬件组成:STM32F103C8单片机 +LCD1602显示器+ADC220V转3.3V电路+DS18B20温度+多个按键(设置温度和水位)+继电器模拟加热+继电器模拟加水。 1.人工

    2024年02月15日
    浏览(39)
  • Clion开发Stm32之温湿度传感器(DS18B20)驱动编写和测试

    涵盖之前文章: Clion开发STM32之HAL库GPIO宏定义封装(最新版) Clion开发stm32之微妙延迟(采用nop指令实现) Clion开发STM32之日志模块(参考RT-Thread) 头文件 源文件

    2024年02月15日
    浏览(48)
  • 【基于STM32F103C8T6的DS18b20温度检测系统】

    库函数是ST公司针对STM32系列微控制器提供的一套API,可以方便地实现各种功能。下面是一个基于STM32F103C8T6的温度检测系统的示例,使用了STM32F10x标准库函数。 硬件部分: - STM32F103C8T6微控制器 - 电源模块 - 温度传感器模块 软件部分: - Keil C编译器 - STM32F10x_StdPeriph_Driver库文件

    2024年01月20日
    浏览(50)
  • 51单片机读取DS18B20温度传感器

    1 .首先我们知道DS18B20是 单总线协议 ,只有一根数据线。所以Data数据线即使发送端又是接收端,同时DS18B20内部接了弱上拉电阻(如图一所示),数据线默认为高电平。有了这些概念,我们就能进行下一步。                                                图一 (截取

    2024年02月08日
    浏览(41)
  • 【正点原子STM32连载】 第四十二章 DS18B20数字温度传感器实验 摘自【正点原子】STM32F103 战舰开发指南V1.2

    1)实验平台:正点原子stm32f103战舰开发板V4 2)平台购买地址:https://detail.tmall.com/item.htm?id=609294757420 3)全套实验源码+手册+视频下载地址: http://www.openedv.com/thread-340252-1-1.html# 本章,我们将介绍STM32F103如何读取外部温度传感器的温度,来得到较为准确的环境温度。我们将学习

    2024年02月04日
    浏览(56)
  • ESP32设备驱动-OLED显示单个或多个DS18B20传感器数据

    在本文中,我们将介绍如何ESP32驱动单个或多个DS18B20传感器,并将DS18B20传感器数据在OLE中显示。 DS18B20 是一种温度传感器,本质上是单线可编程的。 它广泛用于测量存在于硬环境中的化学溶液和物质的温度。 使用此传感器的优势之一是我们只需要 ESP 板上的一个引脚即可传

    2024年02月07日
    浏览(42)
  • DS18B20与单片机的通信、DS18B20采集温度、MODBUS协议、练习框架

    单总线数字温度计 异步的半双工的串行通信 测量范围从-55℃ ~ +125℃,增量值为0.5℃ 要用DS18B20采集温度,就要实现与单片机之间的通信,因此有两个问题 Bus master active low:主机执行低电平 DS1820 active low:DS18B20执行低电平 Both bus master and DS1820 active low:全都释放低电平 Resis

    2024年04月16日
    浏览(46)
  • 【TB作品】MSP430单片机 Proteus仿真 DS18B20温度 LCD1602显示器 温度读取与显示

    效果图如下: 首先,让我们先来说说DS18B20集成电路。 • DS18B20是一款采用OneWire通讯协议的集成电路,因此只需要一条线就可以与微控制器通讯。它不需要额外的电源,但是也有外部电源输入端口。 • OneWire设备具有64位的ROM代码。如我们之前所说,这64位的前8位是家族代码,中间

    2024年02月08日
    浏览(69)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包