为什么没有F()宏(在.text中存储字符串)编译?

时间:2016-02-04 23:24:23

标签: arduino arduino-ide

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的字符串,我想进入程序空间。

1 个答案:

答案 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()
{}