stm32中ds18b20读ID以及温湿度的获取(详细)

一、DS18B20是什么?

是常用的数字温度传感器,其输出的是数字信号,具有体积小,硬件开销低,抗干扰能力强,精度高的特点。DS18B20数字温度传感器接线方便,封装成后可应用于多种场合,如管道式,螺纹式,磁铁吸附式,不锈钢封装式,型号多种多样。

二、主要参数

1.独特的单线接口方式,DS18B20在与微处理器连接时仅需要一条口线即可实现微处理器与DS18B20的双向通讯。
2.测温范围 -55℃~+125℃,固有测温误差(注意,不是分辨率,这里之前是错误的)1℃。
3.支持多点组网功能,多个DS18B20可以并联在唯一的三线上,最多只能并联8个,实现多点测温,如果数量过多,会使供电电源电压过低,从而造成信号传输的不稳定。
4.工作电源: 3.0~5.5V/DC (可以数据线寄生电源)
5.在使用中不需要任何外围元件
6.测量结果以9~12位数字量方式串行传送
7.不锈钢保护管直径 Φ6
8.适用于DN15~25, DN40~DN250各种介质工业管道和狭小空间设备测温
9.标准安装螺纹 M10X1, M12X1.5, G1/2”任选

三、基于嵌入式的使用步骤(以STM32F1X为例)

在我使用的STM32F103ZET6中,DS18B20的电源电压选择为3.3V,5V电压不能工作。
根据时序图来进行配置和初始化。
在这里插入图片描述

下面展示ds18b20.h的完整代码

#ifndef _DS18B20_H
#define _DS18B20_H

#include "stm32l0xx.h"

uint64_t ds18b20_get_id(void);
void bsp_InitDS18B20(void);
int16_t DS18B20_ReadTempReg(void);
uint64_t DS18B20_Get_ID(void);
int DS18B20_ReadTempByID(uint8_t _id);

#if defined USEID
int DS18B20_ReadTemperatureByROMCodes(uint8_t groupid,uint8_t *iRomCode);
#endif

#endif

下面展示 ds18b20.c完整代码。

#include "ds18b20.c"
#include "main.h"
#include "ds18b20.h"
#include "timer.h"

注意:uint8_t 包含的头文件是在我写的main.h里面的 #include <stdint.h>
我用的不是标准库,而是HAL库,所以里面还有 #include “stm32l0xx_hal.h”
我的延时函数delay_us()被包含在#include "timer.h"里面,你们可以自己调用自己的延时函数头文件

下面是通过寄存器来配置GPIO口,你们也可以通过函数来配置,只要能达到相应的功能就行

GPIO_TypeDef* PORT_DQ = NULL;//GPIO_InitTypeDef
uint16_t  PIN_DQ  = NULL;
	
#define DQ_0()		PORT_DQ->BRR = PIN_DQ   //设置某个IO口为低电平
#define DQ_1()		PORT_DQ->BSRR = PIN_DQ  //设置某个IO口为高电平

/* 判断DQ输入是否为低 */
#define DQ_IS_LOW()	((PORT_DQ->IDR & PIN_DQ) == 0)
/*
*********************************************************************************************************
*	函 数 名: DS18B20_Reset
*	功能说明: 复位DS18B20。 拉低DQ为低,持续最少480us,然后等待
*	形    参: 无
*	返 回 值: 0 失败; 1 表示成功
*********************************************************************************************************
*/
uint8_t DS18B20_Reset(void)
{
   
	/*
		复位时序, 见DS18B20 page 15

		首先主机拉低DQ,持续最少 480us
		然后释放DQ,等待DQ被上拉电阻拉高,约 15-60us
		DS18B20 将驱动DQ为低 60-240us, 这个信号叫 presence pulse  (在位脉冲,表示DS18B20准备就绪 可以接受命令)
		如果主机检测到这个低应答信号,表示DS18B20复位成功
	*/

	uint8_t i;
	uint16_t k;

	/* 复位,如果失败则返回0 */
	for (i = 0; i < 1; i++)
	{
   
		DQ_0();				/* 拉低DQ */
		delay_us(520);	    /* 延迟 520uS, 要求这个延迟大于 480us */
		DQ_1();				/* 释放DQ */
		delay_us(60);	    /* 等待15us-60us */

		/* 检测DQ电平是否为低 */
		for (k = 0; k < 24; k++)//60-240us
		{
   
			if (DQ_IS_LOW())
			{
   
				break;
			}
			delay_us(10);	/* 等待65us */
		}
		if (k >= 24)
		{
   
			continue;		/* 失败 */
		}

		/* 等待DS18B20释放DQ */
		for (k = 0; k < 41; k++)
		{
   	
			delay_us(10);	/* 等待至少405us */
		}
		if (
  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
DS18B20是一种数字温度传感器,可以通过一根单总线线路进行通信。在STM32使用DS18B20需要先了解其通信协议,然后编写对应的程序。 DS18B20通信协议基于1-Wire总线,需要使用STM32的GPIO来模拟1-Wire总线。具体的通信流程如下: 1. 发送复位信号(reset):主机(STM32)拉低总线,持续时间大于480us,然后释放总线,等待DS18B20拉低总线表示接收到复位信号。 2. 发送指令(command):主机发送指令(例如取温度),指令由8位二进制数据组成,每一位都要在60us内完成发送和接收。 3. DS18B20响应:DS18B20在接收到指令后,会发送响应信号(response),拉低总线15-60us,然后释放总线。 4. 数据传输:主机发送和接收数据,数据由8位二进制数据组成,每一位都要在60us内完成发送和接收。 5. 延时:在每一步操作后,需要等待一定的时间,从而等待DS18B20完成相应的操作。 下面是一个简单的STM32程序,用于DS18B20的温度: ```c #include "stm32f10x.h" #define DS18B20_GPIO GPIOA #define DS18B20_PIN GPIO_Pin_1 void delay_us(uint16_t us) { uint16_t i; while(us--) { i = 10; // 这里的延时是根据CPU的主频来计算的,需要根据实际情况进行调整 while(i--); } } void ds18b20_reset(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_GPIO, &GPIO_InitStructure); GPIO_ResetBits(DS18B20_GPIO, DS18B20_PIN); delay_us(500); GPIO_SetBits(DS18B20_GPIO, DS18B20_PIN); delay_us(100); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(DS18B20_GPIO, &GPIO_InitStructure); while(GPIO_ReadInputDataBit(DS18B20_GPIO, DS18B20_PIN) == Bit_RESET); while(GPIO_ReadInputDataBit(DS18B20_GPIO, DS18B20_PIN) == Bit_SET); } void ds18b20_write_byte(uint8_t byte) { uint8_t i; for(i = 0; i < 8; i++) { 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_GPIO, &GPIO_InitStructure); GPIO_ResetBits(DS18B20_GPIO, DS18B20_PIN); if(byte & (1 << i)) { delay_us(5); GPIO_SetBits(DS18B20_GPIO, DS18B20_PIN); delay_us(80); } else { delay_us(80); GPIO_SetBits(DS18B20_GPIO, DS18B20_PIN); delay_us(5); } } } uint8_t ds18b20_read_byte(void) { uint8_t i, byte = 0; for(i = 0; i < 8; i++) { 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_GPIO, &GPIO_InitStructure); GPIO_ResetBits(DS18B20_GPIO, DS18B20_PIN); delay_us(2); GPIO_SetBits(DS18B20_GPIO, DS18B20_PIN); GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; GPIO_Init(DS18B20_GPIO, &GPIO_InitStructure); if(GPIO_ReadInputDataBit(DS18B20_GPIO, DS18B20_PIN) == Bit_SET) { byte |= (1 << i); } delay_us(60); } return byte; } float ds18b20_read_temperature(void) { uint8_t temp_l, temp_h; float temp; ds18b20_reset(); ds18b20_write_byte(0xcc); ds18b20_write_byte(0x44); delay_us(750); ds18b20_reset(); ds18b20_write_byte(0xcc); ds18b20_write_byte(0xbe); temp_l = ds18b20_read_byte(); temp_h = ds18b20_read_byte(); temp = (temp_h << 8) | temp_l; temp = temp * 0.0625; return temp; } int main(void) { float temperature; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); while(1) { temperature = ds18b20_read_temperature(); // 这里可以将温度值通过串口或LCD等方式显示出来 } } ``` 在这个程序ds18b20_reset()函数用于发送复位信号,ds18b20_write_byte()函数用于发送指令和数据,ds18b20_read_byte()函数用于接收数据,ds18b20_read_temperature()函数用于DS18B20的温度。在主函数,不断取温度并将其显示出来。 需要注意的是,这个程序的延时函数是通过循环来实现的,需要根据实际情况进行调整。另外,DS18B20的通信速度较慢,每次取温度需要耗费一定的时间,因此需要考虑如何优化程序性能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值