Skip to content

Contributed by 黎明将至!, organized by Ai-Thinker

Ai-WB2-32S IIC Driving a Temperature and Humidity Sensor (SHT31)

Preface

The code for this tutorial has already been implemented in demo_i2c and pushed to the repository. Note: use the unmodified bl_uart.c and bl_uart.h files (some readers may have modified these two files while following the UART tutorial, but no modification is required below).

If you want to follow the procedure below, please first check the firmware flashing process under Linux Ubuntu by clicking this link.

1. Detailed Procedure

Step 1. Enter the directory

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

Step 2. Compile with make

make -j8

Step 3. Flash the firmware

  1. Connect the serial port to the virtual machine

  1. Flash the firmware to the module make flash p=/dev/ttyUSB0 b=115200

按下模组上的RST键

Step 4. Check the output

Here is the pin connection: Sensor Module GND---------------GND VCC---------------3.3V SDA----------------IO3 SCL----------------IO12

再次按下模组上的RST键 The display is as follows

2. main.c Code with Comments

If you don't understand any part of the code, check the comments.

Click to expand full code
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
;
}

3. Screenshots of the Sensor Data

Original link: <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