[学习资料] 基于STM32的AT21CS01 EEPROM驱动代码

[复制链接]
1369|38
 楼主| 过期的塔头 发表于 2022-11-30 19:48 | 显示全部楼层
ROM区域寄存器写

        ROM 区域寄存器只能写入逻辑 1,该操作会将相应的存储区域设置为 ROM 状态。一旦写入 ROM 区域寄存器,便无法再次更改。
 楼主| 过期的塔头 发表于 2022-11-30 19:49 | 显示全部楼层
代码:
  1. u8 RomZoneRegWrite(u8 addr)
  2. {
  3.     Ack_t ack = ACK;

  4.     if(addr != 1 && addr != 2 && addr != 4 && addr != 8)
  5.     {
  6.         return 0xEE;        //ERROR
  7.     }
  8.     DELAY_HTSS();
  9.     ack &= AT21CS01_SendByte(ROM_ZONE_REG_ACCESS | WRITE);
  10.     ack &= AT21CS01_SendByte(addr);
  11.     ack &= AT21CS01_SendByte(0xFF);
  12.     DELAY_HTSS();
  13.     delay_ms(5);        //t_WR
  14.     return (u8)ack;
  15. }
 楼主| 过期的塔头 发表于 2022-11-30 19:50 | 显示全部楼层
ROM区域寄存器写

        ROM 区域寄存器只能写入逻辑 1,该操作会将相应的存储区域设置为 ROM 状态。一旦写入 ROM 区域寄存器,便无法再次更改。
 楼主| 过期的塔头 发表于 2022-11-30 19:50 | 显示全部楼层
代码:
  1. u8 RomZoneRegWrite(u8 addr)
  2. {
  3.     Ack_t ack = ACK;

  4.     if(addr != 1 && addr != 2 && addr != 4 && addr != 8)
  5.     {
  6.         return 0xEE;        //ERROR
  7.     }
  8.     DELAY_HTSS();
  9.     ack &= AT21CS01_SendByte(ROM_ZONE_REG_ACCESS | WRITE);
  10.     ack &= AT21CS01_SendByte(addr);
  11.     ack &= AT21CS01_SendByte(0xFF);
  12.     DELAY_HTSS();
  13.     delay_ms(5);        //t_WR
  14.     return (u8)ack;
  15. }
 楼主| 过期的塔头 发表于 2022-11-30 19:51 | 显示全部楼层
ROM区域寄存器读

        要检查 ROM 区域寄存器的当前状态,主器件必须对随机读操作序列进行仿真,但使用的是操作码 0111b(7h)。为了指定将要读取的 ROM 区域寄存器地址,需要使用随机读操作序列的虚拟写入部分。
 楼主| 过期的塔头 发表于 2022-11-30 19:51 | 显示全部楼层
代码:
  1. u8 RomZoneRegWrite(u8 addr)
  2. {
  3.     Ack_t ack = ACK;

  4.     if(addr != 1 && addr != 2 && addr != 4 && addr != 8)
  5.     {
  6.         return 0xEE;        //ERROR
  7.     }
  8.     DELAY_HTSS();
  9.     ack &= AT21CS01_SendByte(ROM_ZONE_REG_ACCESS | WRITE);
  10.     ack &= AT21CS01_SendByte(addr);
  11.     ack &= AT21CS01_SendByte(0xFF);
  12.     DELAY_HTSS();
  13.     delay_ms(5);        //t_WR
  14.     return (u8)ack;
  15. }
 楼主| 过期的塔头 发表于 2022-11-30 19:52 | 显示全部楼层
冻结ROM区域寄存器

        通过冻结当前 ROM 区域状态,可防止对 ROM 区域寄存器进行进一步修改。一旦冻结,便无法撤销此事件。
 楼主| 过期的塔头 发表于 2022-11-30 19:53 | 显示全部楼层
  1. u8 RomZoneRegFreeze(void)
  2. {
  3.     Ack_t ack = ACK;

  4.     DELAY_HTSS();
  5.     ack &= AT21CS01_SendByte(FREEZE_ROM_ZONE_STATE | WRITE);
  6.     if(ack == NACK)        //可能是之前已经冻结
  7.     {
  8.         return ack;
  9.     }
  10.     ack &= AT21CS01_SendByte(0x55);
  11.     ack = AT21CS01_SendByte(0xAA);        //NACK:已经锁定 ACK:锁定成功
  12.     DELAY_HTSS();
  13.     delay_ms(5);        //t_WR
  14.     return ack;
  15. }
 楼主| 过期的塔头 发表于 2022-11-30 19:53 | 显示全部楼层
安全寄存器访问

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 过期的塔头 发表于 2022-11-30 19:54 | 显示全部楼层
代码:
  1. //安全寄存器页写
  2. Ack_t SecRegWritePage(u8* data, u8 addr, u16 len)
  3. {
  4.     int i = 0;
  5.     Ack_t ack = ACK;

  6.     DELAY_HTSS();
  7.     ack &= AT21CS01_SendByte(SECURITY_REG_ACCESS | WRITE);
  8.     ack &= AT21CS01_SendByte(addr);
  9.     for(i = 0; i < len; i++)
  10.     {
  11.         ack &= AT21CS01_SendByte(data[i]);
  12.     }
  13.     DELAY_HTSS();
  14.     delay_ms(5);        //t_WR
  15.     return ack;
  16. }
 楼主| 过期的塔头 发表于 2022-11-30 19:55 | 显示全部楼层
//读取安全寄存器中的序列号
void SecRegReadSN(u8* buffer)
{
    DELAY_HTSS();
    AT21CS01_SendByte(SECURITY_REG_ACCESS | WRITE);//dummy write
    AT21CS01_SendByte(0x00);
    delay_us(800);
    AT21CS01_SendByte(SECURITY_REG_ACCESS | READ);
    AT21CS01_ReadData(buffer, 8);
    DELAY_HTSS();
}
 楼主| 过期的塔头 发表于 2022-11-30 19:55 | 显示全部楼层
锁定命令是一个不可逆序列,在此之后将永久阻止对 AT21CS01/11 上的安全寄存器高 16 字节的所有写操作。一旦执行了锁定命令,整个 32 字节的安全寄存器都变为只读。一旦锁定了安全寄存器,便无法将其解锁。
 楼主| 过期的塔头 发表于 2022-11-30 19:57 | 显示全部楼层
  1. //锁定安全寄存器
  2. Ack_t SecRegLock(void)
  3. {
  4.     Ack_t ack = ACK;

  5.     DELAY_HTSS();
  6.     ack &= AT21CS01_SendByte(SECURITY_REG_LOCK | WRITE);
  7.     ack &= AT21CS01_SendByte(0x60);                //NACK:已经锁定 ACK:锁定成功
  8.     if(ack == NACK)
  9.     {
  10.         return ack;
  11.     }
  12.     ack &= AT21CS01_SendByte(0x00);
  13.     DELAY_HTSS();
  14.     delay_ms(5);        //t_WR
  15.     return ack;
  16. }
 楼主| 过期的塔头 发表于 2022-11-30 19:58 | 显示全部楼层
制造商ID读取

        AT21CS01/11 提供了查询器件制造商、容量和版本信息的功能。通过使用特定的操作码并遵循当前地址读操作的格式,器件将返回一个 24 位值,该值对应为 Microchip 保留的 I2C 标识符值以及用于表示 1 Kb 容量和器件版本的其他数据。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
 楼主| 过期的塔头 发表于 2022-11-30 19:59 | 显示全部楼层
代码:

void MfrIDRead(u8* buffer)
{
    DELAY_HTSS();
    AT21CS01_SendByte(MFRID_READ | READ);//注意这个没有假写
    AT21CS01_ReadData(buffer, 3);
    DELAY_HTSS();
}
 楼主| 过期的塔头 发表于 2022-11-30 20:00 | 显示全部楼层
高速/标准速度模式
9.1 模式切换

        可以使用 Eh 操作码将器件设置为高速模式或检查其是否处于高速模式。该事务只需要 8 位。AT21CS01/11 在上电后默认处于高速模式。
        可以使用 Dh 操作码将 AT21CS01 设置为标准模式或检查其是否处于标准模式。该事务只需要 8 位。
 楼主| 过期的塔头 发表于 2022-11-30 20:02 | 显示全部楼层
代码:
  1. void SpeedModeSet(u8 mode)
  2. {
  3.     DELAY_HTSS();
  4.     if(mode == HIGH_SPEED_MODE || mode == HIGH_SPEED)
  5.     {
  6.         AT21CS01_SendByte(HIGH_SPEED_MODE | WRITE);
  7.         SPEED_MODE = HIGH_SPEED;
  8.     }
  9.     else if(mode == STANDARD_SPEED_MODE || mode == STANDARD_SPEED)
  10.     {
  11.         AT21CS01_SendByte(STANDARD_SPEED_MODE | WRITE);
  12.         SPEED_MODE = STANDARD_SPEED;
  13.     }
  14.     DELAY_HTSS();
  15. }
 楼主| 过期的塔头 发表于 2022-11-30 20:02 | 显示全部楼层
模式检查

        要确定器件是否已设置为标准模式,必须将器件地址字节(操作码为 1101b(Dh))连同相应的从器件地址组合一起发送到器件,并且将读/写 位设置为逻辑 1。如果器件已设置为标准速度模式,则将返回 ACK(逻辑 0)。如果器件当前未设置为标准速度模式,则将返回 NACK(逻辑 1)。
        要确定器件是否已设置为高速模式,必须将器件地址字节(指定操作码 1110b(Eh))连同相应的从器件地址组合一起发送到器件,并且将读/写 位设置为逻辑 1。如果器件已设置为高速模式,则将返回 ACK(逻辑 0)。如果器件当前未设置为高速模式,则将返回 NACK(逻辑 1)。
 楼主| 过期的塔头 发表于 2022-11-30 20:03 | 显示全部楼层
代码:
  1. Ack_t SpeedModeCheck(u8 mode)
  2. {
  3.     Ack_t ack = ACK;

  4.     DELAY_HTSS();
  5.     if(mode == HIGH_SPEED_MODE || mode == HIGH_SPEED)
  6.     {
  7.         ack = AT21CS01_SendByte(HIGH_SPEED_MODE | READ);
  8.     }
  9.     else if(mode == STANDARD_SPEED_MODE || mode == STANDARD_SPEED)
  10.     {
  11.         ack = AT21CS01_SendByte(STANDARD_SPEED_MODE | READ);
  12.     }
  13.     DELAY_HTSS();
  14.     return ack;
  15. }
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 在线客服 返回列表 返回顶部