Teraz mam nieco czasu, więc pozwolę sobie na szerszą odpowiedź.
rskup napisał(a):
Tutaj andrews trochę Ci namieszał
![Puszcza oko ;)](https://forum.atnel.pl/images/smilies/icon_e_wink.gif)
, bo namawia Cię do tego co od pewnego czasu avr gcc udostępnia, czyli nowy sposób na definiowanie zmiennych / stałych w pamięciach EEPROM/Flash zwany Named Address Spaces.
"Namawianie" nie było skierowane do konkretnej osoby, tylko do ogółu czytających ten wątek.
Named Address Spaces funkcjonują już od prawie
6 lat i nie jest to wcale taka nowość. Mimo tego cały czas odnoszę wrażenie, że wielu programistów odczuwa niechęć do czegoś, co naprawdę upraszcza kod i eliminuje kilka poważnych problemów.
Szczególnie mam tutaj na myśli właśnie początkujących. Jeśli bowiem ktoś opanuje już pewne podstawowe zagadnienia, wie co to są zmienne, tablice, struktury, potrafi je zdefiniować w RAM i prawidłowo odczytać, a później chce pewne
stałe dane przenieść do FLASH, by zaoszczędzić nieco pamięci RAM, to (jak pokazałem w swoim przykładowym kodzie) wystarczy do zmiennej globalnej dopisać kwalifikator
__flash i kod będzie działał prawidłowo bez modyfikacji. Nie trzeba pamiętać o konieczności użycia makr, nie trzeba się uczyć tych wszystkich makr z rodziny
pgm_read_xxx() i godzinami modyfikować kodu (który dla danych w RAM działał przecież prawidłowo), zastanawiając się, które makro użyć, aby odczytać odpowiednią ilość bajtów dla typu odczytywanej zmiennej, jak pobrać prawidłowy adres odczytywanej zmiennej, aby odczytać dokładnie to co chcemy itp.
rskup napisał(a):
W skrócie działa to tak, że przez odpowiednie zdefiniowanie zmiennej zrzuca się z programisty konieczność późniejszego odpowiedniego odczytywania jej (czyli korzystania z np. pgm_read_byte()).
Nie bardzo rozumiem, co miałeś na myśli używając określenia "odpowiedniego odczytywania", ale zapewniam Cię, że odczytywanie danych zdefiniowanych z kwalifikatorem
__flash jest na pewno dużo bardziej odpowiednie, niż używanie makr
pgm_read_xxx(). Stosowanie tych makr to nie tylko kwestia niewygody i gorszej czytelności kodu. Jeśli programista ich używa, kompilator traci możliwość kontroli typów, która jest ważnym elementem analizy poprawności kodu. Użycie
__flash (lub
__memx) eliminuje ten problem.
Reasumując, poza siłą przyzwyczajenia i strachem przed nieznanym, osobiście nie widzę argumentów przemawiających za stosowaniem makr
pgm_read_xxx(), za to na pewno widzę kilka przeciw
![Puszcza oko ;)](https://forum.atnel.pl/images/smilies/icon_e_wink.gif)
Robert_1967 napisał(a):
Co do funkcji lcd_char_P, czy lcd_str_P() , to myślę, że lepiej je rozgraniczyć (P), ponieważ moim skromnym zdaniem będziemy wiedzieć, co kiedy użyć
(nie zwalnia od myślenia). Jeśli funkcja jest uniwersalna, to nie zastanawiamy się, której aktualnie potrzebujemy, bo i tak zadziała.
Nie obraź się, ale moje skromne zdanie jest akurat dokładnie odwrotne. I wcale nie chodzi o to, że myślenie mnie boli
![Puszcza oko ;)](https://forum.atnel.pl/images/smilies/icon_e_wink.gif)
Generalnie języki wyższego poziomu po to zostały stworzone, aby ułatwiać życie programiście, co nie oznacza, że przez to "zwalniają od myślenia". Po prostu dzięki nim programista może myśleć bardziej globalnie, a oprócz tego, jakiej funkcji użyć w zależności od miejsca zapisania danych, jest na prawdę wiele innych rzeczy, które musi przemyśleć.
Nie traktuj tego co powiedziałem jako złośliwość. Nikomu nie chcę odbierać prawa do własnego zdania oraz własnych wyborów i szanuję je nawet, jeśli się z nimi nie zgadzam.
Wprawdzie tylko kolega
Daro69 zainteresował się tematem funkcji uniwersalnej, ale mimo wszystko podpowiem co obiecałem
![Puszcza oko ;)](https://forum.atnel.pl/images/smilies/icon_e_wink.gif)
Nie znam kodu funkcji
lcd_str(), której używa kolega
Robert_1967, ale powiedzmy, że to coś w stylu:
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
"Przerobienie" funkcji polegałoby w takim przypadku na dodaniu kwalifikatora
__memx do parametru funkcji (oczywiście tak samo w deklaracji jak i w definicji):
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Dane definiujemy globalnie:
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
Funkcję wywołujemy:
język c
Musisz się zalogować, aby zobaczyć kod źródłowy. Tylko zalogowani użytkownicy mogą widzieć kod.
I to by było na tyle...
Pozdrawiam
Andrzej