Отключение указателя на сравнение указателей при удалении while (1) - почему? - PullRequest
0 голосов
/ 03 марта 2020

Попытка построить систему меню, но столкнуться с некоторыми проблемами с указателями - с которыми у меня не так много опыта.

Я не понимаю, почему удаление while (1) приводит к сбою сравнения между mainmenu_table [1] [i] == & option6, но по какой-то причине это так.

Что я делаю не так? Используя visual studio и atmega328p. Спасибо

Последовательный вывод с исходным кодом:

Serial begins
MeNu6
MeNu6
Starting compare loop
it worked

Последовательный вывод с удаленным while (1).

Serial begins
MeNu6
MeNu6
Starting compare loop
the end

Оригинальный код (с включенным while (1))

const char option1[] PROGMEM = "Menu1";
const char option2[] PROGMEM = "MEnu2";
const char option3[] PROGMEM = "MeNu3";

const char option4[] PROGMEM = "Menu4";
const char option5[] PROGMEM = "MEnu5";
const char option6[] PROGMEM = "MeNu6";
const char option7[] PROGMEM = "menu7";

const char* const submenu1_table[] PROGMEM = { option1, option2, option3 }; // array of pointers to chars stored in flash
const char* const submenu2_table[] PROGMEM = { option4, option5, option6, option7 };
const char** const mainmenu_table[] PROGMEM = { submenu1_table, submenu2_table }; //array of pointers to pointers to chars in flash


// The setup() function runs once each time the micro-controller starts
void setup()
{

    Serial.begin(9600);
    delay(100);
    Serial.println("Serial begins");  

    Serial.println((const __FlashStringHelper*)(mainmenu_table[1][2]));  // prints "Menu6" as expected
    Serial.println((const __FlashStringHelper*)option6);  // also prints "Menu6"

    Serial.println("Starting compare loop");

    for (int i = 0; i < 4; i++) {
        if ( mainmenu_table[1][i] == &option6 ) { //
            Serial.println("it worked");
            while (1);  // COMMENTING THIS OUT MEANS DOESN'T COMPARE SUCCESSFULLY.
        }
    }

    Serial.println("the end");

}

// Add the main program code into the continuous loop() function
void loop()
{

}

1 Ответ

2 голосов
/ 03 марта 2020

Согласно описанию Arduino PROGMEM , вы не можете получить доступ к данным через указатели на них напрямую, как с простыми указателями. Вам необходимо использовать правильные макросы / функции для доступа к данным.

В вашем коде сами таблицы указателей расположены в PROGMEM, поэтому для извлечения отдельных указателей вы должен делать что-то вроде:

const char** submenu = (const char**)pgm_read_word(&(mainmenu_table[1]));
const char* option = (const char*)pgm_read_word(&(submenu[i]));
if (option == option6) {
    //...

Этот код основан на примере таблицы строк из первой ссылки.

...