STM32移植RT-thread实现IIC与AT24C02的通信功能(含软件包和软件模拟IIC两种方法)

最近将纯裸机的老项目进行了RT-Thread实时操作系统的移植,在这里记录一些在移植过程中感觉比较重要的一些内容

一、不使用软件包的方法

1.配置RT-Thread settings中的驱动

在这里插入图片描述

2.进行HAL库的配置

一般情况下需要配置好RCC\SYS\USART以及IIC,一般用到这些功能,前面这些配置已经烂熟于胸。
在这里插入图片描述

3.board.h里面开启IIC的配置

在这里插入图片描述

4.打开stm32f1xx_hal_conf_bak.h里面IIC的宏定义

不知道为什么,这个宏定义没打开,功能也能实现,但是根据配置要求还是打开吧!
在这里插入图片描述

5.代码的实现
#include <rtthread.h>
#include <rtdevice.h>
#include "drv_common.h"

#define EEP_I2C_BUS_NAME          "i2c1"  //连接I2C总线设备名称
#define EEP_ADDR                  0x50    //从机地址

struct rt_i2c_bus_device *i2c_bus = RT_NULL;     //I2C总线设备句柄

//写传EEPROM寄存器
static rt_err_t epp_wr(struct rt_i2c_bus_device *bus, rt_uint8_t *data, rt_uint8_t add)
{

    struct rt_i2c_msg msgs;

    msgs.addr = EEP_ADDR;
    msgs.flags = RT_I2C_WR;
    msgs.buf = data;
    msgs.len = add;

    /* 调用I2C设备接口传输数据 */
    if (rt_i2c_transfer(bus, &msgs, 1) == 1)
    {
        rt_kprintf("write ok!\n");
        return RT_EOK;
    }
    else
    {
        return -RT_ERROR;
    }
}

/* 读传EEPROM寄存器数据 */
static rt_err_t epp_rd(struct rt_i2c_bus_device *bus, rt_uint8_t *data, rt_uint8_t add)
{
    struct rt_i2c_msg msgs;


    msgs.addr = EEP_ADDR;
    msgs.flags = RT_I2C_RD;
    msgs.buf = data;
    msgs.len = add;

    /* 调用I2C设备接口传输数据 */
    if (rt_i2c_transfer(bus, &msgs, 1) == 1)
    {

        //msgs.buf[1] += 1;
        rt_kprintf("read ok!\n");
        return RT_EOK;
    }
    else
    {
        return -RT_ERROR;
    }
}



int main(void)
{
    rt_err_t ret = RT_NULL;
    //设备地址相当于右移了一位
    rt_uint8_t buf_wr[3] = {0x51, 0,21};

    i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(EEP_I2C_BUS_NAME);     //查找设备
    if(i2c_bus == RT_NULL)
    {
        rt_kprintf("can't find %s", EEP_I2C_BUS_NAME);
    }

    epp_wr(i2c_bus, buf_wr, 3);     //从设备地址+写指令 地址  数据
    rt_thread_mdelay(400);

    rt_uint8_t buf_rd[2] = {0x51, 0};
    epp_wr(i2c_bus, buf_rd, 2);     //读数据
    epp_rd(i2c_bus, buf_rd, 1);
    if (ret == RT_EOK)
    {
            rt_kprintf("today is %d.%d\n", buf_rd[0], buf_rd[1]);
    }

}

这一块写和读都用了0x51,按道理应该是一个0x50,一个0x51,具体应该和底层代码有关,没有进行深究。

二、使用软件包的方法

使用软件包的配置步骤和上面是一致的,但是要在RT-thread Setting的配置中,增加一个软件包

1.软件包的添加

在这里插入图片描述

2.一些编码配置的处理

这里的宏定义要改成自己使用的器件型号
在这里插入图片描述

3.代码
/*
 * Copyright (c) 2006-2020, RT-Thread Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 说明:本eeprom 读写测试代码基于 at24cxx 软件包
 * 使用步骤:
 * 1:在 RT-Thread Settings 中开启  【软件模拟I2C】
 * 2:在 RT-Thread Settings 软件包中搜索 at24cxx 添加软件包,并保存。
 * 3:drivers-> board.h 中打开I2C接口的定义  搜索 I2C CONFIG BEGIN,按介绍定义。
 * 4:packages 目录中可以找到添加的软件包,at24cxx.h 中定义 eeprom的型号 ,如 #define EE_TYPE     AT24C64
 *
 * 软件包提示: 注意事项
 * 请在at24cxx.h中修改EE_TYPE为自己使用的型号(默认为AT25C512) 。
 * 请在at24cxx.h中修改EE_TWR为自己使用EEPROM的Write Cycle Time,具体值请查看芯片datasheet(默认为5ms) 。
 * 从设备地址为7位地址 0x50, 而不是 0xA0 。
 */
#include <rtthread.h>
#include <rtdevice.h>
#include "at24cxx.h"

#define EEPROM_I2C  "i2c1"   /* eeprom 所挂载的i2c总线 */
#define EEP_ADDR     0       /* 从设备芯片地址,IC的A2,A1,A0设置的值 */
#define CF_START_ADD 0       /* eeprom 校准系数的首地址 */

static at24cxx_device_t eeprom_dev;  /*    at24cxx 设备对象 */

int main(void)
{
    eeprom_dev = at24cxx_init(EEPROM_I2C,EEP_ADDR);
    if(eeprom_dev == RT_NULL)
    {
        rt_kprintf(">eeprom 注册失败... \n");
    }

    /* 数据读写测试 */
    uint8_t eeprom_RBuffer=0;
    uint8_t eeprom_WBuffer=11;

    at24cxx_write(eeprom_dev,0,&eeprom_WBuffer,1); /*向eeprom 中写入数据*/
    rt_kprintf("Weeprom:%d\n",eeprom_WBuffer);
    rt_thread_mdelay(100);

    at24cxx_read(eeprom_dev,0,&eeprom_RBuffer,1);  /*从eeprom 中读数据*/
    rt_kprintf("Reeprom:%d\n",eeprom_RBuffer);

    while(1)
    {
        rt_thread_mdelay(100);
    }

}

最后

移植中每一步配置都不可缺少,器件通信的逻辑可能和裸机编程思想存在偏差,但是当做规则去应用就好了,可以同时参考对AT24c02的通信以及官方例程中对温湿度传感器的通信,二者对比使用,就搞明白移植的方法。

### RT-Thread I2C 接口配置方法 #### 使用 RT-Thread Studio 创建项目并配置 I2C 设备 在 RT-Thread Studio 上可以方便地创建支持 I2C 的工程项目。通过图形化界面选择所需的组件服务,简化了开发流程[^1]。 对于 STM32 平台而言,在初始化阶段需注意区分软件模拟硬件实现之间的差异,并依据具体需求调整相应的设置选项[^4]。 #### 初始化 I2C 总线设备 为了使能 I2C 功能模块,应在 `rtconfig.h` 文件里定义宏 `RT_USING_I2C` 来开启此特性。接着按照官方文档指导完成必要的参数设定工作,比如指定 SDA SCL 引脚编号以及波特率等重要属性[^3]。 ```c #define RT_USING_I2C 1 ``` #### 编写驱动程序代码样例 下面给出一段简单的 C 语言源码片段用于展示如何利用 RT-Thread API 对 EEPROM 进行数据存取操作: ```c #include <rtthread.h> #include <rtdevice.h> #include <drv_cfg.h> static struct rt_i2c_bus_device *i2c_bus; int main(void) { /* 获取 i2c bus device */ i2c_bus = (struct rt_i2c_bus_device *)rt_device_find("i2c1"); if (!i2c_bus) { rt_kprintf("find i2c1 failed\n"); return -1; } // 更多的操作... return 0; } ``` 上述实例展示了获取已注册到系统的 I2C 总线对象的方法;后续可根据实际应用场景继续扩展功能逻辑,例如向特定地址发送命令字节序列或将接收到的数据保存至内存缓冲区中等待进一步处理[^5]。 #### 调试技巧分享 当遇到难以解决的技术难题时,建议仔细阅读错误提示信息并社区成员交流探讨解决方案。此外,还可以借助专业的仿真器调试工具来辅助定位问题所在位置,提高工作效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值