Arduino从PROGMEM数组读取元素时得到垃圾数据该如何解决
Arduino PROGMEM数组读取错误问题解决
核心原因
AVR架构的Arduino(如Uno、Nano、Mega系列)中,PROGMEM修饰的常量会被存储在Flash程序存储空间,而非SRAM运行内存。常规的数组索引访问逻辑只会读取SRAM地址空间的数据,所以直接用myArray[i]读取PROGMEM数组,得到的是对应SRAM地址的垃圾值,这是正常现象。
解决步骤
1. 引入必要头文件
在代码开头显式引入PROGMEM操作的头文件,避免部分环境编译异常:
#include <avr/pgmspace.h>
你现有的数组定义本身是正确的,无需修改。
2. 使用专用Flash读取函数
32位长整型(long)在AVR架构下占4字节,需要使用读32位双字的专用函数访问Flash数据,修改后的setup函数如下:
void setup() { Serial.begin(115200); for( int i = 0; i < SIZE_OF_ARRAY; i++){ // 先取数组对应元素的Flash地址,再读取该地址的32位数据 long currentNumber = pgm_read_dword_near(&myArray[i]); Serial.println(currentNumber); } } void loop() { }
如果你使用的是Flash容量大于64KB的设备(如Mega2560),请将
pgm_read_dword_near替换为pgm_read_dword_far。
之前写法错误说明
- 直接
myArray[i]访问:默认寻址SRAM空间,PROGMEM数据在独立的Flash地址空间,地址映射不重叠,因此读到垃圾数据。 - 尝试的
pgm_read_word_near:该函数仅读取16位长度数据,你的数组元素是32位long,读取长度不匹配必然得到错误值。 - 尝试的
pgm_read_dword_near(myArray + i):该写法理论上和&myArray[i]等价,如果运行仍报错,大概率是未引入<avr/pgmspace.h>头文件,或设备需要用far版本的读取函数。
内容的提问来源于stack exchange,提问作者doominabox1
相关产品推荐
相关产品推荐

