Skip to content

由 黎明将至! 贡献,Ai-Thinker 进行整理

Ai-WB2-32S IIC驱动温湿度传感器(SHT31)

前言

由于本期文档内容代码已经放在已经在demo_i2c中实现,代码已经放到了仓库里,注意:使用未修改的bl_uart.c和bl_uart.h文件(这里有的朋友看了uart那一期的文档,可能修改了这两个文件,但以下不需要修改)。 如果想要使用下面流程,请先查看Linux Ubuntu下烧录固件的过程,点击此链接进行查看。

一、具体流程

1.进入目录

cd ~/Ai-Thinker-WB2/applications/peripherals/demo_i2c

2.make编译

make -j8

3.烧录固件

1.将串口连接虚拟机

2.将固件烧录到模组中 make flash p=/dev/ttyUSB0 b=115200

按下模组上的RST键

3.查看运行

这里引脚连接线: 传感器 模组 GND---------------GND VCC---------------3.3V SDA----------------IO3 SCL----------------IO12

再次按下模组上的RST键 显示如下

二、main.c文件代码加注释

代码有什么不明白的可以看一下注释

📜 点击展开完整代码
c
#
include

<stdio.h>

#
include

<FreeRTOS.h>

#
include

<task.h>

#
include

<hosal_i2c.h>

#
include

<bl_gpio.h>

#
include

<blog.h>

#
define
 SHT31_DEFAULT_ADDR 0x0044
//温湿度从机地址

#
define
 SHT31_MEAS_HIGHREP 0x2400
//从机寄存器地址(这里选择高精度模式)

#
pragma
 pack(1)

struct

sht3x_data

{

uint8_t
 st_high;
//温度高字节

uint8_t
 st_low;
//温度低字节

uint8_t
 st_crc8;
//温度crc8(8位冗余校验位)

uint8_t
 srh_high;
//湿度高字节

uint8_t
 srh_low;
//湿度低字节

uint8_t
 srh_crc8;
//湿度crc8

};

#
pragma
 pack()

/******
 *功能:求crc8码
 *data:要求校验码的起始地址
 *len:要求校验码的数据长度
******/

static

uint8_t

crc8
(
uint8_t
 *data,
int
 len)

{

const

uint8_t
 POLYNOMIAL =
0x31
;

uint8_t
 crc =
0xFF
;

for
 (
int
 j = len; j; --j)
    {
        crc ^= *data++;

for
 (
int
 i =
8
; i; --i)
        {
            crc = (crc &
0x80
)
                      ? (crc <<
1
) ^ POLYNOMIAL
                      : (crc <<
1
);
        }
    }

return
 crc;
}

//主函数

int

main
(
void
)

{

//IIC外设结构体

static

hosal_i2c_dev_t
 i2c0 = {
        .config = {
            .address_width = HOSAL_I2C_ADDRESS_WIDTH_7BIT,
//IIC从机地址位长度

            .freq =
100000
,
//IIC通信分频数

            .mode = HOSAL_I2C_MODE_MASTER,
//IIC外设为什么模式(这里设置为主机模式)

            .scl =
12
,
//IIC时钟端映射的引脚

            .sda =
3
,
//IIC数据端映射的引脚

        },
        .port =
0
,
//IIC端口号

    };

//IIC初始化

    hosal_i2c_init(&i2c0);

//死循环,使模组一直循环执行以下代码

for
 (;;) {

//创建数据结构体变量

struct

sht3x_data

data
;

//将寄存器地址转换为数据形式

uint8_t
 command[
2
] = { SHT31_MEAS_HIGHREP >>
8
, SHT31_MEAS_HIGHREP &
0xff
 };

//发送从机地址,写位,寄存器地址

        hosal_i2c_master_send(&i2c0, SHT31_DEFAULT_ADDR, command,
sizeof
 command,
100
);

//发送从机地址,读位,接受从机返回的数据到数据结构体变量

        hosal_i2c_master_recv(&i2c0, SHT31_DEFAULT_ADDR, (
uint8_t
*)&data,
sizeof
 data,
100
);

//温度缓冲区

char
 temperature_str[
8
];

//湿度缓冲区

char
 humidity_str[
8
];

//温度数据校验并求出温度的具体值

if
 (crc8(&data.st_high,
2
) == data.st_crc8) {

uint16_t
 st = data.st_high;
//存放温度的值

            st <<=
8
;
            st |= data.st_low;

//根据传感器手册求出相应的温度值

int
 temp = st;
            temp *=
17500
;
            temp /=
0xffff
;
            temp =
-4500
 + temp;

int
 temperature_integer = temp /
100
;
//存放温度小数点前的值

//如果温度小于0,则对数据取反(因为下面要获取温度小数点后的值)

if
 (temp <
0
) {
                temp = -temp;
            }

unsigned
 temperature_decimal = temp %
100
;
//存放温度小数点后的值

//将求得的数据值以一定的格式放入到温度缓冲区里面

sprintf
(temperature_str,
"%d.%02u C"
, temperature_integer, temperature_decimal);
        }
//校验错误,打印错误信息N/A

else
 {

sprintf
(temperature_str,
"%s"
,
"N/A C"
);
        }

////湿度数据校验并求出温度的具体值

if
 (crc8(&data.srh_high,
2
) == data.srh_crc8) {

uint16_t
 srh = data.srh_high;
            srh <<=
8
;
            srh |= data.srh_low;

//根据传感器手册求出相应的温度值

unsigned
 humidity = srh;
            humidity *=
10000
;
            humidity /=
0xFFFF
;

unsigned
 humidity_integer = humidity /
100
;

sprintf
(humidity_str,
"%u %%"
, humidity_integer);
        }
//校验错误,打印错误信息N/A

else
 {

sprintf
(humidity_str,
"N/A %%"
);
        }

//将数据通过串口发送出去

        blog_info(
"temperature: %s\thumidity: %s\r\n"
, temperature_str, humidity_str);

//延迟1000ms

        vTaskDelay(portTICK_RATE_MS *
1000
);
    }

return

0
;
}

三、传感器有关数据的截图如下

原链接:<https://blog.csdn.net/qq_54193285/article/details/135949843?spm=1001.2014.3001.5501>

Released under the MIT License. Build Time 2026-09-11 14:52:23