# FRDM-MCXW72 驱动 SHT30 温湿度传感器教程
这篇文章记录一下我使用 **FRDM-MCXW72** 开发板,在 **Zephyr RTOS** 下驱动 **SHT30 温湿度传感器** 的过程。
本实验通过 **I2C** 接口读取 SHT30 的温度和湿度数据,然后通过串口打印出来。
## 一、实验目标
本次实验实现以下功能:
1. 使用 FRDM-MCXW72 运行 Zephyr 程序;
2. 通过 I2C 接口连接 SHT30 温湿度传感器;
3. 使用 Zephyr 的 Sensor API 读取温度和湿度;
4. 通过串口终端周期性打印温湿度数据。
## 二、硬件准备
需要准备以下硬件:
| 硬件 | 数量 |
| - | - |
| FRDM-MCXW72 开发板 | 1 |
| SHT30 温湿度传感器模块 | 1 |
| 杜邦线 | 若干 |
| USB 数据线 | 1 |
SHT30 是一款常见的数字温湿度传感器,通信接口一般为 I2C。
常见 SHT30 模块默认 I2C 地址为:
```c
0x44
```
有些模块可以通过 ADDR 引脚切换为:
```c
0x45
```
本文默认使用地址:
```c
0x44
```
## 三、硬件接线
SHT30 通过 I2C 与开发板通信,一般只需要连接 4 根线。
| SHT30 引脚 | FRDM-MCXW72 引脚 | 说明 |
| - | - | - |
| VCC / VIN | 3.3V | 电源 |
| GND | GND | 地 |
| SDA | I2C SDA | I2C 数据线 |
| SCL | I2C SCL | I2C 时钟线 |
注意事项:
1. SHT30 建议使用 3.3V 供电;
2. SDA 和 SCL 不要接反;
3. 如果使用的是带 Arduino 接口的模块,可以优先接到开发板 Arduino 接口的 SDA / SCL;
4. 如果后面读取失败,优先检查 I2C 总线和地址是否正确。
## 四、Zephyr 环境准备
我这里使用的是 Windows 下的 Zephyr 开发环境。
如果已经安装好 Zephyr,可以直接进入工作目录并激活虚拟环境:
```powershell
cd D:\Zephyr
zephyrproject\.venv\Scripts\Activate.ps1
```
进入 Zephyr 工作区:
```powershell
cd D:\Zephyr\zephyrproject
```
查看 west 是否正常:
```powershell
west --version
```
查看当前 Zephyr 是否支持 FRDM-MCXW72:
```powershell
west boards | Select-String -Pattern "mcxw72" -CaseSensitive:$false
```
如果能看到类似下面的开发板名称,说明环境正常:
```text
frdm_mcxw72
```
或者可能是带 qualifier 的形式,例如:
```text
frdm_mcxw72/mcxw727c
```
后面编译时,板卡名称以自己电脑上 `west boards` 实际输出为准。
## 五、创建工程目录
在 Zephyr 工作区下面创建一个 SHT30 示例工程。
```powershell
cd D:\Zephyr\zephyrproject
mkdir sht30_demo
cd sht30_demo
mkdir src
```
工程结构如下:
```text
sht30_demo
├── CMakeLists.txt
├── prj.conf
├── app.overlay
└── src
└── main.c
```
## 六、编写 CMakeLists.txt
在 `sht30_demo` 目录下新建 `CMakeLists.txt` 文件,内容如下:
```cmake
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(frdm_mcxw72_sht30_demo)
target_sources(app PRIVATE src/main.c)
```
## 七、编写 prj.conf
在 `sht30_demo` 目录下新建 `prj.conf` 文件,内容如下:
```conf
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_I2C=y
CONFIG_SENSOR=y
CONFIG_SHT3XD=y
CONFIG_LOG=y
CONFIG_SENSOR_LOG_LEVEL_INF=y
```
这里几个关键配置说明一下:
```conf
CONFIG_I2C=y
```
表示启用 I2C 总线。
```conf
CONFIG_SENSOR=y
```
表示启用 Zephyr 传感器框架。
```conf
CONFIG_SHT3XD=y
```
表示启用 Sensirion SHT3x 系列传感器驱动,SHT30 就属于这个系列。
## 八、编写设备树 overlay
在 `sht30_demo` 目录下新建 `app.overlay` 文件。
这里需要根据开发板实际使用的 I2C 总线来写。一般可能是 `i2c0`、`i2c1` 或 `i2c2`。
这里先以 `i2c1` 为例:
```dts
&i2c1 {
status = "okay";
sht30: sht30@44 {
compatible = "sensirion,sht3xd";
reg = <0x44>;
status = "okay";
};
};
```
如果你的 SHT30 地址是 `0x45`,则改成:
```dts
&i2c1 {
status = "okay";
sht30: sht30@45 {
compatible = "sensirion,sht3xd";
reg = <0x45>;
status = "okay";
};
};
```
如果编译时报 `i2c1` 不存在,就需要查看 FRDM-MCXW72 的设备树,确认实际使用的 I2C 节点。
可以进入 Zephyr 根目录搜索:
```powershell
cd D:\Zephyr\zephyrproject\zephyr
Get-ChildItem -Recurse boards | Select-String -Pattern "frdm_mcxw72"
```
也可以搜索 I2C 相关内容:
```powershell
Get-ChildItem -Recurse boards | Select-String -Pattern "i2c"
```
如果发现开发板使用的是 `i2c0` 或 `i2c2`,就把 overlay 里的 `&i2c1` 改掉即可。
例如:
```dts
&i2c0 {
status = "okay";
sht30: sht30@44 {
compatible = "sensirion,sht3xd";
reg = <0x44>;
status = "okay";
};
};
```
## 九、编写 main.c
在 `src` 目录下新建 `main.c` 文件,内容如下:
```c
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/sys/printk.h>
#define SHT30_NODE DT_NODELABEL(sht30)
int main(void)
{
const struct device *sht30 = DEVICE_DT_GET(SHT30_NODE);
struct sensor_value temperature;
struct sensor_value humidity;
printk("FRDM-MCXW72 SHT30 demo start\r\n");
if (!device_is_ready(sht30)) {
printk("SHT30 device is not ready\r\n");
return 0;
}
printk("SHT30 device is ready\r\n");
while (1) {
int ret;
ret = sensor_sample_fetch(sht30);
if (ret < 0) {
printk("Failed to fetch sample, ret = %d\r\n", ret);
k_sleep(K_SECONDS(2));
continue;
}
ret = sensor_channel_get(sht30, SENSOR_CHAN_AMBIENT_TEMP, &temperature);
if (ret < 0) {
printk("Failed to get temperature, ret = %d\r\n", ret);
k_sleep(K_SECONDS(2));
continue;
}
ret = sensor_channel_get(sht30, SENSOR_CHAN_HUMIDITY, &humidity);
if (ret < 0) {
printk("Failed to get humidity, ret = %d\r\n", ret);
k_sleep(K_SECONDS(2));
continue;
}
printk("Temperature: %d.%06d C, Humidity: %d.%06d %%RH\r\n",
temperature.val1,
temperature.val2,
humidity.val1,
humidity.val2);
k_sleep(K_SECONDS(2));
}
return 0;
}
```
## 十、编译工程
进入工程目录:
```powershell
cd D:\Zephyr\zephyrproject\sht30_demo
```
如果你的板卡名称是:
```text
frdm_mcxw72
```
则执行:
```powershell
west build -p always -b frdm_mcxw72 .
```
如果你的板卡名称是带 qualifier 的形式,例如:
```text
frdm_mcxw72/mcxw727c
```
则执行:
```powershell
west build -p always -b frdm_mcxw72/mcxw727c .
```
编译成功后,可以看到类似输出:
```text
[xxx/xxx] Linking C executable zephyr/zephyr.elf
Memory region Used Size Region Size %age Used
FLASH: xxx KB
RAM: xxx KB
```
## 十一、烧录程序
使用 USB 线连接 FRDM-MCXW72 开发板,然后执行:
```powershell
west flash
```
如果烧录正常,会看到类似输出:
```text
-- west flash: rebuilding
ninja: no work to do.
-- west flash: using runner ...
-- runners.xxx: Flashing file: build/zephyr/zephyr.hex
```
## 十二、打开串口查看数据
烧录完成后,打开串口工具,例如:
1. PuTTY
2. MobaXterm
3. Tera Term
4. VS Code Serial Monitor
串口参数一般设置为:
```text
波特率:115200
数据位:8
停止位:1
校验位:None
流控:None
```
打开串口后,按一下开发板 Reset 按键,可以看到类似输出:
```text
FRDM-MCXW72 SHT30 demo start
SHT30 device is ready
Temperature: 25.123456 C, Humidity: 48.654321 %RH
Temperature: 25.125678 C, Humidity: 48.612345 %RH
Temperature: 25.126789 C, Humidity: 48.598765 %RH
```
这样就说明 FRDM-MCXW72 已经成功读取到了 SHT30 的温湿度数据。
## 十三、完整代码汇总
下面把整个工程的代码整理到一起,方便复制。
### 1. CMakeLists.txt
```cmake
cmake_minimum_required(VERSION 3.20.0)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(frdm_mcxw72_sht30_demo)
target_sources(app PRIVATE src/main.c)
```
### 2. prj.conf
```conf
CONFIG_SERIAL=y
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y
CONFIG_I2C=y
CONFIG_SENSOR=y
CONFIG_SHT3XD=y
CONFIG_LOG=y
CONFIG_SENSOR_LOG_LEVEL_INF=y
```
### 3. app.overlay
```dts
&i2c1 {
status = "okay";
sht30: sht30@44 {
compatible = "sensirion,sht3xd";
reg = <0x44>;
status = "okay";
};
};
```
如果使用 `0x45` 地址,则改为:
```dts
&i2c1 {
status = "okay";
sht30: sht30@45 {
compatible = "sensirion,sht3xd";
reg = <0x45>;
status = "okay";
};
};
```
### 4. src/main.c
```c
#include <zephyr/kernel.h>
#include <zephyr/device.h>
#include <zephyr/drivers/sensor.h>
#include <zephyr/sys/printk.h>
#define SHT30_NODE DT_NODELABEL(sht30)
int main(void)
{
const struct device *sht30 = DEVICE_DT_GET(SHT30_NODE);
struct sensor_value temperature;
struct sensor_value humidity;
printk("FRDM-MCXW72 SHT30 demo start\r\n");
if (!device_is_ready(sht30)) {
printk("SHT30 device is not ready\r\n");
return 0;
}
printk("SHT30 device is ready\r\n");
while (1) {
int ret;
ret = sensor_sample_fetch(sht30);
if (ret < 0) {
printk("Failed to fetch sample, ret = %d\r\n", ret);
k_sleep(K_SECONDS(2));
continue;
}
ret = sensor_channel_get(sht30, SENSOR_CHAN_AMBIENT_TEMP, &temperature);
if (ret < 0) {
printk("Failed to get temperature, ret = %d\r\n", ret);
k_sleep(K_SECONDS(2));
continue;
}
ret = sensor_channel_get(sht30, SENSOR_CHAN_HUMIDITY, &humidity);
if (ret < 0) {
printk("Failed to get humidity, ret = %d\r\n", ret);
k_sleep(K_SECONDS(2));
continue;
}
printk("Temperature: %d.%06d C, Humidity: %d.%06d %%RH\r\n",
temperature.val1,
temperature.val2,
humidity.val1,
humidity.val2);
k_sleep(K_SECONDS(2));
}
return 0;
}
```
## 十四、常见问题
### 1. 编译提示 `CONFIG_SHT3XD` 未定义
如果出现类似提示:
```text
warning: attempt to assign the value 'y' to the undefined symbol SHT3XD
```
说明当前 Zephyr 版本中可能没有这个驱动,或者驱动配置名称不同。
可以在 Zephyr 根目录搜索:
```powershell
cd D:\Zephyr\zephyrproject\zephyr
Get-ChildItem -Recurse . | Select-String -Pattern "config SHT3"
```
根据搜索到的 Kconfig 名称修改 `prj.conf`。
### 2. 编译提示 `i2c1` 未定义
如果出现:
```text
undefined node label 'i2c1'
```
说明 `app.overlay` 里的 I2C 节点写错了。
解决方法是查看 FRDM-MCXW72 的设备树文件,确认实际可用的是 `i2c0`、`i2c1` 还是 `i2c2`,然后修改 overlay。
### 3. 串口输出 `SHT30 device is not ready`
如果输出:
```text
SHT30 device is not ready
```
可能原因:
1. I2C 控制器没有启用;
2. overlay 里 I2C 总线选错;
3. SHT30 地址写错;
4. SDA / SCL 接反;
5. 传感器没有供电;
6. I2C 上拉电阻异常。
建议优先检查接线和地址。
### 4. 反复输出 `Failed to fetch sample`
如果程序运行后反复输出:
```text
Failed to fetch sample
```
说明设备树里的 SHT30 节点已经创建,但是实际 I2C 通信失败。
重点检查:
1. SHT30 地址是 `0x44` 还是 `0x45`;
2. SDA 和 SCL 是否接反;
3. I2C 总线是否选错;
4. 模块供电是否正常;
5. 杜邦线是否接触不良。
## 十五、常用命令汇总
激活 Zephyr 环境:
```powershell
cd D:\Zephyr
zephyrproject\.venv\Scripts\Activate.ps1
```
进入工程目录:
```powershell
cd D:\Zephyr\zephyrproject\sht30_demo
```
编译:
```powershell
west build -p always -b frdm_mcxw72 .
```
如果板卡名称带 qualifier:
```powershell
west build -p always -b frdm_mcxw72/mcxw727c .
```
烧录:
```powershell
west flash
```
查看板卡名称:
```powershell
west boards | Select-String -Pattern "mcxw72" -CaseSensitive:$false
```
## 十六、实验现象
程序烧录后,打开串口终端,可以看到温湿度数据每 2 秒刷新一次:
```text
FRDM-MCXW72 SHT30 demo start
SHT30 device is ready
Temperature: 25.123456 C, Humidity: 48.654321 %RH
Temperature: 25.125678 C, Humidity: 48.612345 %RH
Temperature: 25.126789 C, Humidity: 48.598765 %RH
```
至此,FRDM-MCXW72 驱动 SHT30 温湿度传感器实验完成。
我要赚赏金
