Memory 在Arduino和#x27之间读写结构;可编程只读存储器

Memory 在Arduino和#x27之间读写结构;可编程只读存储器,memory,struct,arduino,eeprom,Memory,Struct,Arduino,Eeprom,我正在尝试将C中定义的数据结构写入Arduino Uno板的非易失性内存,因此在断电或重置后,结构的值将保留。 据我所知,唯一的方法(在草图运行时)是写入arduino的EEPROM。虽然我可以写入单个字节(在地址0处设置值为1的字节): 我一直在努力写一个完整的结构: typedef struct NewProject_Sequence { NewProject_SequenceId sequenceId; NewProject_SequenceLength maxRange;

我正在尝试将C中定义的数据结构写入Arduino Uno板的非易失性内存,因此在断电或重置后,结构的值将保留。 据我所知,唯一的方法(在草图运行时)是写入arduino的EEPROM。虽然我可以写入单个字节(在地址0处设置值为1的字节):

我一直在努力写一个完整的结构:

typedef struct NewProject_Sequence {
    NewProject_SequenceId sequenceId;
    NewProject_SequenceLength maxRange;
    NewProject_SequenceLength minRange;
    NewProject_SequenceLength seqLength;
    NewProject_SceneId sceneList[5];
} NewProject_Sequence;
由于EEPROM的写入限制为100000次,我不想在循环中写入Arduino,因为这可能会很快用完它。是否有人知道一种更有效的方法,无论是使用EEPROM,还是在草图运行时有方法写入PROGMEM?(不使用Arduino库,只使用C)

已解决 最后我编写了两个自定义函数——eepromWrite和eepromRead。它们列在下面:

void eepromRead(uint16_t addr, void* output, uint16_t length) {
    uint8_t* src; 
    uint8_t* dst;
    src = (uint8_t*)addr;
    dst = (uint8_t*)output;
    for (uint16_t i = 0; i < length; i++) {
        *dst++ = eeprom_read_byte(src++);
    }
}

void eepromWrite(uint16_t addr, void* input, uint16_t length) {
    uint8_t* src; 
    uint8_t* dst;
    src = (uint8_t*)input;
    dst = (uint8_t*)addr;
    for (uint16_t i = 0; i < length; i++) {
        eeprom_write_byte(dst++, *src++);
    }
}

几种解决方案和/或组合

  • 设置计时器事件以定期存储值,而不是 背靠背
  • 使用校验和,然后增加初始偏移, 写作的时候。当读取时,尝试每个增量,直到 您有一个有效的校验和。这会将您的数据传播到整个系统 射程增加你的生命。现代闪存驱动器可以做到这一点
  • 通过使用外部褐化检测器触发INT,然后快速写入EEPROM,捕捉装置关闭。然后,您还可以使用内部BOD在其低于安全写入电压之前防止损坏。通过使外部阈值显著高于内部阈值。可通过增加VCC电容来增加完全关闭前的写入时间。在VCC之前比较外部BOD,而不是直接比较VCC本身

  • 下面是一段视频,解释了如何为阁楼启用内部BOD,其中它与其他ATmega几乎相同

    Arduino EEPROM库提供能够读取和写入结构的get/put函数

    仅当字节发生更改时才进行写入

    因此,使用put/get是解决问题的方法

    我在一个广泛(25k)的项目中使用这些,没有任何问题

    正如我已经说过的,我不是每次都用定时器,而是一次一次地写

    关闭检测也是一种很好的方法

    void eepromRead(uint16_t addr, void* output, uint16_t length) {
        uint8_t* src; 
        uint8_t* dst;
        src = (uint8_t*)addr;
        dst = (uint8_t*)output;
        for (uint16_t i = 0; i < length; i++) {
            *dst++ = eeprom_read_byte(src++);
        }
    }
    
    void eepromWrite(uint16_t addr, void* input, uint16_t length) {
        uint8_t* src; 
        uint8_t* dst;
        src = (uint8_t*)input;
        dst = (uint8_t*)addr;
        for (uint16_t i = 0; i < length; i++) {
            eeprom_write_byte(dst++, *src++);
        }
    }
    
    uint16_t currentAddress;
    struct {
        uint16_t x;
        uint16_t y;
    } data;
    
    struct {
    
    } output;
    uint16_t input
    
    eepromWrite(currentAddress, data, sizeof(data);
    eepromRead(currentAddress, output, sizeof(data));