发新帖我要提问
12
返回列表
打印
[学习资料]

基于STM32的AT21CS01 EEPROM驱动代码

[复制链接]
楼主: 过期的塔头
手机看帖
扫描二维码
随时随地手机跟帖
21
过期的塔头|  楼主 | 2022-11-30 19:48 | 只看该作者 |只看大图 回帖奖励 |倒序浏览
ROM区域寄存器写

        ROM 区域寄存器只能写入逻辑 1,该操作会将相应的存储区域设置为 ROM 状态。一旦写入 ROM 区域寄存器,便无法再次更改。

使用特权

评论回复
22
过期的塔头|  楼主 | 2022-11-30 19:49 | 只看该作者
代码:
u8 RomZoneRegWrite(u8 addr)
{
    Ack_t ack = ACK;

    if(addr != 1 && addr != 2 && addr != 4 && addr != 8)
    {
        return 0xEE;        //ERROR
    }
    DELAY_HTSS();
    ack &= AT21CS01_SendByte(ROM_ZONE_REG_ACCESS | WRITE);
    ack &= AT21CS01_SendByte(addr);
    ack &= AT21CS01_SendByte(0xFF);
    DELAY_HTSS();
    delay_ms(5);        //t_WR
    return (u8)ack;
}

使用特权

评论回复
23
过期的塔头|  楼主 | 2022-11-30 19:50 | 只看该作者
ROM区域寄存器写

        ROM 区域寄存器只能写入逻辑 1,该操作会将相应的存储区域设置为 ROM 状态。一旦写入 ROM 区域寄存器,便无法再次更改。

使用特权

评论回复
24
过期的塔头|  楼主 | 2022-11-30 19:50 | 只看该作者
代码:
u8 RomZoneRegWrite(u8 addr)
{
    Ack_t ack = ACK;

    if(addr != 1 && addr != 2 && addr != 4 && addr != 8)
    {
        return 0xEE;        //ERROR
    }
    DELAY_HTSS();
    ack &= AT21CS01_SendByte(ROM_ZONE_REG_ACCESS | WRITE);
    ack &= AT21CS01_SendByte(addr);
    ack &= AT21CS01_SendByte(0xFF);
    DELAY_HTSS();
    delay_ms(5);        //t_WR
    return (u8)ack;
}

使用特权

评论回复
25
过期的塔头|  楼主 | 2022-11-30 19:51 | 只看该作者
ROM区域寄存器读

        要检查 ROM 区域寄存器的当前状态,主器件必须对随机读操作序列进行仿真,但使用的是操作码 0111b(7h)。为了指定将要读取的 ROM 区域寄存器地址,需要使用随机读操作序列的虚拟写入部分。

使用特权

评论回复
26
过期的塔头|  楼主 | 2022-11-30 19:51 | 只看该作者
代码:
u8 RomZoneRegWrite(u8 addr)
{
    Ack_t ack = ACK;

    if(addr != 1 && addr != 2 && addr != 4 && addr != 8)
    {
        return 0xEE;        //ERROR
    }
    DELAY_HTSS();
    ack &= AT21CS01_SendByte(ROM_ZONE_REG_ACCESS | WRITE);
    ack &= AT21CS01_SendByte(addr);
    ack &= AT21CS01_SendByte(0xFF);
    DELAY_HTSS();
    delay_ms(5);        //t_WR
    return (u8)ack;
}

使用特权

评论回复
27
过期的塔头|  楼主 | 2022-11-30 19:52 | 只看该作者
冻结ROM区域寄存器

        通过冻结当前 ROM 区域状态,可防止对 ROM 区域寄存器进行进一步修改。一旦冻结,便无法撤销此事件。

使用特权

评论回复
28
过期的塔头|  楼主 | 2022-11-30 19:53 | 只看该作者
u8 RomZoneRegFreeze(void)
{
    Ack_t ack = ACK;

    DELAY_HTSS();
    ack &= AT21CS01_SendByte(FREEZE_ROM_ZONE_STATE | WRITE);
    if(ack == NACK)        //可能是之前已经冻结
    {
        return ack;
    }
    ack &= AT21CS01_SendByte(0x55);
    ack = AT21CS01_SendByte(0xAA);        //NACK:已经锁定 ACK:锁定成功
    DELAY_HTSS();
    delay_ms(5);        //t_WR
    return ack;
}

使用特权

评论回复
29
过期的塔头|  楼主 | 2022-11-30 19:53 | 只看该作者
安全寄存器访问

使用特权

评论回复
30
过期的塔头|  楼主 | 2022-11-30 19:54 | 只看该作者
代码:
//安全寄存器页写
Ack_t SecRegWritePage(u8* data, u8 addr, u16 len)
{
    int i = 0;
    Ack_t ack = ACK;

    DELAY_HTSS();
    ack &= AT21CS01_SendByte(SECURITY_REG_ACCESS | WRITE);
    ack &= AT21CS01_SendByte(addr);
    for(i = 0; i < len; i++)
    {
        ack &= AT21CS01_SendByte(data[i]);
    }
    DELAY_HTSS();
    delay_ms(5);        //t_WR
    return ack;
}

使用特权

评论回复
31
过期的塔头|  楼主 | 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();
}

使用特权

评论回复
32
过期的塔头|  楼主 | 2022-11-30 19:55 | 只看该作者
锁定命令是一个不可逆序列,在此之后将永久阻止对 AT21CS01/11 上的安全寄存器高 16 字节的所有写操作。一旦执行了锁定命令,整个 32 字节的安全寄存器都变为只读。一旦锁定了安全寄存器,便无法将其解锁。

使用特权

评论回复
33
过期的塔头|  楼主 | 2022-11-30 19:57 | 只看该作者
//锁定安全寄存器
Ack_t SecRegLock(void)
{
    Ack_t ack = ACK;

    DELAY_HTSS();
    ack &= AT21CS01_SendByte(SECURITY_REG_LOCK | WRITE);
    ack &= AT21CS01_SendByte(0x60);                //NACK:已经锁定 ACK:锁定成功
    if(ack == NACK)
    {
        return ack;
    }
    ack &= AT21CS01_SendByte(0x00);
    DELAY_HTSS();
    delay_ms(5);        //t_WR
    return ack;
}

使用特权

评论回复
34
过期的塔头|  楼主 | 2022-11-30 19:58 | 只看该作者
制造商ID读取

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

使用特权

评论回复
35
过期的塔头|  楼主 | 2022-11-30 19:59 | 只看该作者
代码:

void MfrIDRead(u8* buffer)
{
    DELAY_HTSS();
    AT21CS01_SendByte(MFRID_READ | READ);//注意这个没有假写
    AT21CS01_ReadData(buffer, 3);
    DELAY_HTSS();
}

使用特权

评论回复
36
过期的塔头|  楼主 | 2022-11-30 20:00 | 只看该作者
高速/标准速度模式
9.1 模式切换

        可以使用 Eh 操作码将器件设置为高速模式或检查其是否处于高速模式。该事务只需要 8 位。AT21CS01/11 在上电后默认处于高速模式。
        可以使用 Dh 操作码将 AT21CS01 设置为标准模式或检查其是否处于标准模式。该事务只需要 8 位。

使用特权

评论回复
37
过期的塔头|  楼主 | 2022-11-30 20:02 | 只看该作者
代码:
void SpeedModeSet(u8 mode)
{
    DELAY_HTSS();
    if(mode == HIGH_SPEED_MODE || mode == HIGH_SPEED)
    {
        AT21CS01_SendByte(HIGH_SPEED_MODE | WRITE);
        SPEED_MODE = HIGH_SPEED;
    }
    else if(mode == STANDARD_SPEED_MODE || mode == STANDARD_SPEED)
    {
        AT21CS01_SendByte(STANDARD_SPEED_MODE | WRITE);
        SPEED_MODE = STANDARD_SPEED;
    }
    DELAY_HTSS();
}

使用特权

评论回复
38
过期的塔头|  楼主 | 2022-11-30 20:02 | 只看该作者
模式检查

        要确定器件是否已设置为标准模式,必须将器件地址字节(操作码为 1101b(Dh))连同相应的从器件地址组合一起发送到器件,并且将读/写 位设置为逻辑 1。如果器件已设置为标准速度模式,则将返回 ACK(逻辑 0)。如果器件当前未设置为标准速度模式,则将返回 NACK(逻辑 1)。
        要确定器件是否已设置为高速模式,必须将器件地址字节(指定操作码 1110b(Eh))连同相应的从器件地址组合一起发送到器件,并且将读/写 位设置为逻辑 1。如果器件已设置为高速模式,则将返回 ACK(逻辑 0)。如果器件当前未设置为高速模式,则将返回 NACK(逻辑 1)。

使用特权

评论回复
39
过期的塔头|  楼主 | 2022-11-30 20:03 | 只看该作者
代码:
Ack_t SpeedModeCheck(u8 mode)
{
    Ack_t ack = ACK;

    DELAY_HTSS();
    if(mode == HIGH_SPEED_MODE || mode == HIGH_SPEED)
    {
        ack = AT21CS01_SendByte(HIGH_SPEED_MODE | READ);
    }
    else if(mode == STANDARD_SPEED_MODE || mode == STANDARD_SPEED)
    {
        ack = AT21CS01_SendByte(STANDARD_SPEED_MODE | READ);
    }
    DELAY_HTSS();
    return ack;
}

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则