RTT_IIC_读写AT24C02

1、根据board.h步骤配置IIC

1.1、打开RT-Thread Settings里的模拟IIC

去RT-Thread Settings里找到模拟iic,打开,然后保存,就配置好了;

1.2、打开"BSP_USING_I2Cx"宏定义

图中I2C1和I2C2都打开了,实际用的是I2C2;

1.3、根据实际的GPIO配置IIC的SCL和SDA引脚

根据硬件来连,PB8是SCL,PB9是SDA;

2、at24cxx软件包

2.1、安装软件包

打开RT-Thread Settings,搜索“at24cxx”,选择安装然后保存,就可以看到packages下面多了一个“at24cxx”的文件夹;

2.2、配置软件包

打开软件包的readme,可以看到注意事项如下,我打开at24cxx.h默认就是AT24C02,5ms

  • 请在at24cxx.h中修改EE_TYPE为自己使用的型号(默认为AT25C512) 。
  • 请在at24cxx.h中修改EE_TWR为自己使用EEPROM的Write Cycle Time,具体值请查看芯片datasheet(默认为5ms) 。
  • 从设备地址为7位地址 0x50, 而不是 0xA0 。

2.2.1、芯片型号 EE_TYPE

#ifndef EE_TYPE
#define EE_TYPE     AT24C02
#endif

2.2.2、写周期时间 EE_TWR

#define EE_TWR      5

 打开数据手册,就可以看到write cycle最大时间是5ms;

 2.2.3、器件的IIC地址

IIC通讯中,主机在发送起始信号之后,会发送一个字节的数据,前7位是从机的地址,最后一位是R/W读写标志;

24C02是2K,A0/A1/A2均为0,根据数据手册的图这个字节也就是,1 0 1 0 0 0 0 R/W

写:R/W=0,1 0 1 0 0 0 0 0,即0xA0;

读:R/W=1,1 0 1 0 0 0 0 1,即0xA1;

 再看rtt中关于发送地址的代码,分析完就很清楚了:

写:addr1 = msg->addr << 1;

已知addr1=0xA0,所以msg->addr = addr1 >> 1 = 0xA0 >> 1 = 0x50;

2.3、测试

配置完软件包后,编译、烧录,打开终端,输入at24cxx可查看命令;

3、查看AT24C02在IIC通信中的流程

修改下DBG_LVL才能看到下面输出的信息;

 at24cxx check

因为已经地址255写过一次了,所以修改为了0x58,这样在check的时候不会读一次数据就结束,而是有读数据,写数据,再读数据的过程。

根据log中的信息,可以看到AT24C02在IIC通信过程中具体的流程。

4、不用软件包,根据rtt模拟iic驱动写一下24C02读写字节的代码

4.1、头文件

#ifndef APPLICATIONS_AT24C02_IIC2_AT24C02_H_
#define APPLICATIONS_AT24C02_IIC2_AT24C02_H_

#include <rtthread.h>
#include "drv_soft_i2c.h"

#define AT24C02_I2C_BUS_NAME    "i2c2"      //挂载IIC2上,P89、PB9
#define AT24C02_I2C_ADDR        0x50        //AT24C02从机地址
#define AT24C02_SIZE            256         //AT24C02大小,共256字节
#define AT24C02_CHECK_VALUE     0x5a

//初始化AT24C02
rt_err_t at24c02_init();

#endif /* APPLICATIONS_AT24C02_IIC2_AT24C02_H_ */

4.2、源文件

#include "at24c02.h"

#define LOG_TAG               "AT24C02"
#define LOG_LVL               LOG_LVL_DBG
#include <ulog.h>

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

//读at24c02中addr地址的数据,并返回
static uint8_t at24c02_read_byte(uint8_t addr)
{
    struct rt_i2c_msg msg;
    uint8_t buffer[2];
    uint8_t data;

    msg.addr = AT24C02_I2C_ADDR;
    msg.flags = RT_I2C_WR;
    buffer[0] = addr;
    msg.buf = buffer;
    msg.len = 1;
    //发送要读数据的地址
    rt_i2c_transfer(i2c_bus, &msg, 1);

    msg.flags = RT_I2C_RD;
    msg.buf = &data;
    //读数据
    rt_i2c_transfer(i2c_bus, &msg, 1);

    return data;
}

//写at24c02中addr地址的数据
static rt_err_t at24c02_write_byte(uint8_t addr,uint8_t data)
{
    struct rt_i2c_msg msg;
    uint8_t buffer[2];
    buffer[0] = addr;
    buffer[1] = data;

    msg.addr = AT24C02_I2C_ADDR;
    msg.flags = RT_I2C_WR;
    msg.buf = buffer;
    msg.len = 2;
    //发送要写数据的地址、写的数据
    if(rt_i2c_transfer(i2c_bus, &msg, 1) != 1){
        return RT_ERROR;
    }
    return RT_EOK;
}


static rt_err_t at24c02_check(uint8_t check)
{
    uint8_t temp;
    temp = at24c02_read_byte(AT24C02_SIZE-1);
    if(temp != check){
        at24c02_write_byte(AT24C02_SIZE-1,check);
        rt_thread_mdelay(5);                        //wait 5ms
        temp = at24c02_read_byte(AT24C02_SIZE-1);
        if(temp != check){
            return RT_ERROR;
        }
    }

    return RT_EOK;
}

//初始化AT24C02
rt_err_t at24c02_init()
{
    //查找I2C总线设备,获取I2C总线设备句柄
    i2c_bus = (struct rt_i2c_bus_device *)rt_device_find(AT24C02_I2C_BUS_NAME);
    if (i2c_bus == RT_NULL){
        LOG_D("can't find device!\n");
        return RT_ERROR;
    }
    //检查AT24C02
    if(at24c02_check(AT24C02_CHECK_VALUE) != RT_EOK){
        LOG_D("at24c02 check fail!\n");
        return RT_ERROR;
    }
    LOG_D("at24c02 check ok!\n");
    return RT_EOK;
}

4.3、main.c

#include <rtthread.h>
#include <rtdevice.h>
#include <board.h>
#include "drv_common.h"
#include "at24c02.h"

#define LOG_TAG         "main"
#define LOG_LVL         LOG_LVL_DBG
#include <ulog.h>

int main(void)
{
    //设置LED为推挽输出
    rt_pin_mode(LED0_PIN, PIN_MODE_OUTPUT);

    LOG_I("init at24c02...");
    at24c02_init();

    while (1)
    {
        rt_pin_write(LED0_PIN, PIN_HIGH);       //设置高电平
        rt_thread_mdelay(500);
        rt_pin_write(LED0_PIN, PIN_LOW);        //设置低电平
        rt_thread_mdelay(500);
    }
    return RT_EOK;
}
  • 1
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值