普中STM32-PZ6806L开发板(HAL库函数实现-访问多个温度传感器DS18B20)

简介

我们知道多个DS18B20的DQ线是可以被挂在一起的, 也就是一根线上可以访问不同的DS18B20而不会造成数据错乱, 怎么做到的,其实数据手册都有说到, 就是靠64-bit ROM code 进行识别, 也可以理解成Serial Number进行识别, 因为主要差异还是在Serial Number上面;

电路图

两个DS18B20连接到一起
在这里插入图片描述

实现步骤

创建项目

基于 上一篇 普中STM32-PZ6806L开发板(HAL库函数实现-温度传感器DS18B20)

添加用户代码

获取DS18B20的Serial Number信息, 然后记录下来, 用于向指定DS18B20获取温度值

typedef struct 
{uint8_t familyCode;uint8_t sns[6];uint8_t crc;
} SENSOR_DS18B20_SerialNumberInfo;SENSOR_DS18B20_SerialNumberInfo SENSOR_DS18B20_GetSN(void)
{SENSOR_DS18B20_SerialNumberInfo info;uint8_t recvs[8] = { 0 };SENSOR_DS18B20_Reset ();HAL_Delay (1);SENSOR_DS18B20_Write (0x33);  // read romHAL_Delay (1);// 1 byte -> family code// 2 ~ 7 byte -> serial number//  8 byte -> CRC8	recvs[0] = SENSOR_DS18B20_Read(); // family codeinfo.familyCode = recvs[0];for (int i = 0; i < 6; ++i) // serial number{ recvs[i+1] = SENSOR_DS18B20_Read();info.sns[i] = recvs[i+1];}recvs[7] = SENSOR_DS18B20_Read(); // CRC8info.crc = recvs[7];if (SENSOR_DS18B20_CRC8(recvs, 7) != recvs[7]) // CRC8 检查{info.familyCode = 0;memset(info.sns, 0, sizeof(info.sns)/sizeof(uint8_t));info.crc = 0; return info; // CRC校验不一致}return info;
}

实现流程参考pdf
在这里插入图片描述
实现代码

/* 两个DS18B20设备 */
#include <stdio.h>
#include <string.h>/* DS18B20, 提前读取出来的SN&familyCode&CRC码 */
SENSOR_DS18B20_SerialNumberInfo  ds18b20_infos[] = 
{{ 0x28, { 0x2E, 0x7C, 0x04, 0x05, 0x00, 0x00 }, 0xCC },{ 0x28, { 0x2F, 0x7D, 0x10, 0x02, 0x01, 0x00 }, 0xBE }
};/* 引脚重新设置为输入 */
static void SENSOR_DS18B20_SetPinInput(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{GPIO_InitTypeDef GPIO_InitStruct;GPIO_InitStruct.Pin = GPIO_Pin;GPIO_InitStruct.Mode = GPIO_MODE_INPUT;GPIO_InitStruct.Pull = GPIO_NOPULL;HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
}
/* 引脚重新设置为输出 */
static void SENSOR_DS18B20_SetPinOutput(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin)
{GPIO_InitTypeDef  GPIO_InitStruct;GPIO_InitStruct.Pin = GPIO_Pin;GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;HAL_GPIO_Init(GPIOx, &GPIO_InitStruct);
}/*SENSOR_DS18B20_Reset :初始化,也是复位, 每次发送指令前的动作0 : 初始化失败1 : 初始化成功
*/
static uint8_t SENSOR_DS18B20_Reset(void)
{uint8_t res = 0;SENSOR_DS18B20_SetPinOutput(DS18B20_PORT, DS18B20_PIN);   // 引脚输出模式HAL_GPIO_WritePin (DS18B20_PORT, DS18B20_PIN, 0);  // 拉低引脚delay_us (480);   // 参考初始化时序图, 延时480usSENSOR_DS18B20_SetPinInput(DS18B20_PORT, DS18B20_PIN);    // set the pin as inputdelay_us (60);    // 15~60us等待DS18B20回复信息, 多等20us避免检测不到if ( !HAL_GPIO_ReadPin(DS18B20_PORT, DS18B20_PIN) )res = 1;  // 检测到低电平,  DS18B20有响应else res = 0;delay_us (420); // 等待DS18B20结束响应return res;
}/* 写流程 */
void SENSOR_DS18B20_Write(uint8_t data)
{/*按位写, 根据时序图, 按照写的 高电平的时序 和 低电平的时序进行延时*/for (int i = 0; i < 8; ++i){if ((data & (1<<i))!=0) // 写1{SENSOR_DS18B20_SetPinOutput(DS18B20_PORT, DS18B20_PIN);  HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, 0);  // 拉低delay_us (2);  // 低电平保持时间SENSOR_DS18B20_SetPinInput(DS18B20_PORT, DS18B20_PIN);  // 输入delay_us (60);  // 等待}else // 写0{SENSOR_DS18B20_SetPinOutput(DS18B20_PORT, DS18B20_PIN);HAL_GPIO_WritePin (DS18B20_PORT, DS18B20_PIN, 0);  // 拉低delay_us (60);  // 等待60usSENSOR_DS18B20_SetPinInput(DS18B20_PORT, DS18B20_PIN); // 输入}}
}
/* 读流程 */
uint8_t SENSOR_DS18B20_Read (void)
{uint8_t value = 0;SENSOR_DS18B20_SetPinOutput(DS18B20_PORT, DS18B20_PIN);for (int i=0;i<8;i++){SENSOR_DS18B20_SetPinOutput(DS18B20_PORT, DS18B20_PIN);HAL_GPIO_WritePin(DS18B20_PORT, DS18B20_PIN, 0);  // 拉低delay_us(2);  // 拉低电平等待时间SENSOR_DS18B20_SetPinInput(DS18B20_PORT, DS18B20_PIN);if (HAL_GPIO_ReadPin (DS18B20_PORT, DS18B20_PIN))  {value |= 1<<i;  }delay_us (60);  // DS18B20数据响应时间}return value;
}/* 计算CRC码 */
uint8_t SENSOR_DS18B20_CRC8(uint8_t *dats, uint8_t len) 
{uint8_t i, dat, crc, fb, st_byt;st_byt = 0;crc = 0;do {dat = dats[st_byt];for (i = 0; i < 8; i++) {  fb = crc ^ dat;fb &= 1;crc >>= 1;dat >>= 1;if (fb == 1) crc ^= 0x8c; }st_byt++;} while (st_byt < len); return crc;
}/* 获取Serial Number&CRC&family Code */
SENSOR_DS18B20_SerialNumberInfo SENSOR_DS18B20_GetSN(void)
{SENSOR_DS18B20_SerialNumberInfo info;uint8_t recvs[8] = { 0 };SENSOR_DS18B20_Reset ();HAL_Delay (1);SENSOR_DS18B20_Write (0x33);  // read romHAL_Delay (1);// 1 byte -> family code// 2 ~ 7 byte -> serial number//  8 byte -> CRC8	recvs[0] = SENSOR_DS18B20_Read(); // family codeinfo.familyCode = recvs[0];for (int i = 0; i < 6; ++i) // serial number{ recvs[i+1] = SENSOR_DS18B20_Read();info.sns[i] = recvs[i+1];}recvs[7] = SENSOR_DS18B20_Read(); // CRC8info.crc = recvs[7];if (SENSOR_DS18B20_CRC8(recvs, 7) != recvs[7]) // CRC8 检查{info.familyCode = 0;memset(info.sns, 0, sizeof(info.sns)/sizeof(uint8_t));info.crc = 0; return info; // CRC校验不一致}return info;
}/* 写Serial Number&CRC&family Code */
void SENSOR_DS18B20_WriteID(uint8_t index) 
{uint8_t id_data[8];id_data[0] = ds18b20_infos[index].familyCode;id_data[7] = ds18b20_infos[index].crc;for ( int i = 1; i < 7; ++i ){id_data[i] = ds18b20_infos[index].sns[i-1];}SENSOR_DS18B20_Reset (); SENSOR_DS18B20_Write (0x55);  // skip ROM; //Match ROM [55h]for ( int i = 0; i < 8; i++ ){SENSOR_DS18B20_Write(id_data[i]);}
}/* 等待电平被拉高 */
void SENSOR_DS18B20_WaitForHigh(uint32_t time) 
{SENSOR_DS18B20_SetPinInput(DS18B20_PORT, DS18B20_PIN);delay_us(time);while(HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_9) == 0);SENSOR_DS18B20_SetPinOutput(DS18B20_PORT, DS18B20_PIN);
}/* 将读取值转化成温度值 */
float SENSOR_DS18B20_ValueToTemperature(uint8_t lsb, uint8_t msb)
{uint16_t temp = 0;temp = (msb << 8) + lsb;if((temp&0xf800)==0xf800) // 符号位判定是否负数{temp=(~temp)+1; // 补码转原码return temp*(-0.0625); //12bit 增量值}else{return temp*0.0625;	//12bit 增量值}
}/* 通过serial number数据获取温度 */
float SENSOR_DS18B20_GetTemperatureByID(uint8_t ds18b20_index)
{uint8_t recv_data[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // 9 Bytesuint8_t ds18b20_num = sizeof(ds18b20_infos) / sizeof(SENSOR_DS18B20_SerialNumberInfo);uint16_t temp = 0;if ( ds18b20_index >= ds18b20_num )return 0; // 不存在此设备SENSOR_DS18B20_Reset ();HAL_Delay (1);SENSOR_DS18B20_WriteID(ds18b20_index);SENSOR_DS18B20_Write(0x44);//Convert Temperature [44h]SENSOR_DS18B20_WaitForHigh(20);SENSOR_DS18B20_Reset ();SENSOR_DS18B20_WriteID(ds18b20_index);SENSOR_DS18B20_Write(0xBE);//Read Scratchpad [BEh]for (uint8_t i = 0; i < 9; i++){recv_data[i] = SENSOR_DS18B20_Read();}return SENSOR_DS18B20_ValueToTemperature(recv_data[0], recv_data[1]);
}

代码

无需下载, 代码上面基本都提供了

Note:
支持你的DS18B20, 你需要修改, 改成你的DS18B20的信息
SENSOR_DS18B20_SerialNumberInfo ds18b20_infos[] =
{
{ 0x28, { 0x2E, 0x7C, 0x04, 0x05, 0x00, 0x00 }, 0xCC },
{ 0x28, { 0x2F, 0x7D, 0x10, 0x02, 0x01, 0x00 }, 0xBE }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/597246.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

本地git服务器的使用

最后总结一句&#xff0c;用gitlab最省事&#xff0c;管理权限最方便&#xff0c;别像下文一样整了。 Windows上使用&#xff1a; 首先要在windows开发机上生成密钥&#xff1a; 1.安装git&#xff0c;首先去git官网下载git&#xff0c;https://git-scm.com/downloads&#xff…

初学者SkyWalking详细使用文档

SkyWalking使用文档 下载地址&#xff1a;https://skywalking.apache.org/downloads/ 主要下载&#xff1a;skywalking apm&#xff08;tar&#xff09; 、agents(tar) 解压&#xff1a; &#xff08;可选操作&#xff09;&#xff1a; ​ apache-skywalking-apm-bin --&g…

chromium在中文用户名下无法编译的问题

新电脑没有太注意&#xff0c;起用户名的时候用了中文。 在编译chromium104的代码时&#xff0c;因为环境变量有中文导致编译失败&#xff1a; 因为我的电脑默认是使用gbk编码&#xff0c;而不是utf-8编码。 这个问题有三种解决办法&#xff1a; &#xff08;一&#xff09;把…

MySQL——事物

目录 一.发现问题 二.什么时事物 三.事务提交方式 四.事物的常规操作方式 五. 事务隔离级别 1.如何理解隔离性 2.隔离级别 3.查看与设置隔离性 4.读未提交【Read Uncommitted】 5.读提交【Read Committed】 6.可重复读【Repeatable Read】 7.串行化【serializabl…

云卷云舒:大型电信运营商应用软件健康度评估方法

大型电信运营商内均会自建云资源池&#xff0c;并基于云资源池构建自己上层应用软件资源&#xff0c;但是各类上层应用软件的故障频发也给运维工作带来了较大的压力&#xff0c;电信运营商急需一种较完善的方法实现对于应用软件的健康度评测&#xff0c;以进一步指导运维完成应…

unity C# 中一看就会的try-catch-finally、throw

文章目录 1、C# 异常处理原理&#xff1a;2、C# 异常处理实用案例&#xff08;简化版示例&#xff09;&#xff1a;3、throw关键字 C# 异常处理是一种用于捕获和处理程序运行时错误的机制&#xff0c;它允许程序在遇到不可预见或非正常条件时进行优雅地恢复或失败。C# 中的异常…

Rust 圣经 阅读 字符、布尔、单元类型

字符类型&#xff08;char&#xff09; Rust 的字符不仅仅是 ASCII &#xff0c;还包含所有的 Unicode 值&#xff0c;包括单个的中文、日文、表情符号等等。 Unicode 值的范围从 U0000 ~ UD7FF 和 UE000 ~ U10FFFF。 因为每个 Unicode 都是 4 个字节编码&#xff0c;所以字符…

知虾皮Shopee:东南亚最受欢迎的电子商务平台

在如今数字化时代&#xff0c;电子商务平台成为人们购物的首选方式。Shopee作为东南亚地区最受欢迎的电子商务平台&#xff0c;通过其多样化的商品、便捷的购物体验和创新的商业模式&#xff0c;迅速在该地区占据了重要地位。本文将详细介绍Shopee的特点和优势&#xff0c;以及…

设计模式 七大原则

1.单一职责原则 单一职责原则&#xff08;SRP&#xff1a;Single responsibility principle&#xff09;又称单一功能原则 核心&#xff1a;解耦和增强内聚性&#xff08;高内聚&#xff0c;低耦合&#xff09;。 描述&#xff1a; 类被修改的几率很大&#xff0c;因此应该专注…

CNN——VGG

1.VGG简介 论文下载地址&#xff1a;https://arxiv.org/pdf/1409.1556.pdf VGGNet 是由牛津大学视觉几何小组&#xff08;Visual Geometry Group, VGG&#xff09;提出的一种深层卷积网络结构&#xff0c;他们以 7.32% 的错误率赢得了 2014 年 ILSVRC 分类任务的亚军&#xff…

2024年MySQL学习指南(二),探索MySQL数据库,掌握未来数据管理趋势

文章目录 前言4. DDL- 操作数据库4.1 查询4.2 创建数据库4.3 删除数据库4.4 使用数据库 5. DDL- 操作数据表5.1 数据类型5.2 查询表5.3 创建表5.4 删除表5.5 修改表 6. 实战案例详解 前言 接上一篇文章【2024年MySQL学习指南&#xff08;一&#xff09;】 4. DDL- 操作数据库 …

2023-2024 年广东省职业院校技能大赛高职组 “软件测试”赛项竞赛规程

2023-2024 年广东省职业院校技能大赛&#xff08;高职组&#xff09; “软件测试”赛项竞赛规程 一、赛项信息 赛项名称&#xff1a;软件测试 赛项编号&#xff1a;GZ034 赛项组别&#xff1a;高职组 二、竞赛目标 软件是新一代信息技术的灵魂&#xff0c;是数字经济发展的基础…

LeetCode 每日一题 Day 32 ||递归单调栈

2487. 从链表中移除节点 给你一个链表的头节点 head 。 移除每个右侧有一个更大数值的节点。 返回修改后链表的头节点 head 。 示例 1&#xff1a; 输入&#xff1a;head [5,2,13,3,8] 输出&#xff1a;[13,8] 解释&#xff1a;需要移除的节点是 5 &#xff0c;2 和 3 。…

大数据 - Doris系列《二》- Doris安装(亲测成功版)

目录 &#x1f436;2.1 安装前准备 &#x1f959;1.设置系统最大文件打开句柄数 >启动一个程序的时候&#xff0c;打开文件的数量就是句柄数 &#x1f959;3.时钟同步 &#x1f959;4.关闭交换分区&#xff08;swap&#xff09; &#x1f436;2.2 安装FE &#x1f436…

论文悦读(7)——NVM文件系统之Trio(SOSP‘23)文件系统

TRIO&#xff08;SOSP23&#xff09; 1. 背景&#xff08;Background&#xff09;1.1 NVM Technologis1.2 File System Customization1.3 Userspace NVM File Systems 2. 观察与动机&#xff08;Observation & Motivation&#xff09;3. 设计与实现&#xff08;Design &…

JMeter 插件大全:详细介绍 Jmeter 常用插件

JMeter作为一个开源的接口性能测试工具&#xff0c;其本身的小巧和灵活性给了测试人员很大的帮助&#xff0c;但其本身作为一个开源工具&#xff0c;相比于一些商业工具&#xff08;比如 LoadRunner&#xff09;&#xff0c;在功能的全面性上就稍显不足。这篇博客&#xff0c;就…

傅里叶级数、傅里叶变换、小波变换、离散余弦变换的理解

目录 1. 傅里叶级数2.傅里叶变换 1. 傅里叶级数 功能&#xff1a;能把任意周期性函数展开成一系列正弦、余弦函数的和。 公式&#xff1a; f ( x ) a 0 2 ∑ n 1 ∞ ( a n cos ⁡ ( 2 π n x T ) b n sin ⁡ ( 2 π n x T ) ) 傅里叶系数 a n 2 T ∫ x 0 x 0 T f ( x )…

网络安全|2024年需要重点关注的10种DNS攻击类型

目前&#xff0c;针对域名系统&#xff08;DNS&#xff09;的攻击已经成为企业组织数字化发展中的一个严重问题&#xff0c;每年都有数千个网站成为此类攻击的受害者。据最近的研究数据显示&#xff0c;2023年企业组织与DNS攻击相关的损失同比增加了49%&#xff0c;这些损失不仅…

即时设计:一键查看设计稿与页面差异,让设计师的工作更便捷高效

设计稿走查 在设计工作中&#xff0c;对设计稿和实际页面进行对比是必不可少的环节。然而&#xff0c;传统的对比方式往往耗时耗力&#xff0c;无法精确测量差异。为了解决这个问题&#xff0c;我们推出了一款强大的工具&#xff0c;它可以通过图片对比&#xff0c;轻松查看设…

使用results.csv文件数据绘制mAP对比图

yolov5每次train完成&#xff08;如果没有中途退出&#xff09;都会在run目录下生成expX目录&#xff08;X代表生成结果次数 第一次训练完成生成exp0 第二次生成exp1…以此类推&#xff09;。expX目录下会保存训练生成的weights以及result.txt文件&#xff0c;其中weights是训练…