oskar777 napisał:
Dzięki za przykład działa dobrze, tylko nadal mnie zastanawia czemu to nie działa, tym bardziej że ten kod powyżej jest o wiele łatwiejszy.
Chyba wartość kodu ocenia się w pierwszej kolejności na podstawie jego skuteczności, a nie tego, czy jest łatwiejszy. No bo co z tego, że jest łatwiejszy, jeśli nie działa?
Przykład, który podałem nie jest mojego autorstwa, jak już zresztą wcześniej zaznaczyłem. Pochodzi z "AVR Libc User Manual". Ja go tylko opatrzyłem komentarzami. Nie chcesz chyba zarzucić autorom AVR libc, że piszą jakiś nieefektywny kod lub podają złe przykłady?
Nie ma nic dziwnego w tym, że Twój kod nie działa. Nie możesz w ten sposób podać do funkcji wskaźnika zapisanego w pamięci flash. W deklaracji
char* Menu_wskaznik[] PROGMEM = {Menu_1,Menu_2,Menu_3};
pomiń atrybut PROGMEM (tablica wskaźników wyląduje wtedy w pamięci RAM, ale Twój kod powinien działać prawidłowo).
Jak masz tablicę wskaźników zapisaną we flash, to musisz to zrobić tak, jak w podanym przeze mnie przykładzie, pomimo tego, że jest to trudniejsze
P.S. Uprzedzę może jeszcze pytanie, dlaczego działa ze stałymi indeksami (
LCD_WriteTextP(Menu_wskaznik[1]);), a nie działa ze zmienną w indeksie (
LCD_WriteTextP(Menu_wskaznik[numer]);). Otóż kompilator w przypadku podania stałej jako indeksu tablicy znając zawartość tej tablicy wymieni w czasie kompilacji
Menu_wskaznik[1] na wartość wskaźnika
Menu_2. Jak użyjesz jako indeksu zmiennej, to już nie może tego zrobić, bo nie jest w stanie podczas kompilacji ustalić, którego wskaźnika w danym momencie użyjesz (jaka będzie wartość zmiennej indeksującej). Musisz więc ten wskaźnik odczytać programowo, a ponieważ jest on w pamięci flash, nie da się tego zrobić bezpośrednio, jak w przypadku zmiennych w RAM
Menu_wskaznik[i]. Najlepiej do tego użyć:
memcpy_P(&tekst, &Menu_wskaznik[i], sizeof(const char *));
Dopiero wtedy możesz użyć zmiennej 'tekst' do odczytywania ciągu znaków z pamięci flash, tak jak to zrobiłeś.