【STM32 驱动 SHT30 温湿度传感器|IIC 通信 + LCD 显示 + 串口双输出完整实战】
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
摘要: 本文基于 STM32L431VC 开发板,完整复现 SHT30 数字温湿度传感器的采集实验。文章首先介绍实验硬件平台与 SHT30 传感器的工作原理,重点剖析软件模拟 IIC 通信时序及温湿度数据换算公式;随后给出工程分层架构下 main.c、handle.c、sht30.c 三个模块的完整代码,涵盖系统初始化、1 秒周期采集、量程判断、LCD 显示与串口打印;最后总结实验现象,并展望智慧农业等场景下的项目拓展方向。
前言
提示:这里可以添加本文要记录的大概内容:
在嵌入式、智慧农业、环境监测项目中,温湿度采集是最常见的基础功能。SHT30 是一款高精度 IIC 接口数字温湿度传感器,很多新手会对 IIC 时序、传感器原始数据换算、多设备协同显示感到困惑。本文基于 STM32L431VC 开发板,完整复现 SHT30 采集实验,带你从硬件原理、代码分层、实验现象到项目拓展完整走一遍嵌入式传感器开发流程。
提示:以下是本篇文章正文内容,下面案例可供参考
一、温湿度传感器原理
1.1 实验硬件平台
主控芯片:STM32L431VC 单片机
传感器:SHT30 数字温湿度传感器(IIC 通信)
外设:LCD 显示屏、串口调试助手、智慧农业扩展板
通信接口:IIC 总线、UART 串口
整体硬件架构:STM32 核心板作为主控,通过插座连接智慧农业扩展板挂载 SHT30 传感器;主控外接 LCD 屏幕用于本地可视化;通过 Type‑C 数据线连接 PC,串口把采集数据上传电脑。
二、工作原理剖析
2.1 SHT30 传感器原理
SHT30 是 IIC 接口数字温湿度传感器。单片机通过 IIC 总线向传感器下发测量指令,传感器完成测量后返回 16 位原始温度、湿度数据,附带 CRC 校验字节。单片机拿到原始采样值,对照官方手册公式,把原始数字量换算成真实环境温度(℃)与相对湿度(% RH)。
2.2 IIC 通信时序
本实验采用软件模拟 IIC 时序,完整通信流程:
发送 IIC 起始信号
发送传感器器件地址 + 读写位
等待从机应答 ACK
发送测量命令
等待测量完成,读取温度、湿度以及 CRC 校验字节
发送 IIC 停止信号
IIC 核心信号:起始信号、停止信号、应答信号、字节收发,是读懂 SHT30 驱动代码的关键。
2.3 数据换算公式
传感器返回的是 16 位原始采样值,不能直接当做温湿度使用,必须进行换算:
温度 = 175.0 * 原始温度值 / 65535.0 - 45.0
湿度 = 100.0 * 原始湿度值 / 65535.0
三、使用步骤
工程采用嵌入式分层设计,代码分为main.c、handle.c、sht30.c三个模块,模块职责相互解耦,逻辑清晰。
1.main.c 主函数入口
代码如下(示例):
#include "stm32l4xx_hal.h"
#include "lcd.h"
#include "sht30.h"
#include "handle.h"
#include "uart.h"
int main(void)
{
HAL_Init(); //HAL库底层初始化
SystemClock_Config(); //系统时钟配置
LCD_Display_Init(); //屏幕初始化显示
uart_module_open(usart2, 115200);//串口初始化 波特率115200
printf("\r\n\t温湿度检测实验\t\r\n");
printf("----------------------------\r\n");
printf("开始实验:\r\n\r\n");
SHT30_GPIO_Init(); //SHT30传感器IIC引脚初始化
printf("*** 温度传感器初始化\r\n");
while(1)
{
Temp_Hum_Handle(); //调用温湿度采集处理函数
}
}
//系统时钟初始化
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct;
//省略时钟寄存器配置代码
}
2.handle.c 业务逻辑层(采集、判断量程、LCD 显示、串口打印)
代码如下(示例):
#include "sht30.h"
#include "lcd.h"
#include "stdio.h"
void LCD_Display_Init(void)
{
LCD_Init();
//填充底色、绘制标题、绘制温湿度图标
LCD_Fill(0,0,lcdev.width,20,BLUE);
Gui_StrCenter(0,2,BLUE,WHITE,"温湿度检测实验",24,1);
LCD_draw_bmp(96,120,48,gImage_wenshi); //绘制温湿度图标
}
void Temp_Hum_Handle(void)
{
static float temp = 0;
static float hum = 0;
static char str[20];
static uint32_t tickstart;
//每1000ms采集一次
if((HAL_GetTick() - tickstart) >= 1000)
{
tickstart = HAL_GetTick();
SHT30_read_result(&temp,&hum); //读取温湿度
LCD_Fill(90,182,200,182+16*2,WHITE); //刷新显示区域
//温度量程判断 SHT30:-0~55℃
if(temp < 0.0f || temp > 55.0f)
{
sprintf(str,"Temperature:");
}
else
{
sprintf(str,"Temperature:%.1f℃",temp);
}
Show_Str(75,182,BLUE,WHITE,(uint8_t *)str,16,1);
//湿度量程判断 20~90%RH
if(hum < 20.0f || hum > 90.0f)
{
sprintf(str,"Humidity:");
}
else
{
sprintf(str,"Humidity:%.1f%%",hum);
}
Show_Str(90,198,BLUE,WHITE,(uint8_t *)str,16,1);
//串口打印输出
printf("*** 读取温湿度传感器数据\r\n");
printf("*** Temperature:%.1f℃\r\n", temp);
printf("*** Humidity:%.1f%%\r\n", hum);
}
}
3.sht30.c 底层驱动:软件 IIC + SHT30 读取与数据换算
#include "sht30.h"
//IIC起始信号
static void SHT30_IIC_Start(void)
{
SHT30_SDA_OUT();
SHT30_SDA_Set();
SHT30_SCLK_Set();
delay_us(5);
SHT30_SDA_Clr();
delay_us(5);
SHT30_SCLK_Clr();
}
//IIC停止信号
static void SHT30_IIC_Stop(void)
{
SHT30_SDA_OUT();
SHT30_SCLK_Clr();
SHT30_SDA_Clr();
delay_us(5);
SHT30_SCLK_Set();
SHT30_SDA_Set();
delay_us(5);
}
//等待从机应答
static uint8_t IIC_wait_ACK(void)
{
uint8_t ack_time=0;
SHT30_SDA_IN();
SHT30_SDA_Set();
delay_us(2);
SHT30_SCLK_Set();
delay_us(2);
while(SHT30_READ_SDA())
{
ack_time++;
delay_us(10);
if(ack_time>250)
{
SHT30_IIC_Stop();
return ERROR;
}
}
SHT30_SDA_Clr();
return TURE;
}
//IIC发送1字节
void IIC_SendByte(uint8_t byte)
{
uint8_t BitCnt;
SHT30_SDA_OUT();
SHT30_SCLK_Clr();
for(BitCnt = 0; BitCnt < 8; BitCnt++)
{
if(byte & 0x80) { SHT30_SDA_Set(); }
else { SHT30_SDA_Clr(); }
byte <<= 1;
delay_us(2);
SHT30_SCLK_Set();
delay_us(2);
SHT30_SCLK_Clr();
delay_us(2);
}
}
//IIC读取1字节
uint8_t IIC_RcvByte(void)
{
uint8_t BitCnt;
uint8_t retc;
retc = 0;
SHT30_SDA_IN();
//省略字节读取循环代码
return retc;
}
/**
* @brief 读取SHT30温湿度
* @param *Temperature 温度浮点指针
* @param *Humidity 湿度浮点指针
*/
void SHT30_read_result(float *Temperature,float *Humidity)
{
uint16_t tem, hum;
uint8_t buff[6];
SHT30_IIC_Start();
IIC_SendByte(0x44 << 1 | write); //SHT30器件地址写
IIC_wait_ACK();
IIC_SendByte(0x2C); //测量命令高字节
IIC_wait_ACK();
IIC_SendByte(0x06); //测量命令低字节
IIC_wait_ACK();
SHT30_IIC_Stop();
delay_ms(50); //等待传感器测量完成
SHT30_IIC_Start();
IIC_SendByte(0x44 << 1 | read); //SHT30器件地址读
if(IIC_wait_ACK() == 0)
{
buff[0] = IIC_RcvByte();
IIC_ACK();
buff[1] = IIC_RcvByte();
IIC_ACK();
buff[2] = IIC_RcvByte(); //温度CRC
IIC_ACK();
buff[3] = IIC_RcvByte();
IIC_ACK();
buff[4] = IIC_RcvByte();
IIC_ACK();
buff[5] = IIC_RcvByte(); //湿度CRC
IIC_ACK();
SHT30_IIC_Stop();
}
tem = (buff[0] << 8) + buff[1]; //拼接温度原始16位数据
hum = (buff[3] << 8) + buff[4]; //拼接湿度原始16位数据
//SHT30官方换算公式
*Temperature = (175.0f * (float)tem / 65535.0f - 45.0f);
*Humidity = (100.0f * (float)hum / 65535.0f);
}
四、实验现象与结果分析
4.1 LCD 屏幕显示效果
程序上电后,LCD 屏幕首先显示蓝色标题栏「温湿度检测实验」,并绘制温湿度图标。进入主循环后,Temp_Hum_Handle() 每 1000ms 采集一次温湿度数据,并在屏幕固定区域刷新显示:
- 温度显示在屏幕左侧,格式为
Temperature:24.9℃; - 湿度显示在温度下方,格式为
Humidity:73.6%; - 每次刷新前会先以白色填充显示区域,避免新旧数据叠加产生残影。
实际运行中,用手靠近传感器时,温度数值会缓慢上升,湿度数值随之变化;移开后数值逐渐回落,屏幕数据与真实环境变化保持同步,刷新节奏稳定,无卡顿或闪烁现象。
4.2 串口调试助手输出效果
通过 Type‑C 数据线连接 PC,打开串口调试助手(波特率 115200),上电后可看到如下输出:
温湿度检测实验
----------------------------
开始实验:
*** 温度传感器初始化
*** 读取温湿度传感器数据
*** Temperature:24.9℃
*** Humidity:73.6%
串口每 1 秒输出一组温湿度数据,与 LCD 屏幕显示完全一致,实现了本地可视化与上位机监控的双重数据输出,便于远程观察与数据记录。
总结
本实验基于 STM32L431VC 单片机平台,使用软件模拟 IIC 时序驱动 SHT30 数字温湿度传感器,工程采用分层代码架构,main.c 负责 HAL 库、系统时钟、LCD、串口、SHT30 引脚等硬件初始化,循环调用业务处理函数;handle.c 实现 1 秒周期采集控制、温湿度量程判断、sprintf 字符串格式化,完成 LCD 屏幕界面刷新显示以及 printf 串口数据输出;sht30.c 实现 IIC 起始、停止、收发字节、等待应答底层时序,调用 SHT30_read_result 函数下发测量命令,读取包含 CRC 位的 6 字节传感器返回数据,拼接高低字节得到 16 位原始采样值,再通过官方公式温度=175.0原始值/65535.0‑45.0、湿度=100.0原始值/65535.0换算出实际温湿度,最终实现 LCD 本地可视化与串口调试助手双重数据输出,屏幕和串口数据保持同步更新;本实验基于 STM32L431VC 单片机平台,使用软件模拟 IIC 时序驱动 SHT30 数字温湿度传感器,工程采用分层代码架构,main.c 负责 HAL 库、系统时钟、LCD、串口、SHT30 引脚等硬件初始化,循环调用业务处理函数;handle.c 实现 1 秒周期采集控制、温湿度量程判断、sprintf 字符串格式化,完成 LCD 屏幕界面刷新显示以及 printf 串口数据输出;sht30.c 实现 IIC 起始、停止、收发字节、等待应答底层时序,调用 SHT30_read_result 函数下发测量命令,读取包含 CRC 位的 6 字节传感器返回数据,拼接高低字节得到 16 位原始采样值,再通过官方公式温度=175.0原始值/65535.0‑45.0、湿度=100.0原始值/65535.0换算出实际温湿度,最终实现 LCD 本地可视化与串口调试助手双重数据输出,屏幕和串口数据保持同步更新;
更多推荐


所有评论(0)