树莓派3B读写EEPROM芯片AT24C256

AT24C256是一个Atmel公司的EEPROM存储芯片,容量是256K个bit(也就是32K字节),I2C接口,而树莓派正好有I2C接口,如下图蓝框中的4个IO口,
在这里插入图片描述
把AT24C256和这4个口接在一起,这样硬件就准备好了。

本文讲述如何使用树莓派3B来读写AT24C256,其它树莓派版本也是类似的。有2种方法:

  1. 使用树莓派CPU的I2C控制器来读写
  2. 使用AT24C256在Linux系统中映射的文件来读写

读写AT24C256

1. 使能I2C接口

在树莓派系统终端下运行以下命令,

sudo raspi-config

然后弹出以下界面,按上下键来选择“3 Interface Options”并回车,
在这里插入图片描述
在新界面里选择“I4 I2C”并回车,
在这里插入图片描述
在新界面里按左右键来选择“Yes”
在这里插入图片描述
最后回到开始的界面,按左右键选择Finish并回车,
在这里插入图片描述
这样I2C功能就开启了。

2. 使用I2C控制器读写

这里使用i2c-tools来操作,树莓派默认已经安装了这个工具,如果没有就使用下面命令进行安装,

sudo apt install i2c-tools

i2c-tools提供了好几个工具:

  • i2cdetect
  • i2cdump
  • i2cget
  • i2cset
  • i2c-stub-from-dump
  • i2ctransfer

先使用i2cdetect来探测有多少I2C控制器,如下,显示有2个,
在这里插入图片描述
同时在/dev/下也能看到这2个I2C控制器,连接上AT24C256后则会使用i2c-1
在这里插入图片描述
i2cget,i2cset和i2ctransfer都是用来通过I2C控制器来读写eeprom,区别是:i2cget和i2cset适合那种地址是一个字节的eeprom芯片,如AT24C02这种,但是本文使用的是AT24C256,地址需要2个字节,所以只能使用i2ctransfer,同样它也能读一字节地址的eeprom,

i2ctransfer帮助信息如下,

在这里插入图片描述

写数据

使用下面命令进行写,"0x50"是芯片的I2C地址, "0x00 0x05"是eeprom内部的地址,该地址可以存放数据,

i2ctransfer 1 w6@0x50 0x00 0x05 0x55 0x66 0x77 0x88

PS:该命令意思是从eeprom的0x0005位置开始存放4个字节,0x55 0x66 0x77 0x88,不过对于i2ctransfer来说,它只是传输6个字节

显示如下,
在这里插入图片描述

PS:如果想写代码来操作,可以参考i2c-tools的源码

读数据

写完后再执行下面命令进行读,注意这里先要写2个字节,就是eeprom的内部地址0x0005,然后再读4个字节,

i2ctransfer 1 w2@0x50 0x00 0x05 r4

显示如下,可以看到读取出来的数据和写入的是一样的,
在这里插入图片描述

3. 使用EEPROM在Linux系统中映射的文件来读写(推荐)

这个也是推荐的方法,因为EEPROM映射成一个文件,这样可以使用常规的open, read和write来读写EEPROM,但是需要注意的是:这个办法和使用控制器的办法同时只能使用一个,因为映射之后控制器会被占用,就不能直接用控制器去读写了。

先执行下面的命令加载AT24的模块,这个模块是AT24系列芯片的驱动,

sudo modprobe at24

加载完毕后,在/sys/class/i2c-adapter/i2c-1/下会出现new_device和delete_device,
在这里插入图片描述
然后再运行sudo -i进入root模式,这点很重要,最后执行下面的命令,这样可以把芯片型号和I2C地址传给驱动,

echo "24c256 0x50" > /sys/class/i2c-adapter/i2c-1/new_device

实际操作如下,
在这里插入图片描述
最后执行exit回到用户模式。

此时在/sys/class/i2c-adapter/i2c-1/能看到新增的目录1-0050,"1"表示是i2c-1,"0050"表示设备的i2c地址是0x50,
在这里插入图片描述
cd进入1-0050目录,可以看到有个文件eeprom,这个就是AT24C256映射的文件,
在这里插入图片描述

PS:如果想取消映射,可以执行下面命令进行操作,

sudo -i
echo "0x50" > /sys/class/i2c-adapter/i2c-1/delete_device

使用代码进行读写

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdint.h>


int main() {
    int fd; // 文件描述符
    char buffer[256]; // 用于读写的缓冲区
    off_t offset;

    // 以读写模式打开文件
    fd = open("/sys/class/i2c-adapter/i2c-1/1-0050/eeprom", O_RDWR, 0644);
    if (fd == -1) {
        perror("无法打开文件");
        exit(EXIT_FAILURE);
    }

    // 向文件写入数据
    uint8_t wr_buf[4] = {0x11, 0x12, 0x55, 0x66};
    ssize_t bytes_written = write(fd, wr_buf, 4);
    if (bytes_written == -1) {
        perror("写入文件时出错");
        close(fd);
        exit(EXIT_FAILURE);
    }
    printf("成功写入 %ld 字节\n", bytes_written);

    // 使用lseek改变文件读写位置到文件开头
    offset = lseek(fd, 0, SEEK_SET);
    if (offset == -1) {
        perror("lseek失败");
        close(fd);
        exit(EXIT_FAILURE);
    }

    // 从文件读取数据到缓冲区
    ssize_t bytes_read = read(fd, buffer, 4);
    if (bytes_read == -1) {
        perror("读取文件时出错");
    } else {
        for (uint32_t i = 0; i < 4; ++i)
        {
            printf("==> 0x%x\n", buffer[i]);
        }
    }

    // 关闭文件
    if (close(fd) == -1) {
        perror("关闭文件时出错");
        exit(EXIT_FAILURE);
    }

    return 0;
}

代码以0x0000位置为起始地址,写入"0x11 0x12 0x55 0x66",编译后运行程序并运行,
在这里插入图片描述
可以看到读写都没问题,同时也能发现映射后对eeprom的操作和读写一个普通文件没有区别。

PS:如果想修改起始地址,可以使用lseek函数来设置位置。


总结

本文讲述了2种方法来读写AT24C256,更推荐文件方式的办法,这种更符合Linux“万物皆文件”的思想。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值