STM32F1使用HAL库驱动DS18B20

这篇具有很好参考价值的文章主要介绍了STM32F1使用HAL库驱动DS18B20。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

DS18B20概述

工程配置

 命令手册

单总线协议

 初始化时序

 写时序

读时序

读取温度

驱动附录


DS18B20概述

hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件

 DS18B20是一款单总线(one wire)芯片,因此其DQ引脚与单片机相连的IO口既要是输入也要是输出,cubeMX的初始化引脚设置只能选择其一,这里我们使用手动配置引脚。

工程配置

先用cubeMX生成一个工程模板,初始化时钟等等。

hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件

 命令手册

hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件

 这里有两个重要的指令,0x44表示触发芯片进行温度转化,0xbe表示请求读取温度转化后的值。

hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件

还有一个常用指令为0xCC,意义是跳过读取芯片ROM而节约时间。

单总线协议

由于是单总线协议,要想写指令,收数据都要遵循其标准,下面查看其时序

 初始化时序

hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件

单片机将DQ线拉低480us至960us后释放总线,ds18b20检测到总线电平变化,会等待15-60us,这段时间总线电平被电阻拉高,然后ds18b20会将总线拉低60-240us,作为应答信号,表明总线上存在ds18b20芯片。然后ds18b20释放总线,电阻将总线拉高。

整个过程为初始化

代码如下

void onewire_init()
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	__HAL_RCC_GPIOB_CLK_ENABLE();
	GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pin=GPIO_PIN_9;
	GPIO_InitStruct.Pull=GPIO_NOPULL;
	GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
	HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
	HAL_Delay_us(500);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);
	HAL_Delay_us(50);
	
	onewire_release();
	HAL_Delay_us(500);
}

用逻辑分析仪检测如下

hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件

实际应答时间约为110us 

 写时序

hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件

写时序分为写0时序和写1时序.

写0时序

单片机拉低总线,产生一个下降沿并保持总线低电平60us-120us,在这期间,18b20会在下降沿出现后大约15us-60us内读取总线电平。然后单片机释放总线,由上拉电阻拉高,直至下一次写时序,这段时间为恢复时间,需要大于1us

写1时序

单片机拉低总线,产生一个下降沿并保持总线低电平1-15us,在这期间,18b20会在下降沿出现后大约15us-60us内读取总线电平。然后单片机释放总线,由上拉电阻拉高,直至下一次写时序,这段时间为恢复时间,需要大于1us

void onewire_write(uint8_t dat)
{
	onewire_hold();
	if(dat==0)
	{
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
		HAL_Delay_us(60);
		onewire_release();
		HAL_Delay_us(2);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
		HAL_Delay_us(2);
		onewire_release();
		HAL_Delay_us(60);
	}
}

hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件

读时序

hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件

 hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件

读时序分为读0时序和读1时序

读0时序

单片机拉低总线并至少保持1us的总线低电平,然后释放总线,此时总线电平将由18b20决定,单片机在下降沿后15us处读取总线电平值,为低电平

读1时序

单片机拉低总线并至少保持1us的总线低电平,然后释放总线,此时总线电平将由18b20决定,单片机在下降沿后15us处读取总线电平值,为高电平

uint8_t onewire_read()
{
	uint8_t t;
	onewire_hold();
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
	HAL_Delay_us(2);
	onewire_release();
	HAL_Delay_us(12);
	t=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9);
	HAL_Delay_us(50);
	return t;
}

读取温度

float ds18b20_getTemp()
{
	uint16_t temp;
	float value;
	uint8_t lsb,msb;
	onewire_init();
	onewire_sendbyte(0xcc);
	onewire_sendbyte(0x44);
	HAL_Delay(750);
	onewire_init();
	onewire_sendbyte(0xcc);
	onewire_sendbyte(0xbe);
	lsb=onewire_readbyte();
	msb=onewire_readbyte();
	temp=msb;
	temp=(temp<<8)+lsb;
    if((temp&0xf800)==0xf800)
	{
		temp=(~temp)+1;
		value=temp*(-0.0625);
	}
	else
	{
		value=temp*0.0625;	
	}
	return value;	
}

逻辑分析仪波形

hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件

 上图为开启温度转化的引脚逻辑电平变化

hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件

上图为读取温度值

读取到的值为0000 0001 1011 1110

hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件

 由图可知为16*1+8*1+2*1+1*1+0.5+0.25+0.125=27.875°C

与串口显示温度值一致

hal库ds18b20,STM32单片机,stm32,单片机,嵌入式硬件

 至此,ds18b20的温度转化,温度读取已经完成

驱动附录

onewire.c

#include "onewire.h"

void HAL_Delay_us(uint32_t nus)
{
	uint32_t ticks;
	uint32_t told,tnow,tcnt=0;
	uint32_t reload=SysTick->LOAD;
	ticks=nus*72;
	told=SysTick->VAL;
	while(1)
	{
		tnow=SysTick->VAL;
		if(tnow!=told)
		{
			if(tnow<told)tcnt+=told-tnow;
			else tcnt+=reload-tnow+told;
			told=tnow;
			if(tcnt>=ticks)break;
		}
	}
}
void onewire_release()
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Mode=GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull=GPIO_NOPULL;
	GPIO_InitStruct.Pin=GPIO_PIN_9;
	GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
	HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
}
void onewire_hold()
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pin=GPIO_PIN_9;
	GPIO_InitStruct.Pull=GPIO_PULLUP;
	GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
	HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
}
void onewire_init()
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	__HAL_RCC_GPIOB_CLK_ENABLE();
	GPIO_InitStruct.Mode=GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pin=GPIO_PIN_9;
	GPIO_InitStruct.Pull=GPIO_NOPULL;
	GPIO_InitStruct.Speed=GPIO_SPEED_HIGH;
	HAL_GPIO_Init(GPIOB,&GPIO_InitStruct);
	
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
	HAL_Delay_us(500);
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_SET);
	HAL_Delay_us(50);
	
	onewire_release();
	HAL_Delay_us(500);
}

void onewire_write(uint8_t dat)
{
	onewire_hold();
	if(dat==0)
	{
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
		HAL_Delay_us(60);
		onewire_release();
		HAL_Delay_us(2);
	}
	else
	{
		HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
		HAL_Delay_us(2);
		onewire_release();
		HAL_Delay_us(60);
	}
}

uint8_t onewire_read()
{
	uint8_t t;
	onewire_hold();
	HAL_GPIO_WritePin(GPIOB,GPIO_PIN_9,GPIO_PIN_RESET);
	HAL_Delay_us(2);
	onewire_release();
	HAL_Delay_us(12);
	t=HAL_GPIO_ReadPin(GPIOB,GPIO_PIN_9);
	HAL_Delay_us(50);
	return t;
}

void onewire_sendbyte(uint8_t dat)
{
	uint8_t i;
	for(i=0;i<8;i++)
	{
		if((dat&0x01)==1)
			onewire_write(1);
		else
			onewire_write(0);
		dat=dat>>1;
	}
}
uint8_t onewire_readbyte(void)    // read one byte
{        
    uint8_t i,j,dat;
    dat=0;
	for (i=1;i<=8;i++) 
	{
        j=onewire_read();
        dat=(j<<7)|(dat>>1);
    }						    
    return dat;
}

onewire.h

#ifndef ONEWIRE_H
#define ONEWIRE_H
#include "main.h"
void onewire_init();
void onewire_write(uint8_t dat);
uint8_t onewire_read();
uint8_t onewire_readbyte(void);
void onewire_sendbyte(uint8_t dat);
#endif

ds18b20.c

#include "ds18b20.h"
#include "onewire.h"
void ds18b20_init()
{
	onewire_init();
}
float ds18b20_getTemp()
{
	uint16_t temp;
	float value;
	uint8_t lsb,msb;
	onewire_init();
	onewire_sendbyte(0xcc);
	onewire_sendbyte(0x44);
	HAL_Delay(750);
	onewire_init();
	onewire_sendbyte(0xcc);
	onewire_sendbyte(0xbe);
	lsb=onewire_readbyte();
	msb=onewire_readbyte();
	temp=msb;
	temp=(temp<<8)+lsb;
    if((temp&0xf800)==0xf800)
	{
		temp=(~temp)+1;
		value=temp*(-0.0625);
	}
	else
	{
		value=temp*0.0625;	
	}
	return value;
	
}

ds18b20.h文章来源地址https://www.toymoban.com/news/detail-757354.html

#ifndef DS18B20_H
#define DS18B20_H
#include "main.h"

void ds18b20_init();
float ds18b20_getTemp();
#endif

到了这里,关于STM32F1使用HAL库驱动DS18B20的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【正点原子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日
    浏览(40)
  • STM32——DS18B20温度传感器

    一、DS18B20介绍 (一)DS18B20技术性能特征 1、独特的单总线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯,大大提高了系统的抗干扰性。 2、测温范围  -55°C~+125°C 3、支持多点组网功能,多个DS18B20可以并联在唯一的三线上,最多只

    2024年01月19日
    浏览(32)
  • STM32读取DS18B20温度,并在OLED上显示

    部分代码来源于网络,侵权删 本文使用硬件:STM32F103C8T6最小系统板、IIC协议0.96寸OLED屏幕显示、DS18B20传感器  实现功能:在OLED上显示出DS18B20采集到的温度,精确到小数点后一位。 DS18B20.c DS18B20.h main.c 实物效果图: 工程文件百度网盘链接:链接:https://pan.baidu.com/s/17QLXeaq2

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

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

    2024年02月07日
    浏览(34)
  • STM32CubeMX 读取DS18B20温度传感器数据串口打印显示

    本文要做的所有工作标题基本都包括了,读取温度传感器的温度数值,再通过串口打印到串口助手; 好多博主大神的教程我按步骤做了之后总是出现程序不报错并且检测不到传感器的情况,后来找到原因并且修改后调试正常。 我用的是普中科技的实验板,主控芯片为STM3210

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

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

    2024年02月15日
    浏览(27)
  • 通过stm32读取DS18B20并在显示屏上显示温度值(附源码)

    使用stm32f103c8t6的芯片,在OLED显示屏上显示DS18B20的温度值。 DS18B20 数字温度计提供 9 位温度读数,指示器件的温度信息经过单线接口送入 DS18B20 或从 DS18B20 送出, 因此从中央处理器到 DS18B20 仅需连接一条线。 读、写和完成温度变换所需的电源可以由数据线本身提供而不需要外

    2024年02月15日
    浏览(26)
  • 单片机驱动多个ds18b20

    目录 1设计内容 2ds18b20介绍 2.1传感器引脚及原理图 2.2寄存器配置 3程序实现 3.1配置初始化 3.2配置寄存器 3.3ROM读取 3.4温度读取 通过51单片机,读取总线上挂载的多个ds18b20的温度信息。 如下图,成功读取到3路温度数据。 DS18B20传感器的引脚及封装图如下: DS18B20一共有三个引脚

    2024年02月21日
    浏览(25)
  • Linux下ds18b20驱动开发获取温度

    对ds18b20不了解的可以查看这篇文章,讲解的比较详细的:STM32一线协议-DS18B20温度传感器采样实现 源码是根据上一届学长的,想要参考的可以去拜访一下gitee:代码链接 (1)修改设备树 在路径 linux-imx/arch/arm/boot/dts/ 下修改设备树 igkboard.dts : 主节点: 从节点: 在源码路径下

    2023年04月22日
    浏览(67)
  • DS18B20使用说明

    基础介绍引脚介绍 DS18B20是单总线协议的典型代表,同时也是单总线协议最广泛的应用场景,是常用的数字温度传感器,其输出的是数字信号。具有体积小,硬件开销低,抗干扰能力强,精度高的特点。DS18B20数字温度传感器接线方便,封装成后可应用于多种场合。 DS18B20 的温

    2024年02月09日
    浏览(24)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包