在documentation on PROGMEM的底部,它显示了将字符串编译到程序中的简单方法.text段:
F()宏
当一条指令如下:
Serial.print("Write something");
使用,要打印的字符串通常保存在RAM中。如果您的草图在串行监视器上打印了很多东西,您可以轻松填充RAM。如果你有空闲的FLASH存储空间,你可以使用以下语法轻松指示字符串必须保存在FLASH中:
Serial.print(F("Write something that is stored in FLASH"));
然而,我只有运气不好才能编译。
#include <avr/pgmspace.h>
static const struct {short cmd; const char *txt;} cmds[] = {
{2, F("Hi")},
};
抱怨
t.c:3: error: initializer element is not constant
{2, F("hi")},
^
t.c:3: error: (near initialization for 'cmds[0].txt')
exit status 1
initializer element is not constant
没有F
宏,它编译得很好。
{2, "Hi"},
有没有人有这方面的工作经验?我喜欢10K的字符串,我想进入程序空间。
答案 0 :(得分:1)
F 宏只能用于代码的可执行部分,而不能用于变量定义。因为struct成员不能拥有PROGMEM属性,所以你必须分两步完成:在PROGMEM中声明每个文本字符串,然后在结构中使用PROGMEM地址。
结构数组也可以在PROGMEM中。
static const char cmd_0_txt[] PROGMEM = "Hello";
static const char cmd_1_txt[] PROGMEM = "World";
struct cmd_t {short cmd; const char *txt; }; // the struct type
// An array of structs in PROGMEM
static const cmd_t cmds[] PROGMEM = {
{2, cmd_0_txt},
{2, cmd_1_txt},
};
void setup()
{
Serial.begin( 9600 );
Serial.println( F("Test") );
for (uint8_t i=0; i < sizeof(cmds)/sizeof(cmds[0]); i++) {
// First, read the PROGMEM txt member (a pointer to the text)
const char *ptr = (const char *) pgm_read_word( &cmds[i].txt ); // cast required
// Next, read each text character from that PROGMEM location
for (;;) {
char c = pgm_read_byte( ptr++ );
if (!c)
break;
Serial.print( c );
}
Serial.println();
}
}
void loop()
{}