前言
由于本期博客内容代码已经放在已经在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文件代码加注释
代码有什么不明白的可以看一下注释
#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;
}
三、传感器有关数据的截图如下
总结
以上就是本期分享的内容,目的为了介绍一下IIC驱动温湿度传感器的具体流程,以及补充示例代码的注释,还有如何连接模组和传感器,更多资料可从安信可官网上获取。
官方官网:https://www.ai-thinker.com
开发资料:https://docs.ai-thinker.com/
官方论坛:http://bbs.ai-thinker.com
技术支持:support@aithinker.com