I2C
介绍
对于不同底层驱动的I2C操作实现,统一封装成本文所述hal I2C接口。 hal相关头文件位于目录:[include/aos/hal] hal相关实现位于具体的mcu目录下,如:[platform/mcu/stm32f1xx/hal/]
API列表
函数名称 | 功能描述 |
---|---|
hal_i2c_init | 初始化指定I2C端口 |
hal_i2c_master_send | master模式下从指定的I2C端口发送数据 |
hal_i2c_master_recv | master模式下从指定的I2C端口接收数据 |
hal_i2c_slave_send | slave模式下从指定的I2C端口发送数据 |
hal_i2c_slave_recv | slave模式下从指定的I2C端口接收数据 |
hal_i2c_mem_write | mem模式下从指定的I2C端口发送数据 |
hal_i2c_mem_read | mem模式下从指定的I2C端口接收数据 |
hal_i2c_finalize | 关闭指定I2C端口 |
API详情
请参考[include/aos/hal/i2c.h]
相关宏定义
#define HAL_WAIT_FOREVER 0xFFFFFFFFU /* Define the wait forever timeout macro */
#define I2C_MODE_MASTER 1 /* i2c communication is master mode */
#define I2C_MODE_SLAVE 2 /* i2c communication is slave mode */
#define I2C_MEM_ADDR_SIZE_8BIT 1 /* i2c memory address size 8bit */
#define I2C_MEM_ADDR_SIZE_16BIT 2 /* i2c memory address size 16bit */
/*
* Specifies one of the standard I2C bus bit rates for I2C communication
*/
#define I2C_BUS_BIT_RATES_100K 100000
#define I2C_BUS_BIT_RATES_400K 400000
#define I2C_BUS_BIT_RATES_3400K 3400000
/* Addressing mode */
#define I2C_HAL_ADDRESS_WIDTH_7BIT 0 /* 7 bit mode */
#define I2C_HAL_ADDRESS_WIDTH_10BIT 1 /* 10 bit mode */
相关数据结构
i2c_dev_t
typedef struct {
uint8_t port; /* i2c port */
i2c_config_t config; /* i2c config */
void *priv; /* priv data */
} i2c_dev_t;
i2c_config_t
typedef struct {
uint32_t address_width;/* Addressing mode: 7 bit or 10 bit */
uint32_t freq; /* CLK freq */
uint8_t mode; /* master or slave mode */
uint16_t dev_addr; /* slave device addr */
} i2c_config_t;
hal_i2c_init
初始化指定I2C端口
函数原型
int32_t hal_i2c_init(i2c_dev_t *i2c)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
i2c_dev_t *i2c | 入参 | I2C设备描述,定义需要初始化的I2C参数 | 用户自定义一个i2c_dev_t结构体 |
返回值
返回成功或失败, 返回0表示I2C初始化成功,非0表示失败
调用示例
#define I2C1_PORT_NUM 1
#define I2C2_PORT_NUM 2
#define I2C2_SLAVE_ADDR 0x50
/* define dev master */
i2c_dev_t i2c_dev_master;
i2c_dev_t i2c_dev_slave;
/* i2c port set */
i2c_dev_master.port = I2C1_PORT_NUM;
/* i2c attr config */
i2c_dev_master.config.mode = I2C_MODE_MASTER;
i2c_dev_master.config.freq = I2C_BUS_BIT_RATES_3400K;
i2c_dev_master.config.address_width = I2C_HAL_ADDRESS_WIDTH_7BIT;
i2c_dev_slave.port = I2C2_PORT_NUM;
/* i2c attr config */
i2c_dev_slave.config.mode = I2C_MODE_SLAVE;
i2c_dev_slave.config.freq = I2C_BUS_BIT_RATES_3400K;
i2c_dev_slave.config.address_width = I2C_HAL_ADDRESS_WIDTH_7BIT;
i2c_dev_slave.config.dev_addr = I2C2_SLAVE_ADDR;
/* init master i2c with the given settings */
ret = hal_i2c_init(&i2c_dev_master);
/* init slave i2c with the given settings */
ret = hal_i2c_init(&i2c_dev_slave);
hal_i2c_master_send
master模式下从指定的I2C端口发送数据
函数原型
int32_t hal_i2c_master_send(i2c_dev_t *i2c, uint16_t dev_addr, const uint8_t *data, uint16_t size, uint32_t timeout)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
i2c_dev_t *i2c | 入参 | I2C设备描述 | 使用hal_i2c_init传入参数 |
uint16_t dev_addr | 入参 | 目标设备地址 | 0x50 |
const uint8_t *data | 入参 | 指向发送缓冲区的数据指针 | char pdata_send[10] |
uint16_t size | 入参 | 要发送的数据字节数 | 10 |
uint32_t timeout | 入参 | 超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER | 50 |
返回值
返回成功或失败, 返回0表示I2C数据发送成功,非0表示失败
调用示例
char pdata_send[10] = {0};
#define I2C2_SLAVE_ADDR 0x50
ret = hal_i2c_master_send(&i2c_dev_master,I2C2_SLAVE_ADDR,pdata_send,10,50);
hal_i2c_master_recv
master模式下从指定的I2C端口接收数据
函数原型
int32_t hal_i2c_master_recv(i2c_dev_t *i2c, uint16_t dev_addr, uint8_t *data,uint16_t size, uint32_t timeout)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
i2c_dev_t *i2c | 入参 | I2C设备描述 | 使用hal_i2c_init传入参数 |
uint16_t dev_addr | 入参 | 目标设备地址 | 0x50 |
uint8_t *data | 入参 | 指向接收缓冲区的数据指针 | char pdata_recv[10] |
uint16_t size | 入参 | 期望接收的数据字节数 | 10 |
uint32_t timeout | 入参 | 超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER | 50 |
返回值
返回成功或失败, 返回0表示成功接收size个数据,非0表示失败
调用示例
char pdata_recv[10] = {0};
#define I2C2_SLAVE_ADDR 0x50
ret = hal_i2c_master_recv(&i2c_dev_master,I2C2_SLAVE_ADDR,pdata_recv,10,50);
hal_i2c_slave_send
slave模式下从指定的I2C端口发送数据
函数原型
int32_t hal_i2c_slave_send(i2c_dev_t *i2c, const uint8_t *data, uint16_t size, uint32_t timeout)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
i2c_dev_t *i2c | 入参 | I2C设备描述 | 使用hal_i2c_init传入参数 |
const uint8_t *data | 入参 | 指向发送缓冲区的数据指针 | char pdata_send[10] |
uint16_t size | 入参 | 要发送的数据字节数 | 10 |
uint32_t timeout | 入参 | 超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER | 50 |
返回值
返回成功或失败, 返回0表示成功发送size个数据,非0表示失败
调用示例
char pdata_send[10] = {0};
ret = hal_i2c_slave_send(&i2c_dev_slave,pdata_send,10,50);
hal_i2c_slave_recv
slave模式下从指定的I2C端口接收数据
函数原型
int32_t hal_i2c_slave_recv(i2c_dev_t *i2c, uint8_t *data, uint16_t size, uint32_t timeout)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
i2c_dev_t *i2c | 入参 | I2C设备描述 | 使用hal_i2c_init传入参数 |
uint8_t *data | 入参 | 指向要接收数据的数据指针 | char pdata_recv[10] |
uint16_t size | 入参 | 要接收的数据字节数 | 10 |
uint32_t timeout | 入参 | 超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER | 50 |
返回值
返回成功或失败, 返回0表示成功接收size个数据,非0表示失败
调用示例
char pdata_recv[10] = {0};
ret = hal_i2c_slave_recv(&i2c_dev_slave,pdata_recv,10,50);
hal_i2c_mem_write
向指定的设备内存写数据
函数原型
int32_t hal_i2c_mem_write(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, uint16_t mem_addr_size, const uint8_t *data, uint16_t size, uint32_t timeout)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
i2c_dev_t *i2c | 入参 | I2C设备描述 | 使用hal_i2c_init传入参数 |
uint16_t dev_addr | 入参 | 目标设备地址 | 0x50 |
uint16_t mem_addr | 入参 | 内部内存地址 | 0x20 |
uint16_t mem_addr_size | 入参 | 内部内存地址大小 | 1 |
const uint8_t *data | 入参 | 指向要发送数据的数据指针 | char pdata[10] |
uint16_t size | 入参 | 要发送的数据字节数 | 1 |
uint32_t timeout | 入参 | 超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER | 50 |
返回值
返回成功或失败, 返回0表示成功发送size个数据,非0表示失败
调用示例
char pdata[10] = {0};
ret = hal_i2c_mem_write(&i2c_dev_master,0x50,0x20,1,pdata,1,50);
hal_i2c_mem_read
从指定的设备内存读数据
函数原型
int32_t hal_i2c_mem_read(i2c_dev_t *i2c, uint16_t dev_addr, uint16_t mem_addr, uint16_t mem_addr_size, uint8_t *data, uint16_t size, uint32_t timeout)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
i2c_dev_t *i2c | 入参 | I2C设备描述 | 使用hal_i2c_init传入参数 |
uint16_t dev_addr | 入参 | 目标设备地址 | 0x50 |
uint16_t mem_addr | 入参 | 内部内存地址 | 0x20 |
uint16_t mem_addr_size | 入参 | 内部内存地址大小 | 1 |
uint8_t *data | 入参 | 指向接收缓冲区的数据指针 | char pdata[10] |
uint16_t size | 入参 | 要接收的数据字节数 | 1 |
uint32_t timeout | 入参 | 超时时间(单位ms),如果希望一直等待设置为HAL_WAIT_FOREVER | 50 |
返回值
返回成功或失败, 返回0表示成功接收size个数据,非0表示失败
调用示例
char pdata[10] = {0};
ret = hal_i2c_mem_read(&i2c_dev_master,0x50,0x20,1,pdata,1,50);
hal_i2c_finalize
关闭指定I2C端口
函数原型
int32_t hal_i2c_finalize(i2c_dev_t *i2c)
参数
参数名称 | 出入参 | 参数描述 | 参数示例 |
---|---|---|---|
i2c_dev_t *i2c | 入参 | I2C设备描述 | 使用hal_i2c_init传入参数 |
返回值
类型:int 返回成功或失败, 返回0表示I2C关闭成功,非0表示失败。
调用示例
ret = hal_i2c_finalize(&i2c_dev_master);
使用
添加该组件
在相应的platform/mcu的mk内,添加对应hal文件的编译包含。
包含头文件
#include "aos/hal/i2c.h"
使用示例
#include <aos/hal/i2c.h>
#define I2C1_PORT_NUM 1
#define I2C_BUF_SIZE 10
#define I2C_TX_TIMEOUT 10
#define I2C_RX_TIMEOUT 10
#define I2C_DEV_ADDR 0x30f
#define I2C_DEV_ADDR_WIDTH 8
/* define dev */
i2c_dev_t i2c1;
/* data buffer */
char i2c_data_buf[I2C_BUF_SIZE];
int application_start(int argc, char *argv[])
{
int count = 0;
int32_t ret = -1;
int i = 0;
int rx_size = 0;
/* i2c port set */
i2c1.port = I2C1_PORT_NUM;
/* i2c attr config */
i2c1.config.mode = I2C_MODE_MASTER;
i2c1.config.freq = 30000000;
i2c1.config.address_width = I2C_DEV_ADDR_WIDTH;
i2c1.config.dev_addr = I2C_DEV_ADDR;
/* init i2c1 with the given settings */
ret = hal_i2c_init(&i2c1);
if (ret != 0) {
printf("i2c1 init error !\n");
}
/* init the tx buffer */
for (i = 0; i < I2C_BUF_SIZE; i++) {
i2c_data_buf[i] = i + 1;
}
/* send 0,1,2,3,4,5,6,7,8,9 by i2c1 */
ret = hal_i2c_master_send(&i2c1, I2C_DEV_ADDR, i2c_data_buf,
I2C_BUF_SIZE, I2C_TX_TIMEOUT);
if (ret == 0) {
printf("i2c1 data send succeed !\n");
}
ret = hal_i2c_master_recv(&i2c1, I2C_DEV_ADDR, i2c_data_buf,
I2C_BUF_SIZE, I2C_RX_TIMEOUT);
if (ret == 0) {
printf("i2c1 data received succeed !\n");
}
while(1) {
printf("AliOS Things is working !\n");
/* sleep 1000ms */
aos_msleep(1000);
};
}
注:port为逻辑端口号,其与物理端口号的对应关系见具体的对接实现
移植说明
新建hal_i2c_xxmcu.c和hal_i2c_xxmcu.h的文件,并将这两个文件放到platform/mcu/xxmcu/hal目录下。在hal_i2c_xxmcu.c中实现所需要的hal函数,hal_i2c_xxmcu.h中放置相关宏定义。<br /> 参考platform/mcu/stm32l4xx/src/STM32L496G-Discovery/hal/hal_i2c_stm32l4.c