Programowanie ■
Programowanie ■
// Teksty
progehar PL_strDisplay[] « „Polski”;
progehar Pl.strStart[] * ..Witaj W wersji Polskiej
Listing 95 - plik lang/english.h // Teksty
prog ehar EN strDisplay[] =» „English"; próg char EN strStart [] — „Welcome in English yersion";
Listing 96 - nagłówki pliicu lar.gsys.c
#include <inttypes.h> #include <avr/pgmspdc_e.h>
#include „makra.h" #include „lcd.h"
#include ..langsys.h"
// Tutaj nagłówki języków ^inc^ude „lang/english.h” #irclude „lang/polski.h”
Listing 9? - zmienne i tablice w iocal.c
statlc uintx i lar.gsys scl « 0; // wybrany język
// Definicja informacji o znakach specjalnych const LCD_LOCAL_PGM* langsys IcdspecC] *
{
NULL,
PLlcdspec
li
Listing Qft - funkcje manipulujące językiem sv local C
// Ilość „zainstalowanych" języków i nl i ne uint8_t langsys GctNumOfLangs (voi d)
{
return LLfcMS(langsys_strTatle);
ł
// wybór języka
inline VOid langsys Select(ninlX t index)
{
langsys scl - indcx;
>
// Pobranie informacji o wybranym języku inline tini8 t langsys GetSelec:ed(void)
{
retu rn langsys sel;
}
// Pobranie nazwy języka o podanym indeksie prog ehar* langsys_GetLangName(uini8 i index)
if(inde\ > ELEMS (langsys strTable)) return NULL;
retu rn (prog_char*) pgm_rcad_word_ near C
Aangsys sIrTable[imiex] [IDS I ANCtN\ME]);
}
zapyta nas o wskazanie folderu, który zostanie odwzorowany. W następnym kroku zostaniemy poproszeni o podanie typu plików, jakie mają być brane pod uwagę - wpisujemy *.h. Resztą opcji możemy się nie przejmować i zostawić ich wartości domyślne.
Stwórzmy od razu pliki języków. Będą to dość nietypowe pliki nagłówkowe, ponieważ będziemy tworzyć w nich zmienne napisowe. Ważne jest, aby nagłówki te dołączać tylko w jednym miejscu całego programu. Z tego powodu też możemy pominąć pisanie sekwencji #ifndef #endif.
Plik lang/polski.h powstał poprzez skopiowanie zawartości pliku local.c z poprzedniej części. Zmienimy jedynie tworzone napisy a nazwy zmiennych zmodyfikujemy tak, aby zaczynały się od lilci PL_. Pokazuje to listing 94. Plik języka angielskiego będzie jeszcze prostszy, ponieważ język ten nie wymaga definicji znaków' specjalnych - zobacz listing 95.
Listing 94 plik lang/polski h
LCD LOG AL PGM PLJcdsp«c[18] -{
ABC... C
Dziś mtmy zamiar korzystać z tablicy zawierającej wskaźniki na wszystkie wykorzystywane napisy. ANSI-C daje nam proste narzędzie do tworzenia takich tablic: char* strTab[] -{
„Napis 2”,
Kompilator umieszcza w pamięć, napisy, a w tablicy wskaźniki na me. Pytanie jednak: jaka to będzie pamięć? Mamy do czynienia z pmhlcmenr na który natknęliśmy się kilkukrotnie ANSI-C zakłada jed nolitą przestrzeń adresową. W naszym przypadku dane zostaną umieszczone w pamięci RAM. Trafi tam zarówno tablica wskaźników, jak i same łańcuchy. Niewiele pomoże poniższa sztuczka: progehar* strTab [] PROGMEM =
Stwórzmy teraz moduł odpowiedzialny za zarządzanie językami. Utwórz dwa nowe pliki: langsys c oraz langsys.h i dodaj je do projektu. Przypominam o wpisaniu pliku langsys.c do pliku make file.
Listing 96 pokazuje niezbędne nam nagłówki. Zauważ, że nie dołączamy tutaj pliku <avr/io.h>. Moduł langsys nie zajmuje się sprzętem, dlatego też plik ten nic jest potrzebny. Do pliku langsys.c dołączamy pliki wszystkich języ ków i co bardzo ważne - robimy to tylko tutaj.
Zaraz po dołączeniu nagłówków tworzymy wszystkie potrzebne zmienne oraz tablice zawierające dane -pokazuje to listing 97. Pojawia się w tym miejscu po raz pierwszy tablica wielowymiarowa, o której możesz przeczytać w odpowiedniej ramce. Zwracam Twoja uwagę na wybrane przypisanie wymiarów: wymiar najwyższy to wymiar języka, wymiar niższy to kolejne teksty. Gdybyśmy wybrali odwrotną konwencję. rozmiar tablicy mógłby dostosowywać się automatycznie do ilości napisów.
Tahlica co prawda znajdzie się w pamięci programu. jednak napisy umieszczone zostaną w pamięci danych. Pomijając wszystkie możliwości które nie działają (plik z propozycją eksperymentów znajdzie się w materiałach dodatkowych), przedstawiam rozwiązanie przyjmowane przez AVR-GCC: progehar napisl []=„Napi s 1"; próg char napis2[]=„NapiS 2";
COHSt prog ehar* strTab [] PROGMEM ■*
napisl, napis2
Sztuczka polega na utworzeniu oddzielnie napi sów w pamięci programu, a następnie wprowadzenie do tablicy wskaźników na odpowiednie „zmienne”.
Dzięki operatorowi const pozbędziemy się ostrzeżenia podczas kompilacji, mówiącego, żc inicjujemy tabelę niekompatybilnymi elementami. Elementy w pamięci programu domyślnie są typu const. Opis, co :o oznacza, znajduje się w oddzielnej ramce
Przykład: listing 97
Jednak inicjowanie takiej tablicy wymagałoby więcej pisania: w naszym przypadku nawiasy klamrowe obejmują wszystkie teksty danego języka; w przypadku odwrócenia indeksów, obok siebie pisalibyśmy te same napisy dla różnych języków i konieczne byłoby każdorazowe ich objęcie klamrami. Rzeczywiście dla tabeli 2x2 nie widać różnicy, jednak zwykle w programie różnych tekstów
// Tablica wszystkich posiadanych napisów // LjęzykJ LtekstJ
const prog_char* langsys_strTabie[2] [2] PROGMEM = 1
ł
EN_strDisplay,
ENstiStart
I.
{
PL_strDisplay,
PL strStart I
};
Listing 99 -jimkcje podając? dane dla wybranego języka (langsys.c)
/i Pobieranie wskaźnika na informację o znakach specjalnych LCD_LOCAL_PGM* langsys.GetSoec (void)
{
return (LCDLOCALPGM^pgmreadwcrdnearC&langiysledspee [langsys sel]) ;
// Pobieranie wybranego napisu próg char* langsys_GeUext(uint8 l index)
{
return (próg char*)pgm read \vord ncar(&lanesvs strTable[lanesvs sel] [index]) ;
>
Elektronika dla Wszystkich Czerwiec 2006 39