Zauważ, że pojawiają się tutaj dwa nowe napisy IDSjCnt oraz IDS Huld Listing 127 pokazuje napisy w wersji polskiej - wprowadzamy je do pliku Polski Ji. Wersja angielska powinna być napisana analogicznie. Przypominam, że dodając nowe napisy, musisz umieścić odpowiednie zmienne w tablicy w pliku langsys.c oraz dodać wyliczenia w pliku langsys.h zgodnie z opisem w części 10.
Program powinien w tej chwili pozwolić się skompilować, a po wpisaniu do procesora, wybraniu języka i odczekaniu przez czas, jaki wyświetla się przywitanie, będziemy mieli możliwość testowania klawiatury.
W moim przypadku program po skompilowaniu zajął prawic 4kB - nie powinno nas to dziwić, biorąc pod uwagę fakt, że korzystamy z funkcji printf. Program doprowadzony do tego poziomu udostępniony zostanie na mojej stronie autorskiej możesz go wykorzystać, gdyby pojawiły się jakieś probiemy.
Często zdarzy się, że będziemy potrzebować odliczenia odcinka czasu. Zamiast testować
wciąż w pętli zmienną sys-temjdehy, przerzucimy to zadanie na system. Sztuka polega na tym, aby po odliczeniu zadanego czasu do kolejki trafił odpowiedni komunikat. Ponadto timery zbudujemy w taki sposób, że będą one umożliwiać zarówno jednorazowe wygenerowanie komunikatu, jak i pracę ciągłą. Listing
128 pokazuje proponowaną strukturę przechowującą stan trzech timerów. Listing
129 pokazuje natomiast funkcje służące do ich sterowania - konfiguracji oraz zerowania. Funkcje te deklarujemy w pliku system.li zgodnie z listingiem 130. Do przerwania timera systemowego dodajemy kod widoczny na listingu 131. Widać tutaj, że komunikat timera jest wysyłany, gdy zliczana przez niego wartość spadnie do 0. Zadanie kończy dodanie do pliku system.h komunikatów widocznych na listingu 132 - timery są gotowe do działania.
Procedury obsługi menu umieścimy w module systemu. Zacznijmy od stworzenia potrzebnych nam typów danych. Przejdź do pliku sys-
ABC... C
Instrukcja goto oraz etykiety
Instrukcja goto w C działa zgodnie z tym, czego można się po niej spedziewać - powoduje wykonanie skoku pod podaną etykietę. Wygląd samej etykiety też raczej nas nie zaskoczy jest to identyfikator zakończony dwukropkiem.
tcm.h i umieść w nim informacje z listingu 133.
Listing 134 pokazuje najważniejszą dla menu funkcję, której celem jest jego wyświetlanie oraz obsługa. Brakuje jeszcze możliwości wywoływania pozycji menu - możliwe jesl jedynie przesuwanie kursora. Przyjrzyj się wykorzystaniu programowego timera do zmiany kierunku przesuwania kursora po pewnym czasie nieaklywności. Odpowiednie fragmenty oznaczyłem żółtym tłem. Stała MENU CHANGEDIR powinna zawierać czas, po jakim nastąpi odwrócenie kierunku, wyrażony w dziesiątkach ms. Musi on być dłuższy niż czas wyznaczający długie przytrzymanie klawisza. W przykładowym programie został on dobrany na 1,1 s.
Jednak w C zasięg utworzonej etykiety kończy się w zakresie nawiasów klamrowych. Nie można wykorzystać instrukcji goto, aby wskoczyć z jednej funkcji do innej. Nie można też wskcc/yć z zewnątrz do wnętrza ciała pętli. Jest to wygodna zasada nic musimy pamiętać, aby tworzonym etykietom nadawać unikalne w skali programu nazwy.
Przykład: listing 134
Widoczne na listingu 134 komendy, których nie znamy, to odpowiednio zdefiniowane komendy przycisków' listing 135 wyjaśnia ich tajemnicę.
Funkcja systemmenu korzysta jeszcze z trzech funkcji, których do tej pory nie utworzyliśmy - listing 136 pokazuje funkcję rysującą na wyświetlaczu wszystkie widoczne pozycje menu. Poza samym uchwytem na tablicy tworzącej menu, przyjmuje ona indeks pierwszej widocznej pozycji.
Ze względu na małą ilość miejsca, spośród funkcji przesuwania się przez menu, na listingu 137. pokazuję jedynie bardziej skompliko-waną system jnenuDovm. Zadaniem obu jest wygenerowanie nowej pozycji kursora oraz
Listing 126 - aplikacja testująca klawiaturę
VOid app_run(void)
uintl5_t a, hold»0;
// wyświetlenie przywitania lcdcisC);
fputs_p(langsys Getrext(lDS_Start), lci_GetrileO); lci_update O;
// odczekanie ls sy3tera_delayMake(100);
// usunięcie wiadomość z kolpjki // (przycisk w czasie czekania?) systerr nsaClearO;
a * 100;
// Ustawienie repetycji systf»m_kbdSatRepeat£peed(l);
// Wyświetlanie stanu przycisków for(;;)
I
uint0_w msyj
// wypisanie informacji
lcd_cisO;
fprir.t:_P(lcd_GetFileO,
langsys_GetText(lDS_Cnt), a); icd_GoTo((J, 1); fprintf ?(lcd_GetFi leO,
langsys GetText(Tns_Holó), hołd); led UpdateO;
// czekanie na komunikat msq «■ 3yst-.fim_ms3Kait.F0r () ;
SWltch(msg)
{
case icm_swup: case idm_swup_rep2at:
++a;
break;
case idm_swl>ijwn; case :dmjdWdown_repeat:
-a;
break;
case 1dm swu p hcld:
■H-hoić;
break;
case idm_swdown_hold:
-hołd;
break;
1
ł
>
Listing 127 dodane teksty, ję/yk polski
prog_char PL__strCnt[] = „Licznik: %d“; prcg~cnar PL~strHola[] = „Przytrzymano: fcć“;
Listing 128- timery programowe
static struct systemjtimer
{
uint8_t modę; irnt8_t start; uint8_t ent; }systGni_timer [3] ;
Listing 129
- funkcje sterujące programowymi linie ram i
void systcm_timer3et(uint8_t timer,
uintO t modę, uint.8 t start, uint8_t init)
{
// zabezpieczenie przed przerwań-pm cii O;
// inicjacja timera
system_ti-nfir [timor] . start. - start; sysffini_timer [timer] . ent - init; systerr._timcr[timer] .modę * modę; cci O;
inline vo1d system timerReset(u-nrR_t timer) {
cli O;
system_t.i mer [timer] .ent -
system_timer[timer].start; saiO ;
>
Listing 130- de li nic ja funkcji timerów w system.h
#define SYSTEM_TIMER_MODE5TOP 0 #define SYSTEM_TIMER_K)DEPREERUN 1 #define system_timer_^odeonfshot 2
VOid system_tim9rSer(uirt8_t timer,
Uint8_t modę, uint8_- start, uiul.8_t Init); inline void systcm_timerRestjL(ulnt8_t tirrer);
44 Sierpień 2006 Elektronika dla Wszystkich