1、先分析野火霸道开发板的BSP是怎么做的,特别是board文件夹下面的Kconfig文件,比较menuconfig菜单下的效果和Kconfig文件。
1.1 先看看主菜单,看名字大概知道硬件的驱动应该都在这个主菜单进行配置。
1.2 再看看里面的子菜单,第一个是板载驱动,我们简单分析下这个菜单是怎么通过Kconfig实现的。
1.3 再看看子菜单下面的MCU外设驱动,也进行简单的分析。
2、分析完别人的BSP以后,我们就来实现自己的BSP,其实都不叫实现,因为软件IIC是RTT写好了的,我们只需要将Kconfig文件改一改就能用了。本质是将IIC的宏给打开。
2.1 先进入自己的BSP目录,然后打开board文件夹下面的Kconfig文件,进行修改。
2.2 回到BSP主目录,打开env工具,选择打开IIC,并配置好两个IIC引脚。
2.3 我们保存、退出,重新生成工程、编译、下载、然后list_device就可以看到IIC设备了。
3、既然驱动有了,我们就根据RTT官方的文档例程来看看能否进行IIC通讯吧。手上的板子接线如下。
3.1 参考官方的文档和例子,进行测试吧。
点我查看官方AT24Cxx例子
特别需要注意的就是,RTT设备的地址是不包含读写标志位的,也就是说发送的设备地址不是0xA0,而是右移一位以后的0x50,这个位置坑了我半小时,要是官网的文档那个注意事项写得更加引人注意就好了。
/* ------------------------------------ IIC测试 ------------------------------------------------- */
/* 24xx02的设备地址 */
#define EEPROM_DEV_ADDR 0x50 //注意不是0xA0
//这里有点坑啊,因为读写标志是独立出来的,因此这个设备地址是不包含读写标志的,也就是0x50才是对的
//官方的IIC驱动文档有写这个注意事项,但是一不留意还是会出错,找好久才发现是这里的原因
static struct rt_i2c_bus_device *i2c_bus = RT_NULL; /* I2C总线设备句柄 */
/* 写一个字节 */
static rt_err_t write_byte(struct rt_i2c_bus_device *bus, rt_uint8_t addr, rt_uint8_t data)
{
rt_uint8_t buf[2];
struct rt_i2c_msg msgs;
buf[0] = addr;
buf[1] = data;
msgs.addr = EEPROM_DEV_ADDR;
msgs.flags = RT_I2C_WR;
msgs.buf = buf;
msgs.len = 2;
/* 调用I2C设备接口传输数据 */
if (rt_i2c_transfer(bus, &msgs, 1) == 1)
{
rt_kprintf("write success\n");
return RT_EOK;
}
else
{
rt_kprintf("write fail\n");
return -RT_ERROR;
}
}
/* 读一个字节 */
static rt_uint8_t read_byte(struct rt_i2c_bus_device *bus, rt_uint8_t read_addr)
{
struct rt_i2c_msg msgs[2];
rt_uint8_t read_data;
msgs[0].addr = EEPROM_DEV_ADDR;
msgs[0].flags = RT_I2C_WR;
msgs[0].buf = &read_addr;/* 设置要读的地址 */
msgs[0].len = 1;
msgs[1].addr = EEPROM_DEV_ADDR;
msgs[1].flags = RT_I2C_RD;
msgs[1].buf = &read_data;
msgs[1].len = 1;
/* 调用I2C设备接口传输数据 */
if( rt_i2c_transfer(bus, msgs, 2) != 1 )
{
rt_kprintf("read success\n");
rt_kprintf("read byte = %d\n", read_data);
return RT_EOK;
}
else
{
rt_kprintf("read fail\n");
return -RT_ERROR;
}
}
/* IIC EEPROM简单测试 */
static void i2c_eeprom_sample(void)
{
/* 查找I2C总线设备,获取I2C总线设备句柄 */
i2c_bus = (struct rt_i2c_bus_device *)rt_device_find("i2c1");
if (i2c_bus == RT_NULL)
{
rt_kprintf("can't find %s device!\n", "i2c1");
}
else
{
write_byte(i2c_bus, 0x00, 15);
rt_thread_mdelay(20);/* 注意写完以后不能直接读,需要延时一小会,否则会出错 */
read_byte(i2c_bus, 0x00);
}
}
/* 导出到 msh 命令列表中 */
MSH_CMD_EXPORT(i2c_eeprom_sample, i2c eeprom sample);
3.2 最后在调试终端进行测试。
4 那么问题来了,如果我又有一个IIC设备呢?怎么办?或者说,我希望IIC设备的名称不是i2c1呢?应该怎么处理?
4.1 首先我们可以看下面这个文件
分析归分析,我们先试试改动一下名字,验证下我们的分析是否是正确的。下图测试以后,验证我们的分析是OK的。
那么接下来,我们就把IIC2给打开吧。首先还是需要修改board文件夹下面的Kconfig文件。依葫芦画瓢,将IIC1改为IIC2即可。
然后我们menuconfig,将IIC2也打开。
保存退出,重新构建工程,编译。
我们再次打开drv_soft_i2c.h文件,可以看到IIC2被打开了。
将程序下载到板子上,list_device以后,果然IIC2设备已经出来了。