这些小活动你都参加了吗?快来围观一下吧!>>
电子产品世界 » 论坛首页 » 活动中心 » 板卡试用 » 【e起DIY】低功耗蓝牙温湿度计SHT30传感器驱动开发

共1条 1/1 1 跳转至

【e起DIY】低功耗蓝牙温湿度计SHT30传感器驱动开发

助工
2026-05-09 14:19:49     打赏
  1. 板卡链接示意图4a0a2748-8f61-42a6-8a11-7e25ad56ddb8.jpg

获取温湿度传感器I2C地址我在淘宝购买了SHT30,通过NRF54L15-DK一直驱动不行,通过其他板卡可以正常驱动。 后面原因分析其中对SHT30对电压很敏感,在其中1.8V和5V之间都不行,只能在基础值3.3V才能成功驱动。 NRF带有nPM1300电管理芯片来输出电压,我们可以通过软件来修改输出电压。修改VDDIO输出电压为3.3V

我们找到Board Configuartor

image.png

先选定我们的开发板,将我们的电压修改为3.3V,之后写入到我们的配置里其中的VDDIO就能输出3.3V

image.png

通过I2C查询地址可以获得其中的I2C的从地址

image.png

温湿度传感器驱动编写app.overrlay这个是zerphy的设备树的配置其中NRF通过TWIM来配置I2C
&i2c21 {
    status = "okay";
    pinctrl-0 = <&i2c21_default>;
    pinctrl-names = "default";
    clock-frequency = <I2C_BITRATE_STANDARD>; 

    sht3xd@44 {
        compatible = "sensirion,sht3xd";
        reg = <0x44>;
    };
};

&pinctrl {
    i2c21_default: i2c21_default {
        group1 {
            psels = <NRF_PSEL(TWIM_SCL, 1, 11)>,
                    <NRF_PSEL(TWIM_SDA, 1, 12)>;
            bias-pull-up; 
        };
    };
};
这里我们选择的引脚P1.11和P1.12将我们的地址信息填写进去其中prj.conf需要打开我们相关配置在这里我们使用到了I2C和其中I2C引脚配置,然后通过配置开启
CONFIG_I2C=y
CONFIG_PRINTK=y
CONFIG_NRFX_TWIM=y
# 新增:开启浮点数打印支持
CONFIG_CBPRINTF_FP_SUPPORT=y
主要实现代码
#include <zephyr/kernel.h>
#include <zephyr/drivers/i2c.h>
#include <stdio.h> /* 用于更标准的 printf 输出 */

/* I2C 结构体定义 */
static const struct i2c_dt_spec sht30_dev = I2C_DT_SPEC_GET(DT_NODELABEL(sht30));

/* SHT3x 标准 CRC-8 校验函数 */
static uint8_t sht3x_crc_check(uint8_t *data, int len) {
    uint8_t crc = 0xFF;
    for (int i = 0; i < len; i++) {
        crc ^= data[i];
        for (int j = 0; j < 8; j++) {
            if (crc & 0x80) {
                crc = (crc << 1) ^ 0x31;
            } else {
                crc <<= 1;
            }
        }
    }
    return crc;
}

/**
 * @brief 读取 GY-SHT30 温湿度数据
 * @param temp 输出温度指针
 * @param hum  输出湿度指针
 * @return 0 成功, -1 失败
 */
int read_gy_sht30(double *temp, double *hum) {
    uint8_t cmd[2] = {0x24, 0x00}; // 高精度单次测量命令
    uint8_t rx_buf[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 
    int ret;

    // 1. 发送测量指令
    ret = i2c_write_dt(&sht30_dev, cmd, 2);
    if (ret < 0) {
        printk("Error: Failed to send measurement command (%d)\n", ret);
        return -1;
    }

    // 2. 等待测量完成 (SHT30 高精度模式最大需要 15ms)
    k_msleep(20);

    // 3. 读取 6 字节原始数据
    ret = i2c_read_dt(&sht30_dev, rx_buf, 6);
    if (ret < 0) {
        printk("Error: Failed to read data from SHT30 (%d)\n", ret);
        return -1;
    }

    // 打印原始数据
    printk("Raw Data: T_MSB:%02X T_LSB:%02X T_CRC:%02X | RH_MSB:%02X RH_LSB:%02X RH_CRC:%02X\n",
           rx_buf[0], rx_buf[1], rx_buf[2], rx_buf[3], rx_buf[4], rx_buf[5]);

    // 4. 数据完整性校验 (CRC)
    if (sht3x_crc_check(&rx_buf[0], 2) != rx_buf[2]) {
        printk("Error: Temperature CRC check failed!\n");
        return -1;
    }
    if (sht3x_crc_check(&rx_buf[3], 2) != rx_buf[5]) {
        printk("Error: Humidity CRC check failed!\n");
        return -1;
    }

    // 5. 物理量转换
    uint16_t raw_t = (rx_buf[0] << 8) | rx_buf[1];
    uint16_t raw_rh = (rx_buf[3] << 8) | rx_buf[4];

    *temp = -45.0 + 175.0 * (double)raw_t / 65535.0;
    *hum = 100.0 * (double)raw_rh / 65535.0;

    return 0;
}

int main(void) {
    double temperature, humidity;

    printk("Starting SHT30 test...\n");

    // 检查 I2C 设备是否就绪
    if (!i2c_is_ready_dt(&sht30_dev)) {
        printk("Error: I2C device not ready.\n");
        return 0;
    }

    while (1) {
        if (read_gy_sht30(&temperature, &humidity) == 0) {
            // 使用 printf 打印格式化浮点数,注意 %% 转义 %
            printf("Temperature: %.1f°C, Humidity: %.1f%%RH\n\n", temperature, humidity);
        } else {
            printk("Failed to read sensor data. Retrying...\n\n");
        }
        
        k_msleep(2000); // 每两秒读一次
    }
    return 0;
}

通过串口查看,成功将数据读取出来

image.png



共1条 1/1 1 跳转至

回复

匿名不能发帖!请先 [ 登陆 注册 ]