FastBond4挑战部分-基于LP-MSPM0G5187与SHT40的楼宇自动化温度采集系统
该项目使用了SHT40,实现了温度采集系统的设计,它的主要功能为:采集温度并串口上报,可以以控制启停。
标签
SHT40
FastBond4
MSPM0G5187
lyz天空
更新2026-06-01
57

一、所选主题和项目介绍

1.1 项目背景

随着楼宇自动化(Building Automation System, BAS)技术的快速发展,环境参数监测已成为智能建筑不可或缺的核心功能之一。温度作为楼宇环境中最重要的环境参数之一,直接影响着人体舒适度、能消耗效率以及设备运行状态。精确、可靠的温度采集系统是实现暖通空调(HVAC)控制、节能优化和舒适度管理的基石。

本项目基于TI最新的LP-MSPM0G5187开发板作为主控单元,结合Sensirion公司的高精度SHT40温湿度传感器,设计了一套具有用户交互功能的温度采集系统。该系统可通过板载按键灵活切换工作模式,通过串口实时输出温湿度数据,非常适用于楼宇自动化场景下的分布式温度监测节点。

1.2 项目目标

本项目旨在实现以下核心目标:

  1. 精确温度采集:利用SHT40传感器的高精度特性,实现室内环境温度的精确测量,测量精度达到±0.3°C(典型值)。
  2. 实时数据输出:通过串口通信接口,以可读的格式实时输出温度和湿度数据,便于上位机采集和后续处理。
  3. 用户交互控制:通过板载按键实现工作模式的切换,用户可选择进入数据采集活跃模式或低功耗空闲模式。
  4. 状态可视化:通过红绿双色LED指示灯,直观显示当前系统工作模式状态。
  5. 模块化设计:采用软件I2C模拟实现与传感器的通信,降低对硬件外设的依赖,提高系统的可移植性。

1.3 应用场景

本项目所设计的温度采集系统可广泛应用于以下楼宇自动化场景:

  • 办公区域温度监测:在大型办公楼的各个楼层或区域部署温度监测节点,实现分区温度管理。
  • 会议室环境监控:实时监测会议室内的温湿度参数,为HVAC系统提供反馈控制依据。
  • 数据中心环境监测:对服务器机房等对温度要求较高的区域进行精确监测,及时发现异常温升。
  • 住宅智能家居节点:作为智能家居系统的环境感知终端,与其他智能设备联动实现舒适度优化。
  • 教学楼与图书馆温控:在教育场所部署,实现根据人流密度自动调节空调参数的功能。

二、硬件介绍

2.1 主控单元:TI LP-MSPM0G5187开发板

LP-MSPM0G5187是TI(Texas Instruments)公司推出的MSPM0系列微控制器开发板之一,搭载了MSPM0G5187微控制器芯片。该芯片基于ARM Cortex-M0+内核,具有出色的能效比和丰富的外设集成,非常适合楼宇自动化等嵌入式应用场景。

本项目使用的主要片上外设包括:

  1. 通用GPIO接口:用于LED指示灯驱动和按键输入检测,支持输入上拉/下拉配置以及外部中断触发。
  2. Timer_A模块:配置为定时器模式,产生周期性中断,用于实现2秒间隔的温湿度数据采集调度。
  3. UART接口:配置为串口通信外设,波特率设为默认配置,用于向上位机发送温湿度数据。
  4. GPIO模拟I2C:通过软件编程模拟I2C通信协议,实现与SHT40传感器的数据交互。

LP-MSPM0G5187开发板提供了丰富的板上资源,包括:

  • 双LED指示灯:红绿双色LED,可通过GPIO直接控制,用于工作状态显示。
  • 用户按键:1个可编程用户按键,连接到GPIO,可配置为外部中断触发。
  • 引脚扩展排针:提供完整的引脚扩展接口,便于连接外部传感器和执行器。
  • 调试接口:集成标准调试器,支持单线调试(SWD)接口。

2.2 感知单元:SHT40传感器

SHT40是Sensirion公司推出的第四代高精度温湿度传感器芯片,属于SHT4x系列的高端型号。该传感器采用了全新的设计和制造工艺,在精度、稳定性和功能特性上都有显著提升。

SHT40采用标准I2C通信接口,支持快速模式(Fast Mode,400kHz)和高速模式(High Speed Mode,1000kHz)。本项目采用100kHz的标准模式,以确保通信可靠性。

传感器响应高精度测量命令(0xFD)后,需要等待典型的85ms测量时间,然后读取6字节的测量数据。数据格式如下:

  • 字节0-1:温度原始数据(Big Endian格式)
  • 字节2:温度CRC校验码
  • 字节3-4:湿度原始数据(Big Endian格式)
  • 字节5:湿度CRC校验码

温度计算公式

SHT40输出的温度原始数据为16位无符号整数,需通过以下公式转换为实际温度值:


T(°C) = -45 + 175 × (raw_temp / 65535)

三、方案框图和项目设计思路

系统总体架构
0

系统功能模块划分

根据系统功能特性,将整个系统划分为以下核心模块:

主控制模块(main函数)

主控制模块负责系统初始化和主循环运行。系统上电后,首先执行各外设模块的初始化配置,包括:

  • GPIO引脚初始化
  • UART串口初始化
  • 定时器Timer_A初始化
  • 软件I2C引脚初始化

初始化完成后,系统进入主循环。主循环在正常情况下为空循环,所有功能性操作均通过中断服务程序完成,这种设计可确保系统的实时响应能力,同时降低功耗。

模式切换模块(switch_mode函数)

模式切换模块负责在IDLE和ACTIVE两种工作模式之间进行切换。该模块提供以下功能:

  • 更新全局工作模式状态变量
  • 控制LED指示灯的亮灭状态
  • 通过UART输出当前模式信息

在IDLE模式下,系统仅维持基本运行状态,不进行温湿度数据采集,红灯亮起表示待机状态。在ACTIVE模式下,系统以2秒为周期持续采集并输出温湿度数据,绿灯亮起表示正常工作状态。

SHT40驱动模块(SHT40_readData函数)

SHT40驱动模块实现了与传感器通信的完整协议,包括:

  • 软件I2C起始条件生成
  • 设备地址发送与ACK检测
  • 测量命令发送
  • 测量等待时间管理
  • 数据读取与CRC校验(校验功能代码中已预留但未强制执行)
  • 温度和湿度原始数据的解析与单位转换

该模块采用查询式设计,每次调用将阻塞等待传感器完成测量并返回数据。

UART通信模块

UART通信模块负责格式化并发送数据到上位机,包括:

  • UART_sendString:发送字符串(阻塞式)
  • UART_sendHex:发送单字节十六进制数据(带空格分隔)
  • UART_sendTempHumidity:发送格式化温湿度数据

输出格式设计充分考虑了可读性和可解析性,温度和湿度均以"XX.XX"格式显示。

3.3 项目设计思路

系统设计了IDLE和ACTIVE两种工作模式,这种双模式策略具有以下实际意义:

  1. 节能考虑:在不需要数据采集时进入IDLE模式,可显著降低系统功耗。
  2. 灵活性:用户可根据实际需求选择是否进行连续数据采集。
  3. 状态明确:通过LED直观显示当前工作状态,避免操作混乱。

四、硬件设计

本次项目单独设计的传感器模块,原理图和PCB下:
0

PCB如下:
0

实物图如下:
0

整体的硬件连接如下:
0

五、软件设计

1 软件流程图

主程序流程图


┌──────────────────────────────────────┐
│ 系统上电 │
└─────────────────┬────────────────────┘


┌──────────────────────────────────────┐
│ 硬件初始化 │
│ · GPIO初始化 │
│ · UART初始化 │
│ · 定时器初始化 │
│ · 软件I2C GPIO初始化 │
└─────────────────┬────────────────────┘


┌──────────────────────────────────────┐
│ 初始状态配置 │
│ · 设置为IDLE模式 │
│ · 红灯亮起 │
│ · 发送系统启动信息 │
└─────────────────┬────────────────────┘


┌──────────────────────────────────────┐
│ 使能中断 │
│ · GPIO中断使能 │
│ · 定时器中断使能 │
└─────────────────┬────────────────────┘


┌──────────────────────────────────────┐
│ 主循环 │
(空循环,等待中断)
└──────────────────────────────────────┘

GPIO中断处理流程图(按键模式切换)


┌──────────────────────────────────────┐
GPIO中断触发 │
└─────────────────┬────────────────────┘


┌──────────────────────────────────────┐
延时消抖 (~160ms)
└─────────────────┬────────────────────┘


┌──────────────────────────────────────┐
│ 再次检测按键状态 │
(确认按键确实按下)
└─────────────────┬────────────────────┘

▼ ┌────────────────────┐
┌──────────────────────────────────────┤ 继续(保持原状态)
│ 判断:按键是否仍为低电平? │ │
└─────────────────┬────────────────────┘ │
│ │
┌────────┴────────┐ │
│ Yes │ No │
▼ ▼ │
┌──────────────┐ ┌──────────────┐ │
│ 执行模式切换 │ │ 忽略本次中断 │
│ switch_mode │ (消除抖动)
└──────┬───────┘ └──────────────┘ │
│ │
▼ │
┌──────────────┐ │
│ 清除中断标志 │ │
└──────────────┘ │

定时器中断处理流程图(数据采集)


┌──────────────────────────────────────┐
定时器中断触发 (1ms)
└─────────────────┬────────────────────┘


┌──────────────────────────────────────┐
│ tick_count++
└─────────────────┬────────────────────┘


┌──────────────────────────────────────┐
│ 判断:tick_count >= 2000? │
(是否已达到2秒周期)
└─────────────────┬────────────────────┘
│ │
┌────────┴────────┐ │
│ Yes │ No │
▼ ▼ │
┌──────────────┐ ┌──────────────┐ │
│ tick_count=0 │ │ 中断返回 │ │
└──────┬───────┘ └──────────────┘ │
│ │
▼ │
┌──────────────┐ │
│ 判断当前模式 │ │
└──────┬───────┘ │
│ │
┌────┴────┐ │
│ │ │
┌─┴──┐ ┌──┴──────┐ │
IDLE│ │ ACTIVE │ │
└─┬──┘ └───┬──────┘ │
│ │ │
▼ ▼ │
┌────┐ ┌──────────────────┐ │
│返回│ │ 调用SHT40_readData│ │
└────┘ └────────┬─────────┘ │
│ │
┌───────┴───────┐ │
│ │ │
▼ ▼ │
┌────────────┐ ┌────────────┐ │
│ 读取成功 │ │ 读取失败 │ │
└─────┬──────┘ └─────┬──────┘ │
│ │ │
▼ │ │
┌────────────┐ │ │
UART发送 │ │ │
│ 温湿度数据 │ │ │
└────────────┘ │ │
│ │
┌────┴────┐ │
│ 返回 │ │
└────────┘ │

I2C通信完整流程图

┌──────────────────────────────────────┐
I2C_START
SDA_OUTSDA_HIGHSCL_HIGH
│ → SDA_LOWSCL_LOW
└──────────────────────────────────────┘

┌──────────────────────────────────────┐
发送设备地址()
I2C_SEND_BYTE(SHT40_ADDR<<1)
└─────────────────┬────────────────────┘

┌────────┴────────┐
ACK检测结果 │
▼ ▼
┌────────┐ ┌────────┐
NACK │ │ ACK
(失败)(成功)
└───┬────┘ └────┬───┘
│ │
▼ ▼
┌───────────────┐ ┌──────────────────┐
I2C_STOP返回 │ │ 发送测量命令0xFD
│ 返回false │ │ I2C_SEND_BYTE
└───────────────┘ └────────┬─────────┘

┌───────┴───────┐
ACK检测结果 │
▼ ▼
┌────────┐ ┌────────┐
NACK │ │ ACK
└───┬────┘ └───┬────┘
│ │
▼ ▼
┌────────────┐ ┌────────────┐
I2C_STOP │ │ I2C_STOP
│ 返回false │ │ 等待85ms │
└────────────┘ └─────┬──────┘


┌──────────────┐
I2C_START
(重复起始)
└─────┬───────┘


┌──────────────┐
│发送设备地址 │
()
└─────┬───────┘

┌────────┴────────┐
ACK检测结果 │
▼ ▼
┌────────┐ ┌────────┐
NACK │ │ ACK
└───┬────┘ └───┬────┘
│ │
▼ ▼
┌────────────┐ ┌──────────────┐
I2C_STOP │ │ 读取6字节数据│
│ 返回false │ │ I2C_RECV_BYTE
└────────────┘ └──────┬───────┘


┌──────────────┐
I2C_STOP
└──────┬───────┘


┌──────────────┐
│ 解析原始数据 │
│ 计算温度/湿度│
└──────────────┘

2 关键代码分析

软件I2C核心实现


/* Software I2C 延时 (约100kHz) */
#define I2C_DELAY() delay_cycles(160) /* 约5us @ 32MHz */

软件I2C的时序参数设计非常关键。I2C标准模式要求SCL频率不超过100kHz,每个时钟周期为10μs。本项目在32MHz系统时钟下,通过delay_cycles(160)实现约5μs的半周期延时,确保SCL频率约为100kHz,满足I2C标准模式时序要求。


/* Software I2C 起始信号 */
static void I2C_START(void)
{
I2C_SDA_OUT();
I2C_SDA_HIGH();
I2C_SCL_HIGH();
I2C_DELAY();
I2C_SDA_LOW(); // 在SCL高电平期间拉低SDA
I2C_DELAY();
I2C_SCL_LOW();
}

起始条件时序分析:按照I2C协议规范,起始条件定义为在SCL高电平期间,SDA从高电平切换到低电平。上述代码严格遵循此规范,确保主控设备正确发起通信。

/* Software I2C 发送一个字节, 返回ACK (0=ACK, 1=NACK) */
static uint8_t I2C_SEND_BYTE(uint8_t data)
{
uint8_t ack;
uint8_t bit;

I2C_SDA_OUT();

/* 发送8位数据 */
for (bit = 0; bit < 8; bit++) {
if (data & 0x80) {
I2C_SDA_HIGH();
} else {
I2C_SDA_LOW();
}
data <<= 1;
I2C_DELAY();

I2C_SCL_HIGH();
I2C_DELAY();
I2C_SCL_LOW();
I2C_DELAY();
}

/* 读取ACK */
I2C_SDA_IN();
I2C_DELAY();

I2C_SCL_HIGH();
I2C_DELAY();

ack = I2C_READ_SDA(); /* 0=ACK, 1=NACK */

I2C_SCL_LOW();
I2C_DELAY();

return ack;
}

字节发送函数实现了标准的I2C字节发送时序:先设置SDA数据,然后拉高SCL产生时钟脉冲,最后拉低SCL完成一位的传输。循环8次完成一个字节的发送。随后释放SDA线并切换到输入模式,发送第九个时钟脉冲并读取从设备的ACK响应。

SHT40数据读取与解析


/* SHT40读取温湿度数据 */
static bool SHT40_readData(float *temperature, float *humidity)
{
uint8_t rxData[6];
uint16_t raw_temp, raw_hum;

/* 发送START */
I2C_START();

/* 发送设备地址+写 */
if (I2C_SEND_BYTE(SHT40_I2C_ADDR << 1)) {
I2C_STOP();
return false; /* NACK */
}

/* 发送测量命令 */
if (I2C_SEND_BYTE(SHT40_CMD_MEASURE_H)) {
I2C_STOP();
return false; /* NACK */
}

/* 发送STOP */
I2C_STOP();

/* 等待85ms测量时间 */
delay_cycles(DELAY / 2);

/* 发送START */
I2C_START();

/* 发送设备地址+读 */
if (I2C_SEND_BYTE((SHT40_I2C_ADDR << 1) | 0x01)) {
I2C_STOP();
return false; /* NACK */
}

/* 读取6字节数据 */
for (int i = 0; i < 6; i++) {
uint8_t ack = (i < 5) ? 0 : 1; /* 前5字节ACK, 最后1字节NACK */
rxData[i] = I2C_RECV_BYTE(ack);
}

/* 发送STOP */
I2C_STOP();

/* 计算温度: T = -45 + 175 * raw / 65535 */
raw_temp = (rxData[0] << 8) | rxData[1];
*temperature = -45.0f + 175.0f * (float)raw_temp / 65535.0f;

/* 计算湿度: RH = 125 * raw / 65535 */
raw_hum = (rxData[3] << 8) | rxData[4];
*humidity = 125.0f * (float)raw_hum / 65535.0f;

return true;
}

SHT40数据读取函数严格按照传感器数据手册的操作流程实现:

  1. 发送起始条件:主控设备发起通信
  2. 发送设备地址(写):I2C地址为0x44,左移一位后为0x88,末位为0表示写操作
  3. 发送测量命令:0xFD表示高精度测量模式
  4. 发送停止条件:完成命令发送后释放总线
  5. 等待测量完成:SHT40需要约85ms完成测量,本项目使用DELAY/2(约0.5秒)延时,充分满足测量时间要求
  6. 再次发起通信:发送重复起始条件,准备读取数据
  7. 发送设备地址(读):地址仍为0x44,左移一位后为0x88,末位为1表示读操作
  8. 读取6字节数据:包括温度原始数据(2字节)、温度CRC、温度校验码(1字节未使用)、湿度原始数据(2字节)、湿度CRC(1字节未使用)
  9. 发送停止条件:完成数据读取
  10. 数据解析与转换:将原始数据转换为标准单位

按键消抖与模式切换


/* GPIO中断处理函数 */
void GROUP1_IRQHandler(void)
{
uint32_t int_iidx = GPIO_GRP_KEY_INT_IIDX;
(void)int_iidx;

/* 消除按键抖动,延时后再次确认 */
delay_cycles(DELAY / 100);
if (DL_GPIO_readPins(GPIO_GRP_KEY_PORT, GPIO_GRP_KEY_PIN_7_PIN) == 0) {
switch_mode();
}

/* 清除中断标志 */
DL_GPIO_clearInterruptStatus(GPIO_GRP_KEY_PORT, GPIO_GRP_KEY_PIN_7_PIN);
}

按键中断处理体现了良好的消抖处理策略。当检测到GPIO中断触发时,并不立即执行模式切换,而是延时约160ms(DELAY/100,即0.5秒的1/100)后再次确认按键状态。只有在延时后按键仍处于按下状态(低电平)时,才执行模式切换。这种双重确认策略可有效避免按键抖动造成的误触发。

定时采集调度


/* 定时器中断处理函数 - 1ms触发一次 */
void TIMA0_IRQHandler(void)
{
static uint16_t tick_count = 0;

/* 清除定时器中断标志 */
DL_Timer_clearInterruptStatus(TIMER_0_INST, DL_TIMER_INTERRUPT_ZERO_EVENT);

/* 计数到2000次 = 2秒 */
tick_count++;
if (tick_count >= 2000) {
tick_count = 0;

/* 只在活跃模式下读取并上报温湿度 */
if (current_mode == MODE_ACTIVE) {
float temperature, humidity;
if (SHT40_readData(&temperature, &humidity)) {
UART_sendTempHumidity(temperature, humidity);
}
}
}
}

定时器中断服务程序采用分频计数策略实现周期性数据采集。定时器每1ms触发一次中断,中断服务程序对tick_count进行递增操作。当计数达到2000时,即表示已过去约2秒时间,此时清零计数器并执行数据采集。只有在ACTIVE模式下,系统才会调用SHT40读取函数并通过UART发送数据。

六、系统功能展示

工作模式切换操作

系统支持两种工作模式,通过板载按键进行切换:

当系统上电或用户按下按键切换后,系统进入IDLE模式:

  • LED状态:红色LED点亮,绿色LED熄灭
  • UART输出:System Start - Mode: IDLE 或 Mode: IDLE (Red LED)
  • 数据采集:不进行温湿度数据采集
  • 功耗状态:处于低功耗待机状态

当用户在IDLE模式下按下按键,系统切换至ACTIVE模式:

  • LED状态:绿色LED点亮,红色LED熄灭
  • UART输出:Mode: ACTIVE (Green LED)
  • 数据采集:每2秒自动采集并发送一次温湿度数据

串口输出示例

相关操作串口输出:
0

七、设计中遇到的难题和解决方法

本次的功能调试要到的主要问题就是I2C的驱动问题,一直到最后都没有实现硬件I2C功能,那怕只跑的官方例程都没有成功,也不知道具体是什么问题,这个流程都没有什么异常,但是对于标志位的查询就会卡主,最后只能通过GPIO的操作模拟I2C的通信流程实现。

八、心得体会

本项目成功实现了一套基于TI LP-MSPM0G5187开发板和SHT40传感器的温度采集系统,充分体现了嵌入式系统在楼宇自动化领域的应用潜力。系统具备精确温度测量、实时数据输出、用户交互控制等核心功能,代码结构清晰、可读性强、易于扩展。

通过本项目的实践,不仅加深了对嵌入式系统开发的理解,也掌握了软硬件协同设计的核心方法。系统所采用的中断驱动架构、软件I2C模拟、双模式工作策略等设计思路,对于今后的嵌入式开发工作具有重要的参考价值。未来可在本项目基础上,进一步扩展系统功能,如增加无线通信、数据存储、LCD显示等模块,形成更加完整的楼宇环境监测解决方案。

附件下载
gpio_toggle_output_LP_MSPM0G5187_nortos_gcc.zip
SHT40.zip
团队介绍
评论
0 / 100
查看更多
硬禾服务号
关注最新动态
0512-67862536
info@eetree.cn
江苏省苏州市苏州工业园区新平街388号腾飞创新园A2幢815室
苏州硬禾信息科技有限公司
Copyright © 2024 苏州硬禾信息科技有限公司 All Rights Reserved 苏ICP备19040198号