目录
概述
1 硬件接口介绍
1.1 Version Board上的I2C硬件接口
1.2 SHT20
1.2.1 SHT20简介
1.2.2 SHT-20模块电路
2 软件实现
2.1 软件版本信息
2.2 RT-Thread Studio创建项目
2.3 FSP配置I2C接口
2.4 使能Sensor驱动
3 RT-Thread驱动架构
3.1 接口函数
3.1.1 查找设备函数
3.1.2 数据传输函数
3.3 驱动Demo
4 系统测试
4.1 硬件环境
4.2 软件测试方法介绍
4.2.1 探测传感器
4.2.2 读取数据
4.3 板卡级测试
4.3.1 准备测试环境
4.3.2 测试
概述
本文主要介绍如何使用Renesa Version Board上的I2C接口在RT -Thread框架下功能的应用。笔者基于SHT-Sensor详细介绍了配置的方法。还介绍了RT -Thread框架下I2C驱动的接口函数。
1 硬件接口介绍
1.1 Version Board上的I2C硬件接口
Renesa Version Board板卡扩展口提供一个标准的I2C接口,其命名如下:
在如下网址能看见该IO所对应的Pin引脚:
https://www.rt-thread.org/document/site/#/rt-thread-version/rt-thread-standard/hw-board/ra8d1-vision-board/ra8d1-vision-board
1.2 SHT20
1.2.1 SHT20简介
SHT20是由Sensirion公司推出的一款数字温湿度传感器。它采用先进的CMOSens®技术,具有高精度、低功耗和长期稳定性的特点。
SHT20的测量范围涵盖了-40℃至125℃的温度和0%至100%的湿度,精确度分别为±0.3℃和±3%RH。它使用了数字式输出接口,可以通过I2C总线进行数据通信,并支持温度和湿度的实时测量。
SHT20的封装形式小巧,尺寸为3x3x1.1mm,适合各种应用场景。它具有低功耗特性,工作电压范围为2.1V至3.6V,供电电流在典型条件下为1.2mA。此外,SHT20还具有快速响应时间和强大的抗干扰能力。
1.2.2 SHT-20模块电路
1)SHT20硬件接口图
2) sensor模块电路
SHT-20实物图:
2 软件实现
2.1 软件版本信息
软硬件信息 | 版本信息 |
---|---|
Renesas MCU | R7FA8D1BH |
RT-Thread Studio | 2.2.7 |
FSP 版本 | 5.1.0 |
调试工具:DAP-link | ART-Link CMSIS-DAP: V2.0.0 |
2.2 RT-Thread Studio创建项目
打开RT-Thread Studio,File->RT-Thread Project,打开之后看见如下页面,输入项目名称,创建项目。
2.3 FSP配置I2C接口
1)选择SCI3接口,配置为I2C模式,该接口对应的IO口为P408和P409
2)在Stacks面板上配置驱动的相关信息
完成以上两个步骤之后,就可以重新生成项目代码。
3) RT-Thread Studio打开驱动接口,配置完成后,使用Ctrl+S保存文件。
2.4 使能Sensor驱动
打开RT-Thread Setting,搜索sht2,找到该驱动后使能该驱动。
在项目目录中,packages中已经加载该驱动程序。
3 RT-Thread驱动架构
3.1 接口函数
一般来说,MCU的I2C设备作为主从设备进行通信。在RT-Thread中,I2C主机被虚拟化为I2C总线设备。I2C从站通过I2C设备接口与I2C总线通信。相关接口如下:
Function | Description |
---|---|
rt_device_find() | Find device handles based on I2C bus device name |
rt_i2c_transfer() | transfer data |
3.1.1 查找设备函数
在使用I2C总线设备之前,需要根据I2C总线设备名称获取设备句柄,以便对I2C总线设备进行操作。设备功能如下:
rt_device_t rt_device_find(const char* name);
Parameter | Description |
---|---|
name | I2C bus device name |
Return Value | —— |
device handle | Finding the corresponding device will return the corresponding device handle |
RT_NULL | No corresponding device object found |
举个例子:
注册到系统的I2C设备名称为i2co2、i2c1等。使用示例如下:
#define AHT10_I2C_BUS_NAME "i2c1" /* Sensor connected I2C bus device name */
struct rt_i2c_bus_device *i2c_bus; /* I2C bus device handle *//* Find the I2C bus device and get the I2C bus device handle */
i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(name);
3.1.2 数据传输函数
可以通过获取I2C总线设备句柄来使用' rt_i2c_transfer() '进行数据传输。函数原型如下:
rt_size_t rt_i2c_transfer(struct rt_i2c_bus_device *bus,struct rt_i2c_msg msgs[],rt_uint32_t num);
Parameter | Description |
---|---|
bus | I2C bus device handle |
msgs[] | Message array pointer to be transmitted |
num | The number of elements in the message array |
Return Value | —— |
the number of elements in the message array | succeeded |
error code | failed |
一个应用实例:
Message结构体定义
struct rt_i2c_msg
{rt_uint16_t addr; /* Slave address */rt_uint16_t flags; /* Reading, writing signs, etc. */rt_uint16_t len; /* Read and write data bytes */rt_uint8_t *buf; /* Read and write data buffer pointer */
}
读数据函数实现
/* Read sensor register data */
static rt_err_t read_regs(struct rt_i2c_bus_device *bus, rt_uint8_t len, rt_uint8_t *buf)
{struct rt_i2c_msg msgs;msgs.addr = AHT10_ADDR; /* Slave address */msgs.flags = RT_I2C_RD; /* Read flag */msgs.buf = buf; /* Read and write data buffer pointer */msgs.len = len; /* Read and write data bytes *//* Call the I2C device interface to transfer data */if (rt_i2c_transfer(bus, &msgs, 1) == 1){return RT_EOK;}else{return -RT_ERROR;}
}
3.3 驱动Demo
RT-Thread提供了一个Demo,其详细代码如下:
/** Program listing: This is an I2C device usage routine* The routine exports the i2c_aht10_sample command to the control terminal* Command call format: i2c_aht10_sample i2c1* Command explanation: The second parameter of the command is the name of the I2C bus device to be used. If it is empty, the default I2C bus device is used.* Program function: read the temperature and humidity data of the aht10 sensor and print.
*/#include <rtthread.h>
#include <rtdevice.h>#define AHT10_I2C_BUS_NAME "i2c1" /* Sensor connected I2C bus device name */
#define AHT10_ADDR 0x38 /* Slave address */
#define AHT10_CALIBRATION_CMD 0xE1 /* Calibration command */
#define AHT10_NORMAL_CMD 0xA8 /* General command */
#define AHT10_GET_DATA 0xAC /* Get data command */static struct rt_i2c_bus_device *i2c_bus = RT_NULL; /* I2C bus device handle */
static rt_bool_t initialized = RT_FALSE; /* Sensor initialization status *//* Write sensor register */
static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint8_t reg, rt_uint8_t *data)
{rt_uint8_t buf[3];struct rt_i2c_msg msgs;buf[0] = reg; //cmdbuf[1] = data[0];buf[2] = data[1];msgs.addr = AHT10_ADDR;msgs.flags = RT_I2C_WR;msgs.buf = buf;msgs.len = 3;/* Call the I2C device interface to transfer data */if (rt_i2c_transfer(bus, &msgs, 1) == 1){return RT_EOK;}else{return -RT_ERROR;}
}/* Read sensor register data */
static rt_err_t read_regs(struct rt_i2c_bus_device *bus, rt_uint8_t len, rt_uint8_t *buf)
{struct rt_i2c_msg msgs;msgs.addr = AHT10_ADDR;msgs.flags = RT_I2C_RD;msgs.buf = buf;msgs.len = len;/* Call the I2C device interface to transfer data */if (rt_i2c_transfer(bus, &msgs, 1) == 1){return RT_EOK;}else{return -RT_ERROR;}
}static void read_temp_humi(float *cur_temp, float *cur_humi)
{rt_uint8_t temp[6];write_reg(i2c_bus, AHT10_GET_DATA, 0); /* send command */rt_thread_mdelay(400);read_regs(i2c_bus, 6, temp); /* obtian sensor data *//* Humidity data conversion */*cur_humi = (temp[1] << 12 | temp[2] << 4 | (temp[3] & 0xf0) >> 4) * 100.0 / (1 << 20);/* Temperature data conversion */*cur_temp = ((temp[3] & 0xf) << 16 | temp[4] << 8 | temp[5]) * 200.0 / (1 << 20) - 50;
}static void aht10_init(const char *name)
{rt_uint8_t temp[2] = {0, 0};/* Find the I2C bus device and get the I2C bus device handle */i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(name);if (i2c_bus == RT_NULL){rt_kprintf("can't find %s device!\n", name);}else{write_reg(i2c_bus, AHT10_NORMAL_CMD, temp);rt_thread_mdelay(400);temp[0] = 0x08;temp[1] = 0x00;write_reg(i2c_bus, AHT10_CALIBRATION_CMD, temp);rt_thread_mdelay(400);initialized = RT_TRUE;}
}static void i2c_aht10_sample(int argc, char *argv[])
{float humidity, temperature;char name[RT_NAME_MAX];humidity = 0.0;temperature = 0.0;if (argc == 2){rt_strncpy(name, argv[1], RT_NAME_MAX);}else{rt_strncpy(name, AHT10_I2C_BUS_NAME, RT_NAME_MAX);}if (!initialized){/* Sensor initialization */aht10_init(name);}if (initialized){/* Read temperature and humidity data */read_temp_humi(&temperature, &humidity);rt_kprintf("read aht10 sensor humidity : %d.%d %%\n", (int)humidity, (int)(humidity * 10) % 10);rt_kprintf("read aht10 sensor temperature: %d.%d \n", (int)temperature, (int)(temperature * 10) % 10);}else{rt_kprintf("initialize sensor failed!\n");}
}
/* Export to the msh command list */
MSH_CMD_EXPORT(i2c_aht10_sample, i2c aht10 sample);
4 系统测试
4.1 硬件环境
将SHT20的电源和通信接口与Version Board连接起来,其连接图如下:
硬件实物图如下:
4.2 软件测试方法介绍
RT-Thread已经提供了SHT20相关的测试命令,其具体测试方法如下:
4.2.1 探测传感器
sht2x 软件包提供了丰富的测试命令,项目只要在 RT-Thread 上开启 Finsh/MSH 功能即可。在做一些基于 sht2x
的应用开发、调试时,这些命令会非常实用,它可以准确的读取指传感器测量的温度与湿度。具体功能可以输入 sht20
,可以查看完整的命令列表:
msh /> sht20
Usage:
sht20 probe <dev_name> - probe sensor by given name
sht20 read - read sensor sht20 data
msh />
具体方法如下:
msh />sht20 probe i2c1 #探测成功,没有错误日志
msh />
msh />sht20 probe i2c88 #探测失败,提示对应的 I2C 设备找不到
[E/sht20] can't find sht20 device on 'i2c88'
msh />
4.2.2 读取数据
探测成功之后,输入 sht20 read
即可获取温度与湿度,包括提示信息,日志如下:
msh />sht20 read
read sht20 sensor humidity : 54.7 %
read sht20 sensor temperature: 27.3
msh />
4.3 板卡级测试
4.3.1 准备测试环境
1)使用Ctrl+B组合键,编译项目代码,如下编译成功,可以看见如下log:
2)下载代码到板卡中
3)打开串口终端工具,如果代码能正常工作,可以看见如下log:
4.3.2 测试
1)查询I2C驱动接口信息,使用如下命令:
list device
2)检测SHT20在线状态
探测失败状态:
sht20 probe sci3i
探测成功状态:
sht20 probe sci3i
改变环境温度,观察传感器温湿度的变化情况: