直接从 C 源代码对 AVR EEPROM 进行编程

电器工程 avr C 服装 eeprom
2022-01-12 07:07:26

当您在 AVR C 源代码中包含以下代码时,您显然可以直接对熔丝进行编程,而无需额外的命令或 .hex 文件:

#include <avr/io.h>

FUSES = {
        .low =          LFUSE_DEFAULT ,
        .high =         HFUSE_DEFAULT ,
        .extended =     EFUSE_DEFAULT ,
};

在 EEPROM 中编程值是否有类似的技巧?

我已经检查了/usr/lib/avr/include/avr/fuse.h在哪里可以找到关于宏的一些评论,但是我在其中找不到类似的评论,/usr/lib/avr/include/avr/eeprom.h并且解释预处理器的内容有点超出我的范围。

如果我可以在 C 源代码中包含默认的 EEPROM 值,那将非常方便。有谁知道如何做到这一点?

编辑1:

这个 FUSES 技巧只在 ISP 时执行,而不是在 RUN 时执行。因此,在控制器中生成的汇编代码中没有对保险丝进行编程。相反,程序员会自动循环通过一个额外的 FUSES 编程周期。

编辑2:

我在 Linux 上使用 avr-gcc 和 avrdude 工具链。

2个回答

使用 avr-gccEEMEM宏可用于变量的定义,请参见此处的libc文档和示例

#include <avr/eeprom.h>
char myEepromString[] EEMEM = "Hello World!";

声明字符数组驻留在名为“.eeprom”的部分中,编译后告诉程序员该数据将被编程到 EEPROM。根据您的程序员软件,您可能需要明确地将在构建过程中创建的“.eep”文件的名称提供给程序员,或者它可能会自行隐式找到它。

是的,您可以在源代码中手动将默认数据写入 EEPROM。首先,查看这个关于 AVR EEPROM 的精彩指南:Dean 的 AVR EEPROM 教程。另外,我应该补充一点,使用 makefile 创建一个包含 EEPROM 数据的 .eep 文件是一个更好的主意,该文件将与源代码一起编程到设备中。但是,如果您不熟悉各种 makefile 和链接器操作,仍然可以在您的源代码文件中完成 - 只要电路通电,就会停止初始程序操作。

在程序开始时(在任何类型的主循环之前),您可以执行以下操作:

#include <avr/eeprom.h>

#define ADDRESS_1 46  // This could be anything from 0 to the highest EEPROM address
#define ADDRESS_2 52  // This could be anything from 0 to the highest EEPROM address
#define ADDRESS_3 68  // This could be anything from 0 to the highest EEPROM address

uint8_t dataByte1 = 0x7F;  // Data for address 1
uint8_t dataByte2 = 0x33;  // Data for address 2
uint8_t dataByte3 = 0xCE;  // Data for address 3

eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
eeprom_update_byte((uint8_t*)ADDRESS_2, dataByte2);
eeprom_update_byte((uint8_t*)ADDRESS_3, dataByte3);

“更新”功能首先检查该值是否已经存在,以节省不必要的写入,保持 EEPROM 寿命。但是,对很多位置执行此操作可能需要相当长的时间。检查单个位置可能会更好。如果它是所需的值,则可以完全跳过其余的更新。例如:

if(eeprom_read_byte((uint8_t*)SOME_LOCATION) != DESIRED_VALUE){
  eeprom_write_byte((uint8_t*)SOME_LOCATION, DESIRED_VALUE);
  eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
  eeprom_update_byte((uint8_t*)ADDRESS_2, dataByte2);
  eeprom_update_byte((uint8_t*)ADDRESS_3, dataByte3);
}

如果您要更新大量数据,请尝试使用其他功能,例如eeprom_update_block(...). 并且一定要阅读该教程;它写得很好。

您可以将所有 EEPROM 更新语句放在一个预处理器条件语句中。这很简单:

#if defined _UPDATE_EEPROM_
  #define ADDRESS_1 46  // This could be anything from 0 to the highest EEPROM address
  uint8_t dataByte = 0x7F;  // Data for address 1
  eeprom_update_byte((uint8_t*)ADDRESS_1, dataByte1);
#endif // _UPDATE_EEPROM_

除非您执行以下操作,否则甚至不会编译这段代码:

#define _UPDATE_EEPROM_

您可以将其作为注释留在那里,如果您需要更改默认 EEPROM 值,请取消注释。有关 C 预处理器的更多信息,请查看此在线手册我想你可能对宏和条件语句部分最感兴趣。