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
- Connect the serial port to the virtual machine

- 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
#
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>

