由 黎明将至! 贡献,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>

