总线学习6--I2C(EEPROM)

鉴于I2C的项目还是很多,所以又多做了一个试验,这次是包含读写的。

之前的两篇:

总线学习1--I2C-CSDN博客

总线学习2--使用GPIO模拟I2C_gpio模拟iic,如何实现对数据的解析-CSDN博客

1 环境说明

主控还是树莓派Pico。eeprom用的是之前买的AT24C02。 软件环境还是老朋友micropython。

接线是这样接的。

24C02 PinPico Pin
VCC3.3V
GNDGND
SDAGP16
SCLGP17

AT24C02数据手册:

AT24C02 datasheet(1/24 Pages) ATMEL | 2-Wire Serial EEPROM

2 代码

代码如下:

from machine import Pin, I2C
import time

# 初始化I2C接口 (GP0 - SDA, GP1 - SCL)
i2c = I2C(0, scl=Pin(17), sda=Pin(16), freq=400000)

# EEPROM的I2C地址,一般为0x50
EEPROM_I2C_ADDRESS = 0x50

def eeprom_write(address, data):
    """
    向EEPROM的指定地址写入数据。
    :param address: EEPROM地址
    :param data: 要写入的字节数据(一个字节)
    """
    if not 0 <= address <= 255:
        raise ValueError("地址超出范围")

    # 发送地址和数据
    i2c.writeto(EEPROM_I2C_ADDRESS, bytearray([address, data]))
    # 等待写入完成
    time.sleep(0.01)

# 示例:将数据0xAB写入地址0x10
eeprom_write(0x10, 0xAB)

def eeprom_read(address):
    """
    从EEPROM的指定地址读取数据。
    :param address: EEPROM地址
    :return: 读取到的数据字节
    """
    if not 0 <= address <= 255:
        raise ValueError("地址超出范围")

    # 发送要读取的地址
    i2c.writeto(EEPROM_I2C_ADDRESS, bytearray([address]))
    
    # 读取一个字节的数据
    data = i2c.readfrom(EEPROM_I2C_ADDRESS, 1)
    
    return data[0]

# 示例:从地址0x10读取数据
read_data = eeprom_read(0x10)
print("读取到的数据: ", hex(read_data))

注释写的很好,这里就不多解释了。。

3 波形分析

抓波形还是用的之前的设备:逻辑分析仪小试-CSDN博客

抓到的波形和命令的对照。

1 eeprom_write(0x10, 0xAB)

根据接口i2c.writeto(EEPROM_I2C_ADDRESS, bytearray([address, data])),这里实际上写入了三个东西,第一个是设备地址,第二个是0x10,第三个是0xAB。

可以看到。

开始和结束略过。。。

第一段就是1010 0000,第一段比较特殊,地址是7位,所以是101 0000,就是0x50,也就是24C02的设备地址,这个一般是厂商就设置好的。然后是读写位,1是读0是写,这里就是写。最后面跟了一个拉高的ACK。

第二段是0001 0000。这里就是0x10,表明写在地址0x10。

第三段是1010 1011。就是AB,表示将AB写进去。

稍微特别的是好像第二个byte之后,不管是时钟还是数据线,都有点紊乱。虽然不影响结果,还是有点怪。。。

2 read_data = eeprom_read(0x10)

根据代码,这里实际上是两段,    i2c.writeto(EEPROM_I2C_ADDRESS, bytearray([address]))
data = i2c.readfrom(EEPROM_I2C_ADDRESS, 1)。

第一个操作写入了设备地址和读写地址。第二个操作读了设备地址,1是参数,表示只读1个byte。

 读的操作要麻烦一些,有4个byte。首先写入地址,再去读。可以看到,这里读写区分很严格,读就是读,写就是写。

首先还是地址,1010 0000。和上面一模一样,不多解释了。

第二个就是写地址,0001 0000,和上面也是一样。

然后是读取的命令,1010 0001,地址还是0x50,但是读写位变成了1,也就是要读了。

最后是eeprom返回的数据,1010 1011,就是0xAB。

这里如果readfrom要读多个地址怎么搞呢?也就是参数不为1。从波形上看好像直接无法支持,我理解是如果是2,那么后面会自动跟着多发一个1010 0011,多去读取0x51的地址数据。当然,这个只是猜测,没有做实验去验证了。

4 小结

看看AT24C02这个芯片。

还是来自于美的的Atmel,24C02可以提供2Kb(256字节)的存储容量。存储器按字节进行组织,每个字节可以独立读写。每次写入操作的时间通常在5ms到10ms之间。

试了一下随机读取,原始的数据都是0xFF。

2K就是256*8。也就是说地址范围是0到FF。按照一个汉字两个字节,这个芯片也就是能存1000字的文章,差不多一篇高考作文。。。确实只能存储一些参数和配置的信息

不过用来存储一些个人秘密信息还是很nice。你自己的一些绝密信息存进去,我敢说99.99%的人是没法读出来的。。。

5 对比flash

最后看看eeprom和flash的区别:

存储单元操作按字节(Byte)擦除和写入按块(Block)擦除,按字节/页写入
擦除方式单字节擦除整块擦除
写入方式单字节写入通常按页写入(如256字节)
读写速度写入速度较慢,通常5ms到10ms/字节写入速度较快,通常几十微秒到几毫秒/页
擦除速度无需整体擦除,擦除时间按字节计算擦除速度较慢,通常几毫秒到几百毫秒/块
使用寿命100,000到1,000,000次擦写100,000次擦写
存储容量通常较小(几Kb到几Mb)通常较大(几Mb到几Gb)
功耗较低较高
应用场景配置数据、小数据块存储、频繁更新的数据大容量数据存储,如固态硬盘、嵌入式存储等
数据保持时间通常为10年以上通常为10年以上
工作电压1.8V到5.5V2.7V到3.6V 或 1.8V到3.6V
擦除单位单字节单块(如4KB, 64KB, 128KB等)

flash的速度快,一般起码就得用SPI了。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值