寻求更好的阅读体验,请移步Mculover666的个人博客:

【STM32Cube_15】使用硬件I2C读取温湿度传感器数据(SHT30)​www.mculover666.cn

本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件I2C外设,读取SHT30温湿度传感器的数据并通过串口发送。


1. 准备工作

硬件准备

  • 开发板

首先需要准备一个开发板,这里我准备的是STM32L4的开发板(BearPi):

  • SHT30温湿度传感器

SHT30温湿度传感器是一个完全校准的、现行的、带有温度补偿的数字输出型传感器,具有 2.4V-5.5V 的宽电压支持,使用IIC接口进行通信,最高速率可达1M并且有两个用户可选地址,除此之外,它还具有8个引脚的DFN超小封装,如图:

SHT30的原理图如下:

软件准备

  • 需要安装好Keil - MDK及芯片对应的包,以便编译和下载生成的代码;
  • 准备一个串口调试助手,这里我使用的是Serial Port Utility

Keil MDK和串口助手Serial Port Utility 的安装包都可以在文末关注公众号获取,回复关键字获取相应的安装包:

2.生成MDK工程

选择芯片型号

打开STM32CubeMX,打开MCU选择器:

搜索并选中芯片STM32L431RCT6:

配置时钟源

  • 如果选择使用外部高速时钟(HSE),则需要在System Core中配置RCC;
  • 如果使用默认内部时钟(HSI),这一步可以略过;

这里我都使用外部时钟:

配置串口

小熊派开发板板载ST-Link并且虚拟了一个串口,原理图如下:

这里我将开关拨到AT-MCU模式,使PC的串口与USART1之间连接。

接下来开始配置USART1

配置I2C接口

查看小熊派E53接口的原理图:

接下来开始配置I2C接口1:

配置时钟树

STM32L4的最高主频到80M,所以配置PLL,最后使HCLK = 80Mhz即可:

生成工程设置

代码生成设置

最后设置生成独立的初始化文件:

生成代码

点击GENERATE CODE即可生成MDK-V5工程:

3. 在MDK中编写、编译、下载用户代码

重定向printf( )函数

参考:【STM32Cube_09】重定向printf函数到串口输出的多种方法。

修改I2C初始化代码的小BUG

4. 编写SHT30驱动程序

参考SHT30数据手册.pdf进行编程。

宏定义SHT30器件地址

先来编写sht30_i2c_drv.h头文件,SHT30的器件地址由ADDR端口的高低电平决定:

注意数据手册中给出了8位数据,只有低7位用作地址,结合原理图,可以定义如下:

/* ADDR Pin Conect to VSS */#define SHT30_ADDR_WRITE    0x44<<1         //10001000
#define SHT30_ADDR_READ     (0x44<<1)+1     //10001011

枚举SHT30命令列表

参考数据手册,在sht30_i2c_drv.h头文件中给出如下枚举定义:

typedef enum
{/* 软件复位命令 */SOFT_RESET_CMD = 0x30A2,    /*单次测量模式命名格式:Repeatability_CS_CMDCS: Clock stretching*/HIGH_ENABLED_CMD    = 0x2C06,MEDIUM_ENABLED_CMD  = 0x2C0D,LOW_ENABLED_CMD     = 0x2C10,HIGH_DISABLED_CMD   = 0x2400,MEDIUM_DISABLED_CMD = 0x240B,LOW_DISABLED_CMD    = 0x2416,/*周期测量模式命名格式:Repeatability_MPS_CMDMPS:measurement per second*/HIGH_0_5_CMD   = 0x2032,MEDIUM_0_5_CMD = 0x2024,LOW_0_5_CMD    = 0x202F,HIGH_1_CMD     = 0x2130,MEDIUM_1_CMD   = 0x2126,LOW_1_CMD      = 0x212D,HIGH_2_CMD     = 0x2236,MEDIUM_2_CMD   = 0x2220,LOW_2_CMD      = 0x222B,HIGH_4_CMD     = 0x2334,MEDIUM_4_CMD   = 0x2322,LOW_4_CMD      = 0x2329,HIGH_10_CMD    = 0x2737,MEDIUM_10_CMD  = 0x2721,LOW_10_CMD     = 0x272A,/* 周期测量模式读取数据命令 */READOUT_FOR_PERIODIC_MODE = 0xE000,
} SHT30_CMD;

发送命令函数

/*** @brief   向SHT30发送一条指令(16bit)* @param   cmd —— SHT30指令(在SHT30_MODE中枚举定义)* @retval  成功返回HAL_OK
*/
static uint8_t  SHT30_Send_Cmd(SHT30_CMD cmd)
{uint8_t cmd_buffer[2];cmd_buffer[0] = cmd >> 8;cmd_buffer[1] = cmd;return HAL_I2C_Master_Transmit(&hi2c1, SHT30_ADDR_WRITE, (uint8_t* cmd_buffer, 2, 0xFFFF);
}

复位函数

/*** @brief   复位SHT30* @param   none* @retval  none
*/
void SHT30_reset(void)
{SHT30_Send_Cmd(SOFT_RESET_CMD);HAL_Delay(20);
}

SHT30工作模式初始化函数(周期测量模式)

/*** @brief   初始化SHT30* @param   none* @retval  成功返回HAL_OK* @note    周期测量模式
*/
uint8_t SHT30_Init(void)
{return SHT30_Send_Cmd(MEDIUM_2_CMD);
}

从SHTY30读取一次数据(周期测量模式下)

从SHT30数据手册中可以得到在周期测量模式下读取一次数据的时序,如图:

根据该时序可以看出,首先要发送读数据的命令,然后接收6个字节的数据,编写程序如下:

/*** @brief   从SHT30读取一次数据* @param   dat —— 存储读取数据的地址(6个字节数组)* @retval  成功 —— 返回HAL_OK
*/
uint8_t SHT30_Read_Dat(uint8_t* dat)
{SHT30_Send_Cmd(READOUT_FOR_PERIODIC_MODE);return HAL_I2C_Master_Receive(&hi2c1, SHT30_ADDR_READ, dat, 6, 0xFFFF);
}

从接收数据中校验并解析温度值和湿度值

在数据手册中可知,SHT30分别在温度数据和湿度数据之后发送了8-CRC校验码,确保了数据可靠性。

关于CRC校验请参考我的另一篇博客:如何通俗的理解CRC校验并用C语言实现。

CRC-8校验程序如下:

#define CRC8_POLYNOMIAL 0x31uint8_t CheckCrc8(uint8_t* const message, uint8_t initial_value)
{uint8_t  remainder;     //余数uint8_t  i = 0, j = 0;  //循环变量/* 初始化 */remainder = initial_value;for(j = 0; j < 2;j++){remainder ^= message[j];/* 从最高位开始依次计算  */for (i = 0; i < 8; i++){if (remainder & 0x80){remainder = (remainder << 1)^CRC8_POLYNOMIAL;}else{remainder = (remainder << 1);}}}/* 返回计算的CRC码 */return remainder;
}

计算温度值和湿度值的公式在数据手册中已给出,如图:

接下来编写解析数据的函数:

/*** @brief   将SHT30接收的6个字节数据进行CRC校验,并转换为温度值和湿度值* @param   dat  —— 存储接收数据的地址(6个字节数组)* @retval  校验成功  —— 返回0*          校验失败  —— 返回1,并设置温度值和湿度值为0
*/
uint8_t SHT30_Dat_To_Float(uint8_t* const dat, float* temperature, float* humidity)
{uint16_t recv_temperature = 0;uint16_t recv_humidity = 0;/* 校验温度数据和湿度数据是否接收正确 */if(CheckCrc8(dat, 0xFF) != dat[2] || CheckCrc8(&dat[3], 0xFF) != dat[5])return 1;/* 转换温度数据 */recv_temperature = ((uint16_t)dat[0]<<8)|dat[1];*temperature = -45 + 175*((float)recv_temperature/65535);/* 转换湿度数据 */recv_humidity = ((uint16_t)dat[3]<<8)|dat[4];*humidity = 100 * ((float)recv_humidity / 65535);return 0;
}

5. 测试SHT30驱动程序

在main函数中对该驱动进行测试,在main.c中添加如下代码:

#include <stdio.h>
#include "sht30_i2c_drv.h"int main(void)
{/* USER CODE BEGIN 1 */uint8_t recv_dat[6] = {0};float temperature = 0.0;float humidity = 0.0;/* USER CODE END 1 */HAL_Init();SystemClock_Config();MX_GPIO_Init();MX_I2C1_Init();MX_USART1_UART_Init();/* USER CODE BEGIN 2 */SHT30_Reset();if(SHT30_Init() == HAL_OK)printf("sht30 init ok.n");elseprintf("sht30 init fail.n");/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */while (1){/* USER CODE END WHILE *//* USER CODE BEGIN 3 */HAL_Delay(1000);if(SHT30_Read_Dat(recv_dat) == HAL_OK){if(SHT30_Dat_To_Float(recv_dat, &temperature, &humidity)==0){printf("temperature = %f, humidity = %fn", temperature, humidity);}else{printf("crc check fail.n");}}else{printf("read data from sht30 fail.n");}}/* USER CODE END 3 */
}

测试结果如图:

至此,我们已经学会如何使用硬件IIC接口读取温湿度传感器数据并使用软件CRC校验(SHT30),下一节将讲述如何使用硬件CRC校验SHT30的数据。

更多精彩文章及资源,请关注我的微信公众号:『mculover666』。

vb6编写dll读取dat文件_【STM32Cube_15】使用硬件I2C读取温湿度传感器数据(SHT30)...相关推荐

  1. cass读取dat文件_南方CASS教程+视频讲解+插件汇总,小白快速上手的测绘神器

    南方CASS教程+视频讲解+插件汇总,小白快速上手的测绘神器 自CASS软件推出以来,市场占有率遥遥领先,已经成为业内应用最广.使用最方便快捷的软件品牌.也是用户量最大.升级最快.服务最好的主流成图和 ...

  2. java 读取dat文件_想知道如何从.dat文件中读取对象

    所以即时通讯基本上试图做一个"银行"计划. 到目前为止(我认为)我已经获得了将对象写入.dat文件供将来使用的方法,并且我希望在每次启动时将这些对象读入ArrayList,以便您可 ...

  3. python怎么读取word文件_使用python编辑和读取word文档

    python调用word接口主要用到的模板为python-docx,基本操作官方文档有说明. 使用python新建一个word文档,操作就像文档里介绍的那样: 1 from docx importDo ...

  4. python读取bmp文件_如何在python中读取bmp文件头?

    您可以使用imghdr module(在python stdlib中):>>> import imghdr >>> print(imghdr.what(input_ ...

  5. java 读取doc文件_如何在java中读取Doc或Docx文件?

    我想在 java中读一个word文件 import org.apache.poi.poifs.filesystem.*; import org.apache.poi.hpsf.DocumentSumm ...

  6. Gh0st源码学习(三)生成DLL和DAT文件

    从生成的EXE文件中分离出DLL和DAT 文件 一.自定义DLL和DAT文件的生成路径 先搜索 IDR_BSS . IDR_DLL   1. IDR_DLL   位置:\Gh0st3.6原版\Serv ...

  7. matlab文件名批量读取dat文件,matlab批量读取dat

    matlab如何生成数据dat文件_数学_自然科学_专业资料.第一种方法:sav... matlab中读取txt中数据 2页 1下载券 MATLAB读取文本格式数据 21页 1下载券 用Matlab读 ...

  8. matlab打开dat形式文件_matlab 读取dat文件

    matlab 读取dat文件 关注:145  答案:2  mip版 解决时间 2021-01-17 21:36 提问者壹玍徴戰何亽陪 2021-01-17 14:35 想用matlab 语句读取桌面上 ...

  9. python如何自动读取excel文件_基于Python的接口自动化-读写excel文件

    引言 使用python进行接口测试时常常需要接口用例测试数据.断言接口功能.验证接口响应状态等,如果大量的接口测试用例脚本都将接口测试用例数据写在脚本文件中,这样写出来整个接口测试用例脚本代码将看起来 ...

最新文章

  1. CDN 监控系统(二)
  2. 用宏定义代替printf函数
  3. Apache PHP-fpm Mariadb
  4. java 使用ehcache,ehcache的介绍和使用,ehcache介绍使用
  5. 解决asp.net(C#)中 DataTime 空值 null为0001-01-01
  6. 牛气!GitHub 标星 119K+!这些神器仅需一行代码即可下载全网视频!
  7. 归纳整理--第4篇--常用软件
  8. 微软 MS Learn 上线 Blazor 入门教程
  9. Android--Facebook Login without LoginButton
  10. pmp知识点详解-项目大牛整理_PMP核心知识点—第四章:项目整合管理(一)
  11. 微软发布人工智能教育与学习共建社区
  12. android surfaceview camera,android – 如何在SurfaceView上显示相机预览?
  13. java date.from_java datefromat
  14. Java 面向对象:多态的理解
  15. 第二十二:第一个Pytest UI自动化测试实战实例
  16. 业务请求量膨胀的扩容技术实践
  17. ENVI入门系列教程---二、图像分析---14.基本光谱分析
  18. Linux下C编程入门(2)
  19. win8系统本地计算机策略,win8本地安全策略怎么打开?三种方法轻松打开win8本地安全策略...
  20. python惰性求值例子_惰性求值和yield-Python

热门文章

  1. 那些鼓吹国内首个.NET 5框架的,该醒醒了!
  2. 使用代码片段的正确姿势,打造高效的vscode开发环境
  3. 全球顶级开源大神们现身 COSCon'20
  4. 使用Azure DevOps Pipeline实现.Net Core程序的CI
  5. 沈向洋对于工程技术人员的十点经验分享
  6. .NetCore使用skywalking实现实时性能监控
  7. 值类型、引用类型和泛型的前世今生
  8. Asp.Net Core 快速邮件队列设计与实现
  9. .NET Core 2.1 Preview 1发布:更快的构建性能
  10. 35年编程史沉淀下来的8条宝贵经