工程创建
我使用的开发板是正点原子的STM32F1精英板,所以在建立工程的时候配置如下(我使用的是盗版的精英版,所以在选择调试工具的时候要选择SWO模式,因为板子没连JTAG的模式的线):
加载驱动
加载模拟I2C驱动
因为我们要测试的是一个IIC设备,这里我们就使用STM32板载的AT24C02芯片来当作待测芯片。因为STM32硬件IIC在设计之初就存在一定的缺陷,所以一般我们都是采用软件模拟IIC,这里需要先加载RTThread包支持的soft IIC驱动。方法如下:
双击项目资源管理器中的“RT-thread Setting”标题,如图所示:
在右端的软件中心中单击“软件模拟I2C”图标即可添加IIC驱动。
然后选定“软件模拟I2C”右键“详细配置”选项,在右侧弹出的选项框中选择“组件”选项框并将“使用I2C设备驱动程序”选项栏和其子选选项栏“使用GPIO模拟I2C”选项栏打钩,如图所示:
下载驱动代码:
上节中只是打开了软件 I2C 的驱动框架,具体芯片的软件 I2C 驱动源码还需要自己手动添加到工程驱动文件所在的路径,所以需要下载 STM32 系列的软件 I2C 驱动。下载地址。
下载完成之后将“drv_soft_i2c.c
” 和“ drv_soft_i2c.h
”这两个文件放置在工程下的“drivers”目录下即可。
加载AT24CXX驱动
单击软件包中心的“立即添加”按钮,会弹出在线的RTThread软件包中心(如图下所示)。其中包含了RTThread官方支持的诸多的组件,下载后加载即可用于自己的程序中。
因为我们要使用的24C02隶属于AT24CXX系列属于外设部分,单击“外设”图标并且在搜索栏查找AT24CXX,找到后点击添加即可,如图所示:
添加完成之后IDE并不会立即就下载驱动代码,需要关闭或者“Ctrl+S”保存一次“RT-Thread settings”这个界面IDE才会下载并且将代码载入到工程。代码成功载入工程后会分别在drivers目录下生成“drv_soft_i2c.h”、“drv_soft_i2c.c”和packages目录下生成一个“AT24cxx-latest”文件夹,如下图所示:
这样整个代码环境就搭建完成了。
代码编写
在编写代码的时候需要注意两点:
- I2C的设备地址都是7位,所以精英板的设备地址应该设置为0x50而不是0xA0。
- 在使用AT24cxx驱动之前需要在“at24cxx.h”中设置EEPROM的型号,如下所示:
代码:
/*
* Copyright (c) 2006-2019, RT-Thread Development Team
*
* SPDX-License-Identifier: Apache-2.0
*
* Change Logs:
* Date Author Notes
* 2019-09-09 RT-Thread first version
*/
#include <rtthread.h>
#include <board.h>
#include <rtdevice.h>
#define DBG_TAG "main"
#define DBG_LVL DBG_LOG
#include <rtdbg.h>
#include "drv_soft_i2c.h"
#include "at24cxx.h"
const char *i2c_bus_name = "i2c1";
struct at24cxx_device *i2c_bus = RT_NULL;
/*
* @discription:AT24Cxx设备的初始化
* @param:无
* @return:无
*/
void eeprom_init()
{
/*初始化IIC设备*/
int iRet = RT_NULL;
iRet = rt_hw_i2c_init(i2c_bus_name,GET_PIN(B,6),GET_PIN(B,7));
if(iRet == RT_EOK)
{
rt_kprintf("i2c设备初始化成功\r\n");
}
else
{
rt_kprintf("i2c设备初始化失败\r\n");
return RT_ERROR;
}
i2c_bus = at24cxx_init(i2c_bus_name, 0x50);
rt_kprintf("i2c_address:%x\r\n",i2c_bus->AddrInput);
if (i2c_bus != RT_NULL)
{
rt_kprintf("成功读取设备\r\n");
}
else
{
rt_kprintf("获取设备失败\r\n");
return RT_ERROR;
}
}
/*
* @discription:GPIO的初始化
* @param:无
* @return:无
*/
void gpio_init()
{
/* set LED0 pin mode to output */
rt_pin_mode(GET_PIN(B, 5), PIN_MODE_OUTPUT);
}
/*
* @discription:主函数
* @param:无
* @return:无
*/
int main(void)
{
static unsigned int flag = 0;
gpio_init();
eeprom_init();
while (1)
{
flag = ~flag;
rt_pin_write(GET_PIN(B,5), flag&0x01);
rt_thread_mdelay(1000);
}
return RT_EOK;
}