RT-Rhread这里用的是软件模拟i2c,stm32的驱动里并没有找到硬件i2c的驱动,但是在GD32里面却有硬件i2c的驱动,有兴趣的小伙伴可以根据gd32的代码写一份stm32硬件I2c的驱动。
rtconfig.h里添加i2c的配置
Makefile里添加i2c的编译
这样修改后,输入list_device,会列出i2c1设备。
在PB6 PB7 上挂了一颗at24c02,我们用msh cmd写几个数据进去,然后读出来。
应用层最重要的是发送函数的封装,如果在kernel下搞过i2c的设备驱动,rt_i2c_transfer函数这个形式并不陌生。我这里封装了读函数,写函数,多寄存器,多数据的读写方式。
#include
#include
#include
#define I2C_BUS_NAME "i2c1" /* EEPROM连接的I2C总线设备名称 */
#define I2C_TEST_ADDR 0x50 /* 从机地址 */
#define I2C_MAX_DATA_LENGTH 128
static struct rt_i2c_bus_device *i2c_bus = RT_NULL; /* I2C总线设备句柄 */
/* I2C 写寄存器 */
static rt_err_t write_reg(struct rt_i2c_bus_device *bus, rt_uint16_t reg_len,rt_uint8_t *reg,
rt_uint16_t len, rt_uint8_t *data)
{
rt_uint8_t buf[I2C_MAX_DATA_LENGTH] = {0};
rt_uint8_t *p = buf;
struct rt_i2c_msg msgs;
memcpy(p,reg,reg_len);
p += reg_len;
memcpy(p,data,len);
msgs.addr = I2C_TEST_ADDR;
msgs.flags = RT_I2C_WR;
msgs.buf = buf;
msgs.len = reg_len + len;
/* 调用I2C设备接口传输数据 */
if (rt_i2c_transfer(bus, &msgs, 1) == 1)
{
return RT_EOK;
}
else
{
return -RT_ERROR;
}
}
/* 读I2C寄存器数据 */
static rt_err_t read_regs(struct rt_i2c_bus_device *bus, rt_uint16_t reg_len,
rt_uint8_t *reg, rt_uint16_t len, rt_uint8_t *buf)
{
struct rt_i2c_msg msgs[2];
msgs[0].addr = I2C_TEST_ADDR;
msgs[0].flags = RT_I2C_WR;
msgs[0].buf = reg;
msgs[0].len = reg_len;
msgs[1].addr = I2C_TEST_ADDR;
msgs[1].flags = RT_I2C_RD;
msgs[1].buf = buf;
msgs[1].len = len;
/* 调用I2C设备接口传输数据 */
if (rt_i2c_transfer(bus, msgs, 2) == 1)
{
return RT_EOK;
}
else
{
return -RT_ERROR;
}
}
static void i2c_sample(int argc, char *argv[])
{
rt_uint8_t reg = 0x00;
rt_uint8_t r_value[5] = {0};
rt_uint8_t w_value[5] = {0x98,0x97,0x99,0xA0,0x45};
char name[RT_NAME_MAX];
if (argc == 2)
{
rt_strncpy(name, argv[1], RT_NAME_MAX);
}
else
{
rt_strncpy(name, I2C_BUS_NAME, RT_NAME_MAX);
}
/* 查找I2C总线设备,获取I2C总线设备句柄 */
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);
}
write_reg(i2c_bus,1,®,5,w_value);
rt_thread_delay(10);
read_regs(i2c_bus,1,®,5,r_value);
for(int i=0;i<5;i++)
{
rt_kprintf("get data[%d] == 0x%02x\n",i,r_value[i]);
}
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(i2c_sample, i2c test sample);