硬汉嵌入式论坛

 找回密码
 立即注册
查看: 8510|回复: 3
收起左侧

[有问必答] STM32操作EEPROM疑问

[复制链接]

13

主题

20

回帖

59

积分

初级会员

积分
59
发表于 2014-8-20 11:21:20 | 显示全部楼层 |阅读模式
开发板上使用的是256Byte的EEPROM,如果使用512Byte或更大的呢?
看了开发板的例程

static uint8_t ee_ReadBytes(uint8_t *_pReadBuf, uint16_t _usAddress, uint16_t _usSize)
{
    uint16_t i;
   
    /* 采用串行EEPROM随即读取指令序列,连续读取若干字节 */
   
    /* 第1步:发起I2C总线启动信号 */
    g_i2c_gpio.start();
   
    /* 第2步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
    g_i2c_gpio.write_byte(EE_DEV_ADDR | I2C_WR);    /* 此处是写指令 */
   
    /* 第3步:发送ACK */
    if (g_i2c_gpio.wait_ack() != 0)
    {
        goto cmd_fail;    /* EEPROM器件无应答 */
    }

    /* 第4步:发送字节地址,24C02只有256字节,因此1个字节就够了,如果是24C04以上,那么此处需要连发多个地址 */
    g_i2c_gpio.write_byte((uint8_t)_usAddress);
   
    /* 第5步:发送ACK */
    if (g_i2c_gpio.wait_ack() != 0)
    {
        goto cmd_fail;    /* EEPROM器件无应答 */
    }
   
    /* 第6步:重新启动I2C总线。前面的代码的目的向EEPROM传送地址,下面开始读取数据 */
    g_i2c_gpio.start();
   
    /* 第7步:发起控制字节,高7bit是地址,bit0是读写控制位,0表示写,1表示读 */
    g_i2c_gpio.write_byte(EE_DEV_ADDR | I2C_RD);    /* 此处是读指令 */
   
    /* 第8步:发送ACK */
    if (g_i2c_gpio.wait_ack() != 0)
    {
        goto cmd_fail;    /* EEPROM器件无应答 */
    }   
   
    /* 第9步:循环读取数据 */
    for (i = 0; i < _usSize; i++)
    {
        _pReadBuf = g_i2c_gpio.read_byte();    /* 读1个字节 */
        
        /* 每读完1个字节后,需要发送Ack, 最后一个字节不需要Ack,发Nack */
        if (i != _usSize - 1)
        {
            g_i2c_gpio.ack();    /* 中间字节读完后,CPU产生ACK信号(驱动SDA = 0) */
        }
        else
        {
            g_i2c_gpio.nack();    /* 最后1个字节读完后,CPU产生NACK信号(驱动SDA = 1) */
        }
    }
    /* 发送I2C总线停止信号 */
    g_i2c_gpio.stop();
    return 1;    /* 执行成功 */

cmd_fail: /* 命令执行失败后,切记发送停止信号,避免影响I2C总线上其他设备 */
    /* 发送I2C总线停止信号 */
    g_i2c_gpio.stop();
    return 0;
}
现在有个疑问在第2步发起控制字节和第4步发送字节地址
2K以下EEPROM设备地址说明
2K.JPG

2K以下EEPROM写
2K_W.JPG

8-16K之间EEPROM设备地址说明
4K.JPG

8-16K之间EEPROM写
4K_W.JPG

16K以上EEPROM设备地址说明
32K.JPG

16K以上EEPROM写
32K_W.JPG

从上面手册数据可以知道

由于一个字节8bit最大表示2^8=256个存储空间,每个存储空间1Byte。共256*8=2048=2K。也就是说对EEPROM,以一个8字节发送地址最多访问2Kb(256KB)空间。

对于4Kb-16Kb的EEPROM,一个字节的地址不够用,此时采用分页访问。使用了命令字中的A2+A1+A0(2^3=8,即最多访问8*2Kb=16Kb。不一定全用,看EEPROM大小,对于

4Kb只用了A0,A0=1表示0x100-0x1FF空间,A0=0表示0x000-0x0FF空间)。
对于16Kb以上的EEPROM,则没有使用命令字中的A2+A1+A0,而是采用命令字节后发送16位地址方式(2个字节的地址)

所以上面的第2步发送的命令字节好像不是固定的,只有小于4Kb和大于16Kb的才是固定的0x1010+A2+A1+A0+W/R。对于4Kb-16Kb是0x1010+A2+A1+将访问的页+W/R(4Kb)
而第4步发送地址,只有16Kb以上的EEPROM才用发送两个地址字节。

以上说法对么?如果对,那就有个问题了,
对于4Kb-16Kb的EEPROM,当在写数据时,越过了一页要怎么办呢?就是说我从地址0xF0写100个字节,这时会超过一页(256字节)。
写0xF0-0XFF时发送的命令字节为0x1010+A2+A1+0+W
写0x100后面的发送命令字节为0x1010+A2+A1+1+W
回复

使用道具 举报

1万

主题

7万

回帖

11万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
117512
QQ
发表于 2014-8-20 11:25:15 | 显示全部楼层
帮顶,这个已经不记得了。
回复

使用道具 举报

1

主题

10

回帖

13

积分

新手上路

积分
13
发表于 2022-12-14 17:02:13 | 显示全部楼层
揪心,遇到一样的问题找到这发现没答案
回复

使用道具 举报

1

主题

9

回帖

12

积分

新手上路

积分
12
发表于 2024-10-23 10:55:43 | 显示全部楼层
本帖最后由 tajiong 于 2024-10-23 11:01 编辑

使用页写入操作,当数据超过一页的话,剩下数据应该会重新写入该页
比如:BL24C16F数据手册有描述
The data word address lower four bits are internally incremented following the receipt of each data word. The   higher data word address bits are not incremented, retaining the memory page row location. When the word   address, internally generated, reaches the page boundary, the following byte is placed at the beginning of the   same page. If more than sixteen data words are transmitted to the EEPROM, the data word address will "roll   over" and previous data will be overwritten.
在收到每个数据字后,数据字地址的低四位会在内部递增。数据字地址高位不递增,保留内存页面行位置。当内部生成的字地址到达页面边界时,下一个字节将被置于同一页面的起始位置。如果向 EEPROM 传输的数据字超过 16 个,数据字地址将 “滚动”,之前的数据将被覆盖。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|小黑屋|Archiver|手机版|硬汉嵌入式论坛

GMT+8, 2025-8-12 06:23 , Processed in 0.043880 second(s), 27 queries .

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2023, Tencent Cloud.

快速回复 返回顶部 返回列表