NUCLEO-F411RE RT-Thread 体验 (6) - GCC环境 I2C驱动移植以及简单使用

NUCLEO-F411RE RT-Thread 体验 (6) - GCC环境 I2C驱动移植以及简单使用

1、I2C驱动移植

RT-Rhread这里用的是软件模拟i2c,stm32的驱动里并没有找到硬件i2c的驱动,但是在GD32里面却有硬件i2c的驱动,有兴趣的小伙伴可以根据gd32的代码写一份stm32硬件I2c的驱动。
rtconfig.h里添加i2c的配置
NUCLEO-F411RE RT-Thread 体验 (6) - GCC环境 I2C驱动移植以及简单使用_第1张图片
Makefile里添加i2c的编译
NUCLEO-F411RE RT-Thread 体验 (6) - GCC环境 I2C驱动移植以及简单使用_第2张图片
这样修改后,输入list_device,会列出i2c1设备。
NUCLEO-F411RE RT-Thread 体验 (6) - GCC环境 I2C驱动移植以及简单使用_第3张图片

2、应用层的使用

在PB6 PB7 上挂了一颗at24c02,我们用msh cmd写几个数据进去,然后读出来。
NUCLEO-F411RE RT-Thread 体验 (6) - GCC环境 I2C驱动移植以及简单使用_第4张图片
NUCLEO-F411RE RT-Thread 体验 (6) - GCC环境 I2C驱动移植以及简单使用_第5张图片

应用层最重要的是发送函数的封装,如果在kernel下搞过i2c的设备驱动,rt_i2c_transfer函数这个形式并不陌生。我这里封装了读函数,写函数,多寄存器,多数据的读写方式。
NUCLEO-F411RE RT-Thread 体验 (6) - GCC环境 I2C驱动移植以及简单使用_第6张图片
NUCLEO-F411RE RT-Thread 体验 (6) - GCC环境 I2C驱动移植以及简单使用_第7张图片

3 、完整测试代码

#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);

你可能感兴趣的:(RT-Thread,单片机,stm32,嵌入式硬件)