GD32F470_GY-SHT31-D 数字温湿度传感器模块移植

2.11 SHT30温湿度传感器
2.11.1 模块来源
采购链接:
GY-SHT31-D 数字温湿度传感器模块
资料下载链接:
https://pan.baidu.com/s/1kisMJspcV6Qdr1ye9ElOlQ

2.11.2 规格参数
工作电压:2.4-5.5V
工作电流:0.2~1500uA
温度测量范围:-40~125℃
温度测量精度:±0.3℃
湿度测量范围:0~100%RH
湿度测量精度:±2%RH
输出方式: IIC
管脚数量:4 Pin
暂时无法在飞书文档外展示此内容
文件2.11.2-1 产品规格书

工作电流:0.2~1500uA
温度测量范围:-40~125℃
温度测量精度:±0.3℃
湿度测量范围:0~100%RH
湿度测量精度:±2%RH
输出方式: IIC
管脚数量:4 Pin

2.11.3 移植过程
我们的目标是在梁山派GD32F470上能够测量温湿度的功能。首先要获取资料,查看数据手册应如何实现,再移植至我们的工程。
2.11.3.1 查看资料
模块原理图
在这里插入图片描述
SHT30地址
数据手册上说明,当ADDR引脚接入VSS(接地)时,地址为0X44。而原理图上已经通过R14这个下拉电阻接地。不过需要注意的是,实际地址为0X44左移一位,因需要空出最低位给读写位,所以实际的地址是 0X44<<1。
在这里插入图片描述

测量模式
SHT30有两种测量模式,分别是单次测量模式和周期测量模式。
在单次测量模式下,发出一个测量命令就触发一次数据采集。每个数据都由一个16位的温度值和一个16位的湿度值(按此顺序)组成。在传输过程中,每个数据值后面总是跟着一个CRC校验和。但是在该模式下又分有时钟拉伸模式和时钟不拉伸模式,具体情况见下图。
在这里插入图片描述
并且在单次测量模式下,可以选择不同的测量命令。它们在可重复性(低、中、高)和时钟拉伸(启用或禁用)方面有所不同。这里的可重复性设置影响测量持续时间,从而影响传感器的总体能耗。
在这里插入图片描述
在周期测量模式下,时钟拉伸模式禁用,但是可以分为高中低的可重复性测量,测量周期为0.5、1、2、4、10(单位 次/秒)(这种模式下最快的测量速度是1秒10次)如果传感器在一种工作模式下正在测量数据,此时要发送其他命令(推荐先发送一次中断命令),让传感器停止当前的测量,进入单次测量模式,然后再发送命令。这里需要注意:如果测量频率过高,会导致传感器自热。
在这里插入图片描述
设置好周期测量模式的测量周期和可重复性强度后,随时可以进行测量读取数据,需要发送一个读取命令(0XE000)。一旦读取时序结束之后,寄存器中的数值就会清零,如果这时再一次读取数据将得到0。下一次测量结束后,寄存器的值就会重新写入。
在这里插入图片描述

2.11.3.2 引脚选择

SHT30立创·梁山派
VIN5V
GNDGND
SCLPB9
SDAPB8

在这里插入图片描述
2.11.3.3 移植至工程
移植步骤中的导入.c和.h文件与上一节相同,只是将.c和.h文件更改为bsp_sht30.c与bsp_sht30.h。见2.2.3.3 移植至工程。这里不再过多讲述。移植完成后面修改相关代码。
在文件bsp_sht30.c中,编写如下代码。

/********************************************************************************* 文 件 名: bsp_sht30.c* 版 本 号: 初版* 修改作者: LC* 修改日期: 2023年04月19日* 功能介绍:          ******************************************************************************* 注意事项:
*********************************************************************************/#include "bsp_sht30.h"
#include "bsp_usart.h"
#include "stdio.h"
#include "systick.h"//端口移植
#define RCU_SDA RCU_GPIOB
#define PORT_SDA GPIOB
#define GPIO_SDA GPIO_PIN_8#define RCU_SCL RCU_GPIOB
#define PORT_SCL GPIOB
#define GPIO_SCL GPIO_PIN_9//设置SDA输出模式
#define SDA_OUT()        gpio_mode_set(PORT_SDA,GPIO_MODE_OUTPUT,GPIO_MODE_OUTPUT,GPIO_SDA)
//设置SDA输入模式
#define SDA_IN()        gpio_mode_set(PORT_SDA,GPIO_MODE_INPUT,GPIO_MODE_OUTPUT,GPIO_SDA)
//获取SDA引脚的电平变化
#define SDA_GET()        gpio_input_bit_get(PORT_SDA,GPIO_SDA)
//SDA与SCL输出
#define SDA(x)          gpio_bit_write(PORT_SDA,GPIO_SDA, (x?SET:RESET))
#define SCL(x)          gpio_bit_write(PORT_SCL,GPIO_SCL, (x?SET:RESET))double Temperature = 0.0, Humidity = 0.0;/******************************************************************* 函 数 名 称:SHT30_GPIO_Init* 函 数 说 明:SHT30的引脚初始化* 函 数 形 参:无* 函 数 返 回:无* 作       者:LC* 备       注:无
******************************************************************/
void SHT30_GPIO_Init(void)
{/* 使能时钟 */rcu_periph_clock_enable(RCU_SCL);rcu_periph_clock_enable(RCU_SDA);/* 配置SCL为输出模式 */gpio_mode_set(PORT_SCL,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_SCL);/* 配置为推挽输出 50MHZ */gpio_output_options_set(PORT_SCL,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_SCL);/* 配置SDA为输出模式 */gpio_mode_set(PORT_SDA,GPIO_MODE_OUTPUT,GPIO_PUPD_NONE,GPIO_SDA);/* 配置为推挽输出 50MHZ */gpio_output_options_set(PORT_SDA,GPIO_OTYPE_PP,GPIO_OSPEED_50MHZ,GPIO_SDA);
}/******************************************************************* 函 数 名 称:IIC_Start* 函 数 说 明:IIC起始时序* 函 数 形 参:无* 函 数 返 回:无* 作       者:LC* 备       注:无
******************************************************************/
void IIC_Start(void)
{SDA_OUT();SCL(1); SDA(0);SDA(1);delay_us(5);SDA(0);delay_us(5);SCL(0);
}
/******************************************************************* 函 数 名 称:IIC_Stop* 函 数 说 明:IIC停止信号* 函 数 形 参:无* 函 数 返 回:无* 作       者:LC* 备       注:无
******************************************************************/
void IIC_Stop(void)
{SDA_OUT();SCL(0);SDA(0);SCL(1);delay_us(5);SDA(1);delay_us(5);}/******************************************************************* 函 数 名 称:IIC_Send_Ack* 函 数 说 明:主机发送应答或者非应答信号* 函 数 形 参:0发送应答  1发送非应答* 函 数 返 回:无* 作       者:LC* 备       注:无
******************************************************************/
void IIC_Send_Ack(unsigned char ack)
{SDA_OUT();SCL(0);SDA(0);delay_us(5);if(!ack) SDA(0);else         SDA(1);SCL(1);delay_us(5);SCL(0);SDA(1);
}/******************************************************************* 函 数 名 称:I2C_WaitAck* 函 数 说 明:等待从机应答* 函 数 形 参:无* 函 数 返 回:0有应答  1超时无应答* 作       者:LC* 备       注:无
******************************************************************/
unsigned char I2C_WaitAck(void)
{char ack = 0;unsigned char ack_flag = 10;SCL(0);SDA(1);SDA_IN();SCL(1);while( (SDA_GET()==1) && ( ack_flag ) ){ack_flag--;delay_us(5);}if( ack_flag <= 0 ){IIC_Stop();return 1;}else{SCL(0);SDA_OUT();}return ack;
}/******************************************************************* 函 数 名 称:Send_Byte* 函 数 说 明:写入一个字节* 函 数 形 参:dat要写人的数据* 函 数 返 回:无* 作       者:LC* 备       注:无
******************************************************************/
void Send_Byte(u8 dat)
{int i = 0;SDA_OUT();SCL(0);//拉低时钟开始数据传输for( i = 0; i < 8; i++ ){SDA( (dat & 0x80) >> 7 );__nop();SCL(1);delay_us(5);SCL(0);delay_us(5);dat<<=1;}        
}/******************************************************************* 函 数 名 称:Read_Byte* 函 数 说 明:IIC读时序* 函 数 形 参:无* 函 数 返 回:读到的数据* 作       者:LC* 备       注:无
******************************************************************/
unsigned char Read_Byte(void)
{unsigned char i,receive=0;SDA_IN();//SDA设置为输入for(i=0;i<8;i++ ){SCL(0);delay_us(5);SCL(1);delay_us(5);receive<<=1;if( SDA_GET() ){        receive|=1;   }delay_us(5); }                                         SCL(0); return receive;
}/******************************************************************* 函 数 名 称:SHT31_Write_mode* 函 数 说 明:在周期模式下设置测量周期与可重复性命令* 函 数 形 参:dat设置命令常用的有:每一秒采集0.5次  0x2024每一秒采集1次    0x2126每一秒采集2次    0x2220每一秒采集4次    0x2334每一秒采集10次   0x2721  * 函 数 返 回:* 作       者:LC* 备       注:
******************************************************************/
char SHT31_Write_mode(uint16_t dat)
{IIC_Start();// << 1 是将最后一位置0,设置为写命令Send_Byte((0X44 << 1) | 0 );//返回0为产生了应答,返回1说明通信失败if( I2C_WaitAck() == 1 )return 1;//发送命令的高8位Send_Byte((dat >> 8 ) );//返回0为产生了应答,返回1说明通信失败if( I2C_WaitAck() == 1 )return 2;//发送命令的低8位Send_Byte(dat & 0xff );//返回0为产生了应答,返回1说明通信失败if( I2C_WaitAck() == 1 )return 3;
//        IIC_Stop();return 0;
}/******************************************************************* 函 数 名 称:crc8* 函 数 说 明:CRC校验* 函 数 形 参:data要校验的数据地址     len要校验的长度* 函 数 返 回:校验后的值* 作       者:LC* 备       注:无
******************************************************************/
unsigned char crc8(const unsigned char *data, int len)
{const unsigned char POLYNOMIAL = 0x31;unsigned char crc = 0xFF;int j, i;for (j=0; j<len; j++){                  crc ^= *data++;for ( i = 0; i <8; i++ ){crc = ( crc & 0x80 ) ? (crc << 1) ^ POLYNOMIAL : (crc << 1); }                                                            }return crc;
}/******************************************************************* 函 数 名 称:SHT30_Read* 函 数 说 明:读取温湿度值* 函 数 形 参:dat读取的命令周期模式命令为:0xe000单次模式命令为:0x2c06 or 0x2400* 函 数 返 回:0读取成功  其他失败* 作       者:LC* 备       注:当前为周期模式读取,如使用单次模式,则将*              【设置周期模式命令】下的命令注释即可。
******************************************************************/
char SHT30_Read(uint16_t dat)
{        uint16_t i = 0;unsigned char buff[6] = {0};uint16_t data_16 = 0;float temp = 0;float humi = 0;//设置周期模式命令SHT31_Write_mode(0x2130);//每1秒一次高重复测量(需要在周期模式下才有用)IIC_Start();Send_Byte( (0x44<<1) | 0);if( I2C_WaitAck() == 1 )return 1;Send_Byte((dat >> 8 ));if( I2C_WaitAck() == 1 )return 2;Send_Byte( dat & 0xff );if( I2C_WaitAck() == 1 )return 3;//如不使用超时判断,很容易数据错乱do{//超时判断i++;if( i > 20 ) return 4;delay_1ms(2);IIC_Start();Send_Byte((0X44 << 1) | 1 );//读}while(I2C_WaitAck() == 1);        //读取到温湿度数据则结束读命令//温度高8位buff[0] = Read_Byte();IIC_Send_Ack(0);//温度低8位buff[1] = Read_Byte();IIC_Send_Ack(0);        //温度CRC校验值buff[2] = Read_Byte();IIC_Send_Ack(0);//湿度高8位buff[3] = Read_Byte();IIC_Send_Ack(0);        //湿度低8位buff[4] = Read_Byte();IIC_Send_Ack(0);        //湿度CRC校验值buff[5] = Read_Byte();IIC_Send_Ack(1);        IIC_Stop();          //CRC校验(将要校验的数值带入,查看计算后的校验值是否和读取到的校验值一致)if( (crc8(buff,2) == buff[2]) && ( crc8(buff+3,2) == buff[5]) ){//计算温度值data_16 =(buff[0]<<8) | buff[1];Temperature = (data_16/65535.0)*175.0 - 45;//计算湿度值data_16 = 0;data_16 =(buff[3]<<8) | buff[4];Humidity = (data_16/65535.0) * 100.0;printf("temp = %.2f\r\n",Temperature);printf("humi = %.2f\r\n",Humidity);return 0;}else{printf("校验失败\r\n");   }return 5;
}

在文件bsp_sht30.h中,编写如下代码。

#ifndef _BSP_SHT30_H_
#define _BSP_SHT30_H_#include "gd32f4xx.h"extern double Temperature, Humidity;#define u8 unsigned charvoid SHT30_GPIO_Init(void);
char SHT30_Read(uint16_t dat);#endif

2.11.4 移植验证
在自己工程中的main主函数中,编写如下。

/********************************************************************************* 文 件 名: main.c* 版 本 号: 初版* 修改作者: LC* 修改日期: 2022年04月19日* 功能介绍:          ******************************************************************************* 注意事项:
*********************************************************************************/#include "gd32f4xx.h"
#include "systick.h"
#include <stdio.h>
#include "main.h"
#include "bsp_led.h"
#include "sys.h"
#include "bsp_usart.h"
#include "bsp_key.h"
#include "bsp_basic_timer.h"
#include "bsp_pwm.h"
#include "stdlib.h"
#include "string.h"
#include "bsp_sht30.h"/************************************************
函数名称 : main
功    能 : 主函数
参    数 : 无
返 回 值 : 无
作    者 : LC
*************************************************/
int main(void)
{nvic_priority_group_set(NVIC_PRIGROUP_PRE2_SUB2);  // 优先级分组systick_config();                                                  // 滴答定时器初始化usart_gpio_config(9600U);                                          // 串口0初始化SHT30_GPIO_Init();printf("start\r\n");while(1) {SHT30_Read(0xe000);delay_1ms(1000);}
}

移植现象:每隔1秒读取一次温湿度,并通过串口输出。
在这里插入图片描述
移植成功示例,见文件2.11.4-1 。
文件2.11.4-1

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

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

相关文章

构建未来交通:香橙派OPI Airpro上的智能交通监管系统

引言&#xff1a; 随着城市化进程的加速&#xff0c;交通管理变得越来越复杂。 传统的交通监管系统往往无法有效应对日益增长的车辆数量和复杂的交通状况。因此&#xff0c;我们需要一种更加智能和自适应的解决方案来提高交通效率并减少事故发生率。 香橙派OPI Airpro以其强大的…

ComfyUI ClipSeg插件报错- resize_image出错应该怎么办

上一篇刚介绍了这个插件&#xff0c;结果emm..很快发现事情并不简单...结果又报错了。 后台报错信息&#xff1a; Unused or unrecognized kwargs: padding. !!! Exception during processing !!! Traceback (most recent call last): File "F:\ComfyUI-aki\execution.p…

Open-Sora环境搭建推理测试

引子 Sora&#xff0c;2024年2月15日&#xff0c;OpenAI发布的人工智能文生视频大模型。支持60秒视频生成&#xff0c;震荡了国内国际学术圈、广告圈、AI教培圈。Sora最主要有三个优点&#xff1a;第一&#xff0c;“60s超长视频”&#xff0c;之前文本生成视频大模型一直无法真…

数据库重点知识(个人整理笔记)

目录 1. 索引是什么&#xff1f; 1.1. 索引的基本原理 2. 索引有哪些优缺点&#xff1f; 3. MySQL有哪几种索引类型&#xff1f; 4. mysql聚簇和非聚簇索引的区别 5. 非聚簇索引一定会回表查询吗&#xff1f; 6. 讲一讲前缀索引&#xff1f; 7. 为什么索引结构默认使用B…

【Visual Studio】将项目下的文件夹所有文件随编译自动复制输出到运行目录

要将项目根目录下的文件夹内容输出到运行目录&#xff0c;去处理其中的子文件夹和文件&#xff0c;逐个手动设置文件属性或进行复制显然不是一个可行的方法&#xff0c;因为这既繁琐又低效&#xff0c;那有没有更加高效的方式呢 文章目录 选择文件夹修改配置文件输出文件夹 这里…

FreeRtos入门-3 信号量(计数值、二进制、互斥量、递归锁)

信号量 计数量 二进制 互斥量 递归锁 创建 xSemCalc xSemaphoreCreateCounting(10, 0);//计数最大值10&#xff0c;初始值0 xSemUart xSemaphoreCreateBinary(); xSemUART xSemaphoreCreateMutex(); xSemUART xSemaphoreCreateRecursiveMutex(); 释放 xSemaphore…

Linux集群(一)Nginx搭建

目录 一、Nginx介绍 1.什么是Nginx 2.Nginx的特点 二、Nginx配置 1.jdk的安装 1.1检查jdk版本 1.2上传并安装jdk 2.安装Tomcat 3.下载Nginx 3.1安装依赖包 ​编辑 3.2安装Nginx 3.3运行 三、Nginx中的常用命令​编辑 一、Nginx介绍 1.什么是Nginx Nginx&#xff08;…

Coursera上Learning Linux for LFCA Certification专项课程01:Linux Fundamentals 学习笔记

Linux Fundamentals Course Certificate 本文是 Linux Fundamentals 这门课的学习笔记&#xff0c;如有侵权&#xff0c;请联系删除。 文章目录 Linux FundamentalsWeek 01: Linux Operating SystemLearning Objectives Specialization OverviewHistory of LinuxQuiz: Hist…

软件设计师27--规范化理论

软件设计师27--规范化理论 考点1&#xff1a;规范化理论基本概念函数依赖规范化理论--Amstrong公理体系候选键主属性与非主属性例题&#xff1a; 考点2&#xff1a;范式判断规范化理论规范化理论 - 范式例题&#xff1a; 考点3&#xff1a;范式分解保持函数依赖分解无损分解模式…

第14章 数据结构与集合源码

一 数据结构剖析 我们举一个形象的例子来理解数据结构的作用&#xff1a; 战场&#xff1a;程序运行所需的软件、硬件环境 战术和策略&#xff1a;数据结构 敌人&#xff1a;项目或模块的功能需求 指挥官&#xff1a;编写程序的程序员 士兵和装备&#xff1a;一行一行的代码 …

基于opencv的猫脸识别模型

opencv介绍 OpenCV的全称是Open Source Computer Vision Library&#xff0c;是一个跨平台的计算机视觉库。OpenCV是由英特尔公司发起并参与开发&#xff0c;以BSD许可证授权发行&#xff0c;可以在商业和研究领域中免费使用。OpenCV可用于开发实时的图像处理、计算机视觉以及…

【前端面试3+1】11 http和https有何不同及https的加密过程、数组有哪些方法及作用、tcp三次握手四次挥手、【分发饼干】

一、http和https有何不同&#xff1f;https的加密过程 1、不同&#xff1a; HTTP和HTTPS的主要区别在于安全性。HTTP是超文本传输协议&#xff0c;是一种用于传输数据的协议&#xff0c;但是传输的数据是明文的&#xff0c;容易被窃听和篡改。而HTTPS是在HTTP基础上加入了SSL/T…

【ORB-SLAM3】Ubuntu20.04 使用 RealSense D435i 运行 ORB-SLAM3 时遇到的一些 Bug

【ORB-SLAM3】使用 RealSense D435i 跑 ORB-SLAM3 时遇到的一些 Bug 1 hwmon command 0x80( 5 0 0 0 ) failed (response -7 HW not ready)2 No rule to make target /opt/ros/noetic/lib/x86_64-linux-gnu/librealsense2.so, needed by ../lib/libORB_SLAM3.so 1 hwmon comman…

力扣108. 将有序数组转换为二叉搜索树

Problem: 108. 将有序数组转换为二叉搜索树 文章目录 题目描述思路复杂度Code 题目描述 思路 根据二叉搜索树中序遍历为一个有序序列的特点得到&#xff1a; 1.定义左右下标left&#xff0c;right分别指向有序序列的头尾&#xff1b; 2.每次取出left和right的中间节点mid&…

电脑上怎么压缩图片?三个处理方法介绍

随着我们现在使用图片的地方越来越多&#xff0c;我们处理图片的情况也比较多了&#xff0c;通过压缩图片大小可以使图片文件更小&#xff0c;从而减少存储空间和带宽的使用&#xff0c;同时也可以提高加载速度和性能。良好的图片压缩可以有效地减少文件大小&#xff0c;同时保…

深入浅出 -- 系统架构之单体架构

单体架构&#xff08;Monolithic Architecture&#xff09; 单体架构的定义 单体架构&#xff08;Monolithic Architecture&#xff09;是一种传统的软件架构模式&#xff0c;将整个应用程序作为一个单一的、统一的单元进行开发、部署和扩展。在单体架构中&#xff0c;所有的功…

JSP

概念&#xff1a;Java Server Pages&#xff0c;Java服务端页面 一种动态的网页技术&#xff0c;其中既可以定义HTML、JS、CSS等静态内容&#xff0c;还可以定义Java代码的动态内容 JSP HTML Java 快速入门 注&#xff1a;Tomcat中已经有了JSP的jar包&#xff0c;因此我们…

【yy讲解PostCSS是如何安装和使用】

&#x1f3a5;博主&#xff1a;程序员不想YY啊 &#x1f4ab;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f917;点赞&#x1f388;收藏⭐再看&#x1f4ab;养成习惯 ✨希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出…

Coursera上托福专项课程01:TOEFL Reading and Listening Sections Skills Mastery 学习笔记

TOEFL Reading and Listening Sections Skills Mastery Course Certificate 本文是学习 https://www.coursera.org/learn/toefl-reading-listening-sections-skills-mastery 这门课的笔记&#xff0c;如有侵权&#xff0c;请联系删除。 文章目录 TOEFL Reading and Listening …

AI绘图:Stable Diffusion ComfyUI局部重绘与智能扩图全面教程

前言 在数字艺术创作中&#xff0c;局部重绘和智能扩图是两个非常重要的功能。局部重绘允许我们在保留原有图像的基础上&#xff0c;对特定区域进行修改或创新。而智能扩图则能够帮助我们在图像的边缘添加新的元素&#xff0c;从而扩展图像的内容。本文将详细介绍如何在Stable…