Listing 71 Makro obliczające ilość elementów tablicy. #define ELEMS(p) (sizeof(p)/sizeof(p[0]))
Listing 72 - „pusty"plik nagłówkowy hurddef.h
Dziś w dużej mierze będziemy wykorzystywać poznane do tej pory informacje o C. Chcę opowiedzieć Ci o tym, jak dostać się 7 poziomu danego pliku (modułu) do zmiennych, które zdeklarowaliśmy zupełnie gdzie indziej. Dowiemy się więcej o tym, jak kompilator rozumie zmienne oraz funkcje globalne. Dodatkowo korzystać dziś będziemy z możliwości, jakie daje najnowsza wersja WinAVR.
Jeśli chodzi o program - chcę pokazać dziś coś oryginalnego. Będzie to propozycja znacznie bardziej zaawansowanej obsługi wyświetlacza alfanumerycznego niż to. czym zajmowaliśmy się do tej pory. Proponowany moduł postanowiłem nazwać szumnie: „obsługa wyświetlacza alfanumerycznego z dynamicznym przydzielaniem znaków specjalnych”. Jednocześnie, z niemałą satysfakcją, pozwolę sobie wyjść poza tematykę realizowaną przez środowisko BASCOM-a „za pomocą jednej instrukcji”.
Najnowsza wersja YVinAVR w chwili pisania tego artykułu pochodzi z końca stycznia 2006 roku Informacje o najważniejszych dla nas, zmianach umieszczam na swojej stronie {wyvw.elportal.pl/n0017). Przypominam tam także sposób instalacji
Nowy projekt nazwałem LCDdynamic. Pamiętaj o takim zmodyfikowaniu pliku makefile, aby głównym plikiem źródłowym projektu był main.c, a nie LCDjdynamic.c. Zmiany takiej dokonywaliśmy już w części 6 przy okazji tworzenia programu składającego się z wielu plików.
Z części 6 zaczerpniemy także utworzony wtedy plik makra.h. Przenieś kursor prawie na koniec pliku - tuż powyżej zamykającej całość instrukcji preprocesora *tendif wpisz kod z listingu 71. Dodane właśnie makro ma na celu obliczenie liczbę elementów tablicy niezależnie od rozmiaru każdego pola. Jego działanie polega na podzieleniu rozmiaru całej tablicy przez rozmiar jednego elementu. Wzmianka o makrze ELEMS, wraz z dokładnym opisem działania, pojawiła się wr części 6.
Utwórz plik harddefh oraz dodaj go do projektu. W tej chwili plik może być pusty -
odpowiednie definicje będziemy wprowadzać tutaj podczas tworzenia programu. Ważne jest jednak, aby plik istniał, co umożliwi nam jego dołączanie do plików kodów źródłowych.
ABC... C
Uwaga. Przyzwyczaj się, aby przez „pusty plik nagłówkowy’’ rozumieć laki plik. w którym znajdzie się jedynie komentarz informujący o przeznaczeniu pliku ora/ ubimią/ktmo kod / Ihtingu 72. Nic piszemy kodu poza ooszarem wyznaczonym przez komendę MJhdef oraz tiendif.
Przechodzimy teraz do najważniejszego dzisiaj modułu - modułu obsługującego wyświetlacz. Utwórz pliki Ica.c oraz led.h. Pamiętaj o dodaniu obu plików do projektu w Programmers Notepadzic.
Plik icd.c koniecznie dodaj do plików źródłowych wypisanych w pliku makefile. Jest to dobry moment, aby popraktykować samodzielne wykorzystanie wiedzy z części 6. Sięgnij tam śmiało, jeśli będziesz miał jakiś problem.
Trzymając się dobrych zwyczajów, umieść teraz w obu plikach krótkie komentarze opisujące ich funkcję. W pliku nagłówkowym dodatkowo obowiązkowo wprowadzamy kod analogiczny do widocznego na listingu 72. Odpowiedniej zmianie ulegnie jedynie definiowana nazwa: zamiast HARDDEF_H_ INC LUDĘD wprowadź LCDHINCLU-DED.
Zajrzyj teraz na początek kodu zawartego w pliku Icd.c widocznego na listingu 73. Aby nie zajmować się tym już później, do pliku od razu dołączmy większość potrzebnych nagłówków. Ja w tym przypadku po prostu wiem, co jest potrzebne, ponieważ mam ukończony kod. Pamiętaj jedynie, źc często pliki nagłówkowe dodaje się w miarę potrzeb, w czasie pisania kodu.
Ponieważ jedną z idei zaawansowanej obsługi LCD jest to, aby reszta programu nic miała dostępu bezpośrednio do wyświetlacza, komendy sterujące zdefiniujemy bezpośrednio tutaj, a nie tak jak poprzednio w odpowiednim pliku nagłówkowym.
Po definicji stałych deklarujemy od razu funkcję led_put. Funkcja ta będzie wpisywać do bufora jeden znak. Jest to funkcja dla operacji strumieniowych. Jej definicję utworzymy później.
Powyższa deklaracjo jest nam niezbędna przed definicją zmiennych. Tworzymy zmienną typu FILE oraz inicjujemy ją podobnie jak udało nam się to zrobić w poprzedniej części. Teraz jednak korzystamy z nowej, w budowa nej w avr-libc możliwości. Zajrzyj do ramki „Nowe sposoby otwierania strumienia w avr-Iibc 1.4”. W ten sposób mamy utworzone połączenie między plikiem a strumie niem już na starcie naszego programu. Zmienna ledJLCDjemp z punktu widzenia kompi latora jest strukturą. W tiinkcjach.ę/tfio powinniśmy natomiast posługiwać się wskaźnikiem na odpowiednią strukturę. Widoczne niżej makro umożliwia nam zapomnienie o ciągłym
#ifndef harddef_h_included #define harddef_h_included
// Zawartość umieszczamy tutaj
#endif // HARDOEF_H_INCLUDED
Listing 73 - Początek kodu w pliku Icd.c.
#include <avr/io.h>
#include nttypes.h>
#inc1ude <uti1/delay.h>
#include <.string.h> finclude <avr/pgmspace.h>
#include „na^ra.h"
#include „harddef.h" tfincludp „led.h*1
//-
// Definicje stałych {/ Komency sterujące wyświetlaczem fdefine lcdc_clś 0x01
(...)
// Komendy identyczne do części S i 6 // (listingi 22 i 40)
//---
// Deklaracja funkcji piszącej static int icd_pu_(char c, file* O i
U_
// Zmienne
Static FILE lcd_fLCD temp »
FnF.V_$F.TnP_Sr,R^.AM(l edjpnt., NULL.
_fdev_setup_write); tfdcfinc lcd_fLCD (&1cd_fLCD_temp)
static char
Lcd_bufEer[LCD_SX*LCD_SY];
Static uint8 t lcd_curpos;
Static uint8_t lcd_spec[8]; static uint8_t lcd_status;
38 Maj 2006 Elektronika dla Wszystkich