cz6

cz6



Programowanie

Programowanie

Przy tw

orzeniu wyrażeń warunkowych dla dyrek-

ratorów C.

Możemy porównywać, mnożyć, dzielić.

rować możi

;my tylko na wartościach stałych - takich

które znane

są w czaśie kompilacji.

ffifdcf, ffifndef

W pewien sposób, oddzielnymi dyrektywami są tytułowe difdef, Sifndef. Mieliśmy okazją już dziśiaj z nich


ABC... C

Kompilacja warunkowa jako sposób na zwiększenie uniwersalności kodu

Na samym początku przypominam, aby wyjaśnić wszelkie wątpliwości, że wszystkie instrukcje zaczynające się znakiem hash (#) są dyrektywami preprocesora. Niektóre z nich mogą w szczególności odnosić się do kompilatora. Jednak w żądnym razie nie tworzą i one części programu wpisywanego w. procesor. Nie mijając się daleko z prawdą, można pówiedzieć, że dyrektywy te tworzą program dla naszego kompilatora - pozwalają nam sterować przebiegiem kompilacji.

#if, #elif, #else, Sendif

Wymienione powyżej dyrektywy są bardzo podobne w swojej składni do instrukcji warunkowej C. Podstawowy przykład wykorzystania pokazuje listing:

#if STALA<2

// Wersja 1 programu ■ #elif STALA<100

// wersja 2 programu

#else

// wersja 3 programu

#endif

Zestaw takich instrukcji umożliwia skompilowanie różnych wersji programu dla różnych wartości stałych. Można wyobrazić sobie takie napisanie funkcji obsługi wyświetlacza, aby możliwe było przełączenie -za pomocą jednej .Stałej między trybami: sterowania wyświetlaczem podpiętym, tak jak na naszej płytce, a podpiętym do Szyny -'danych. Konieczne byłoby; umieszczenie między dyrektywami -#if, ftelif, ffendif różnych wersji funkcji niskiego poziomu.

korzystać. Okazuje Się, że w instrukcjach kompilacji warunkowej mamy: możliwość sprawdzenia, czy dana stała została- zdefiniowana, podjęcia w zależności od tego odpowiednich stałych. Definicja w stylu:

#define NIC

jest jak najbardziej prawidłowa (wszystkie wystąpienia identyfikatora NIC w kodzie zostaną zamienione... na nic - zostaną po prostu usunięte). Pamiętaj ó tym -takie działanie czasami się przydaje.

Jednak to. na co cheę teraz zwróctć uwagę, to fakt, że dokonanie takiej (oraz każdej innej) definicji stałej może być wykryte za pomocą instrukcji #ifdef i #ifndef.

Przy tworzeniu wyrażeń można korzystać ze słowa kluczowego defined. Zwraca ono TRUE, jeśli dana stała jest już zdefiniowana. Tak więc #ifdef i ffifndef mogą być zastąpione przez, odpowiednio:

#if defined NIC #if !defined NIC

Słowa defined można używać także w złożonych warunkach.

Jak zwykłe - wszystko będzie stawać sięnoraz jaśniejsza przy wprowadzaniu tego W' życie.

Listing 41 - nagłówki w i2c.c

łinclude <avr\io.h> rinclude einttypes.fi>

#include „harddef.h,, #include „makra.h„ #incJude „i2c.h„


Listing 42 - opóźnienie połówkowe w i2c.c #defi ne lżc_nhalf CF_cpu/i2c_SPEED/2) // Funkcja dłuższych opóźnień


nop();

#eise

Wdefine l2c_delay1oops (l+(l2c_nha!f-8)/3)

#if !2c_deJayloops > 255

#error Przyspiesz - bo sie nie wyrabiam ;) ffendif

static void i2o_xdelay(void)

asm volatile( \

„delayus8_1oop%=: \n\t„\

„dec %[ticks] \n\t„\

„brnę deiayus8_1oop%= \n\t„\

: : [ticks]„r„fl2c_dełayioops) );

#endif //I2c_nhalf >= 3

// opóźnienia dla i2c

static inline void i2c_hdeiay(void)

{

#if I2C_nhałf < 1 return;

#eiif l2C_nha1f < 2 N0P();

^ selif I2C_nhaJf < 3 asm voiatile(

„rjmp exitX=\n\t„


S=:\n\t„:: i2c_xdeJayO;


„odklepanie sprawy i zapomnienie o problemie”. Spróbujemy stworzyć coś bardziej uniwersalnego.

Powiedzmy sobie najpierw o tym, jak od strony programu będzie wyglądała transmisja jednego baj tu. Sprawa jest prosta:

1.    Między warunkami START i STOP, w przerwie między bajtami, linia zegara znajduje się w stanie niskim.

2.    Zmieniamy stan linii danych i odczekujemy połowę okresu wynikającego z szybkości transmisji - odczekanie pewnego czasu jest konieczne przed wygenerowaniem narastającego zbocza zegara.

3.    Generujemy impuls wysoki na linii zegara o czasie trwania równym pozostałej nam połowie okresu.

4.    Możliwy jest natychmiastowy powrót do punktu 2 - na magistrali nie trzeba podtrzymywać danych.

Jak łatwo zauważyć, konieczne będzie obliczenie występującego wyżej połówkowego opóźnienia. W praktyce, aby transmisja mogła przebiegać z pełną szybkością, na potrzebę warunków START i STOP można stworzyć oddzielną funkcję o opóźnieniu „ćwiartkowym”, jednak w tym przykładzie spowolnimy odrobinę szybkość działania magistrali, uzyskując w zamian uproszczenie kodu. Konieczne opóźnienie możemy obliczyć ze wzoru:

n = ( F_CPU - X ) / I2C_SPEED / 2

Uzyskamy wynik bezpośrednio w cyklach maszynowych. F_CPU jest stałą dołączaną z poziomu pliku makefile, I2C_SPEED zdefiniowaliśmy na listingu 38. Zapytanie może wywołać X. W tym miejscu powinna pojawić się liczba cykli, jakie zajmuje procesorowa zmiana stanu linii danych. W najprostszym przypadku możemy ją pominąć. Wpływ tej wartości jest widoczny jedynie dla prędkości transmisji porównywalnych z częstotliwością pracy mikroprocesora. W takim przypadku nasze obliczenia i tak obarczone będą dużym biędem - zmiana stanu linii to nie wszystko czym musimy się zająć.

I2C - funkcja opóźnienia połówkowego

Stwórz i dodaj teraz do projektu plik i2c.c oraz i2c.h. Plik nagłówkowy pozostawimy chwilowo pusty i zajmiemy się plikiem źródłowym.

Na początku dołączamy wszystkie potrzebne nagłówki - patrz listing 41.

Po tej czynności obliczymy niezbędną wartość opóźnienia oraz stworzymy odpowiednią funkcję. Zależy nam na tym, aby obliczanie opóźnienia oraz wybór odpowiedniej wersji funkcji odbywał się automatycznie. Informacje przydatne do zrozumienia tej części kodu znajdują się w trzech kolejnych ramkach:    „Kompilacja

warunkowa jako sposób zwiększenie uniwersalności kodu”, „Funkcje static i inline” oraz „Generowanie własnych błędów i ostrzeżeń”. Kod przedstawiam na listingu 42.

Listing ten może wyglądać na skomplikowany. Zatrzymajmy się na nim przez chwilę. Jeśli przeczytałeś wspomnianą na początku dokumentację (avr300), po krótkim przyjrzeniu kod wyda się znajomy. W istocie jest to przepisany na C umieszczony w dokumentacji opis generowania niezbędnego opóźnienia. Wprowadzone zostały jedynie niewielkie poprawki dostosowujące kod do poznanej do tej pory części języka C. Pierwsza linia nie powinna budzić wątpliwości - odpowiedni wzór pojawił się w poprzednim śródtytule. Dalszą część łatwiej jest zrozumieć, analizując kod od końca. Funkcja i2cjidelay będzie wywoływana wszędzie tam w programie, gdzie potrzeba opóźnienia połówkowego. Jest to funkcja rozwijalna w miejscu wywołania. W pierwszym przypadku (opóźnienie mniejsze niż jeden cykl) kompilator powinien wszystkie jej wywołania pominąć. Zauważ, że reszta przypadków została zoptymalizowana w taki sposób, żc umieszczenie w kodzie programu odniesienia do funkcji spowoduje dodanie tylko

Elektronika dla Wszystkich Grudzień2005 45


Wyszukiwarka

Podobne podstrony:
Próg. przy Ograniczeniach dowolne wyrażenia i zmienne algebraiczne oraz logiczne, ang. Constraint Pr
Resize of#1 Przełącznik programów przełączania biegów Program wykorzystywany do jazdy w normalnych w
M$4 244 Andrzej Zero - Mathead 7.0 Na rysunku 7.70 przedstawiono rysunek wstawiony do programu przy
142 jpeg I I Sterowanie programowe w funkcji przebiegu procesu sterowniczego: Warunki włączenia kro
220 221 220 Rys. 6.1. Koszt urządzeń cy..,../wych budowanych jako układy konwencjonalne i jako progr
220 221 220 Rys. 6.1. Koszt urządzeń cy....nwych budowanych jako układy konwencjonalne i jako progra
cz6 ProgramowanieWuj/yjjJUY/yjjly jj/uca^jj^uww dmqq©    c* harddef.h makra.h am, gd
cz6 ProgramowanieABC... C Co I Jak umieścić w nagłówku Pliki nagłówkowe możemy, dla własnych potrze
cz6 Programowanie dodawanie przed nazwą funkcji nazwy pliku oraz znaku podkreślenia. Mogą być to za
cz6 Programowanie lif opóźnienie > 2‘. ABC... C Generowanie własnych błędów i ostrzeżeń Gdy
cz6 ProgramowanieABC... C Funkcje statlc i inllne Funkcja statyczna Umieszczenie przed nazwą jiunkc
cz6 Programowanie wyglądać jak w ramce obok: Pole SRC powinno za- wierać
33 □ LEKCJA 34 Struktura programu w C++ ( deklaracje, stałe, zmienne, wyrażenia
INSTRUKCJA PROGRAMOWANIAUWAGA! Przy wczytywaniu pierwszego pilota (pierwsze instalowanie systemu) na
5 lub będą rozwijane albo wewnątrz współpracy bilateralnej, albo wewnątrz ESA Earth Watch program pr

więcej podobnych podstron