You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

AVR内部EEPROM写入函数异常,读取返回255问题求助

ATMEGA32 EEPROM读写返回255的问题排查与修复

问题描述

实现了ATMEGA32的EEPROM读写函数,严格遵循数据手册编写,但写入数据后读取结果始终为255(0xFF),相关代码如下:

EEPROM.c

void IEEPROM_Write(u16 A_u16Adress, u8 A_u8Data)
{
    /* Wait for completion of previous write */
    while(GET_BIT(EECR,EECR_EEWE)==1);
    /* Set up address and data registers */
    EEAR = A_u16Adress;
    EEDR = A_u8Data;
    /* Write logical one to EEMWE */
    SET_BIT(EECR,EECR_EEMWE);
    /* Start eeprom write by setting EEWE */
    SET_BIT(EECR,EECR_EEWE);
}


u8 IEEPROM_Read(u16 A_u16Adress)
{
    /* Wait for completion of previous write */
    while(GET_BIT(EECR,EECR_EEWE)==1);
    /* Set up address and data registers */
    EEAR = A_u16Adress;
    /* Start eeprom read by setting EERE */
    SET_BIT(EECR,EECR_EERE);

    return EEDR;
}

EEPROM.h

#define EEARH (*(volatile u8 *)0x3F)
#define EEARL (*(volatile u8 *)0x3E)
#define EEAR (*(volatile u16 *)0x3E)
#define EECR (*(volatile u8 *)0x3C)
#define EECR_EERE 0
#define EECR_EEWE 1
#define EECR_EEMWE 2
#define EECR_EERIE 3

#define EEDR (*(volatile u8 *)0x3D)
void IEEPROM_Write(u16 A_u16Adress, u8 A_u8Data);
u8 IEEPROM_Read(u16 A_u16Adress);

可能原因与修复方案

1. GET_BIT/SET_BIT宏定义错误

代码中使用了GET_BIT和SET_BIT但未给出定义,若宏实现错误会直接导致读写逻辑失效:

  • 若GET_BIT错误地将位序号当作掩码使用,会导致等待循环直接跳过,写入未完成就执行后续操作;
  • 若SET_BIT实现错误,无法正确置位EEMWE/EEWE,写入操作根本不会触发。

正确宏定义示例:

#define GET_BIT(REG, BIT) ((REG >> BIT) & 1)
#define SET_BIT(REG, BIT) (REG |= (1 << BIT))

2. EEPROM写入时序不满足要求

ATMEGA32数据手册明确要求:置位EEMWE后,必须在4个时钟周期内置位EEWE,否则EEMWE会自动清零,写入操作无法触发。编译器优化可能会在两条SET_BIT指令间插入额外代码,破坏时序。

修复方案:
将EEMWE和EEWE的置位操作合并为连续的寄存器赋值,避免编译器插入冗余指令:

// 替换原有的两个SET_BIT语句
EECR |= (1 << EECR_EEMWE) | (1 << EECR_EEWE);

或者使用内联汇编严格保证时序:

asm volatile(
    "sbi %[eecr], %[eemwe]\n\t"
    "sbi %[eecr], %[eewe]"
    :
    : [eecr] "I" (_SFR_IO_ADDR(EECR)),
      [eemwe] "I" (EECR_EEMWE),
      [eewe] "I" (EECR_EEWE)
);

3. 访问地址超出EEPROM范围

ATMEGA32的EEPROM容量为512字节,有效地址范围是0x000~0x1FF。若写入/读取的地址超出此范围,会返回无效值0xFF。

修复方案:
确保传入的A_u16Adress在0x000到0x1FF之间,可在写入函数中添加地址校验:

if(A_u16Adress > 0x1FF) return; // 超出范围直接返回

4. 电源电压不足

EEPROM写入需要稳定的电源电压(ATMEGA32在5V工作时,写入推荐电压≥4.5V),若电源波动或电压不足,会导致写入失败,读取时返回默认的0xFF。

修复方案:
检查供电电路,确保电源电压稳定且满足芯片规格要求。


内容的提问来源于stack exchange,提问作者Omar A. Abdelazim

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 14:45:34