Image36 (8)

Image36 (8)




Programowanie



ła funkcja pomocnicza Icd LineStart, która przyjmuje numer linii, a zwraca adres jej początku w wyświetlaczu. 7 funkcji tej będziemy jeszcze korzystać. Zauważ, żc została ona stworzona w taki sposób, aby zmieniała się w zależności od zdefiniowanej liczby linii wyświetlacza Jeśli liczba linii nie będzie odpowiadała żadnej ze znanych - zostanie zgłoszony błąd. Przyjrzyj się algorytmowi przeliczającemu pozycję na adres w pamięci modułu alfanumerycznego. Przypominam, ze znak ‘%' oznacza resztę z dzielenia.


Listing 76

Deklaracja i definicja funkcji pat wyświetlacza

static int lcd put(char c, file* f)

{

// zabezpieczenie przed przepełnieniem

if(.lcd_curpo.«? >= F.T.F.MS(lcd_buffer)) lcd curpos = 0;

// Zapfs do bufora

lcc_buf fer [Lcd_curpoa++] =* ej

return 0;


Zmienna przechowująca „ogonki”

Otwórz plik led.h. Zanim przejdziemy dalej, wprowadzimy tutaj definicję struktury LCD_LOCAL. Umieścimy ją w pliku nagłówkowym, ponieważ sama deklaracja wyglądu znaków specjalnych pojawi się poza modułem lcd. Listing 81 przedstawia deklarację potrzebnej nam struktury. Pamiętaj, żc analogicznie do pliku harddcf.h, deklarację tę, razem z dołączeniem plików nagłówkowych, należy umieścić między odpowiednimi komendami #ifndef oraz #endif. Nadawana jest nazwa


pomocne przy ustawianiu kursora. Funkcja IcdJdoToAdr ustawia kursor wewnątrz procesora, ale nie ma wpływu na jego pozycję bezpośrednio na wyświetlaczu. Dopiero funkcja IcdJJpdateCurPos odwzorowuje pozycję kursora w module LCD. Wprowadzona zosta-

Usting 75

Funkcje niskiego poziomu obsługi wyświetlacza

#define lcd_epulse() \

{fokt(lco ctkl?ort) |= 1«lcd_e; \ _delay_us(0.2 5); \

PGR?(LCD CTRLPORT) ~(1«1CD_E);>

/ j odbiór danej - funkcja wewnętrzna static inline .iłntf r l rd nat(void)

{

uint8_t dana;

// ustaw-enie portu lcd jako wejścia

dfr(lcd_datapcrt) - OxOC;

// Aktywacja odczytu PCRT(LCD_CTRLEORT) |* 1«LC3_EJ deiay us(0.5);

7/ Skopiowanie danych z wyj. modułu

dana ■ PIN(LCDJ)ATAPORr);

// Deaktywacja wyjęcia FNARl F por?(lcd_ctrlport) &*= ~(1«lcd_e); return dana;

ł

uintti t lcd Get3F(void)

( ”

// Wyprowadzenia do odczytu statusu PORT Clcd_ctrl port) |- 1«lcd_rw; port(lcd ctrlport) &= ~(1«lcd_rs):

// Odczekanie wymaganego czasu _dcLay_ue(0.25);

7/ Odczyt danej return lcd c-cl();

ł

// Czeka ra wyzerowanie flagi zajętości

void 1cd_Wa i t B F(voi d)

{

// Rit zajętości to bit najstarszy whileCO I- (0<80 A Lcd_GetRFO ) ) 1};

)

// wysłanie danej - funkcja wewnętrzna

static void l~d_send(uint3 t dana)

{

// Ustawienie portu lcd jako wyjęcia

DDR(LCD_DATAPORr) - 0>FF;

// Przesłanie na port danej

PORT(l,CD_nATAPORT) ■ dana;

// Przesłame do łcd lcd_epul3e();

ł

// wysłanie darej

V0id lcd Send0ata(uint8 t dana)

{

lcd_Wait3FO;

// Wyprowadzenia dla zapisu danej P0RT(LCD_CTPI,30RT) Arn ~(1«LCD_RW);

port(lcd_ctrl?ort) I* 1«lcd_rs;

// Odczekanie oraz wysłanie _delcy_us(0.25); lcd_Send(dana); i

// wysłanie instrukcji sterującej

V0id lcd Sendlr.str(uint8 t dana)

{

lcd_Wa-tBF();

// Wyprowadzenia dla zapisu instrukcji port(lcd_ctrlport) A~

~(l«LCD PW I 1«LCC_RS);

// OdczekanTe oraz wysłanie _aelay_us(0.25); lcd_Senć(dana);

nowemu typowi zmiennej LCD LOCAL PGM, która jest naszą strukturą umieszczoną w pamięci programu. Aby możliwe było wykorzystanie makra PROGMEM, dodajemy plik nagłówkowy <avr/pgmspace>. W tej chwili są to wszystkie dane. jakie wprowadzamy do pliku led.h.

Listing 77 - Inicjacja wyświetlacza.

void lcd Init(void)

{

lcd_cis();

fortClc^ctrlport) &=

_del<ły_ts (0. 25); lcd_senć(LCOC func | delay_ms(4.35; lcd SencCLCDC FUNC |

_delay_us(200); lrd_Senć(LCDC_FUNC |

// Już nożna sprawdzać RF #if LCD_SY == 1

lcd_3endlnstr(LCDC_FUNC | LCDC_FUNC8b | LCDC_FUNC1L); #else

lcd_sendinstr(LCUC_FUNC

Jendif

lcdSendlnstr(LCDC ON); lcd_3endInstr(LC0C_CLS); lcd”spru1Tn.sr r(LCDC_NODE | LCDC_MODER) lcd WaitBF();


■ ~(1«LCC_RW | _«LCD_RS) LCDC_FUNC8b)J LCDC_FUNC8b);

LCDC FUNC8b);


LCDC FUNC8b | LCDC FLNC2L);


ABC... C

Propozycja na opóźnienia: delay.ms oraz delay us

W bibliotece avr- ibc, w pliku <util/delay h> znaj-dąją się dwie tytułowe funkcje służące do wygodnego generowania opóźnień. Ich wykorzystanie nie daje nam takiej kontroli nad czasem opóźnienia, jak w przypadku samodzielnego napisania pętli, jednak tam gdzie nic jest ważne bardzo dokładne obliczenie czasu, są one wyjątkowo wygodne w zastosowaniu.

Obie funkcje przyjmują jako argumen: wartość typa double (zmiennoprzecinkową!!, która oznacza żądane opóźnienie w mili- lub mikrosekundach. Tutaj niektórych może ogarnąć słuszna zgroza: wykorzystanie arytmetyki zmiennoprzecinkowej po to, aby wygenerować opóźnienie, wydaje się dużą przesadą. Jednak funkcje tc zostały napisane jako statyczne funkcje typu Inllne. Oznacza to, że działają one trochę jak makra - są rozwijane w miejscu wywołana. Teraz, jeśli argument będzie wartością stalą (!), jako wartość stała pojawi się w rozwinięciu. Ponieważ reszta wartości w chlic/eniach jest wartościami stałymi, m całe


ohliczenie zostanie wykonane laetap.e kompilacji programu - procesor nie będzie wykonywał żadnej operacji zmiennoprzecinkowej.

Opóźnienia są obliczane z uwzględnieniem prędkości oscylatora, klotu została zdefiniowana w pliku makefile. Ważne jest jednak, aby pamiętać o tym, że obie funkcje mają pewną maksymalna wartość opóźnienia, ja<ą są w stanie wygenerować.

Funkcja rielayim jest w stanie wytworzyć opóźnienie o maksymalnej wartości równe 2ó2.14ms / F_CPU, gdzie F CPU oznacza częstotliwość zegara w megahercach. Funkcja delayus może zająć procesor na nic dłużej liż 768us / K_CPU, gdzie F CPU jest także liczone w' megahercach.

Funkcje zostały napisane w taki sposób, żc możemy mieć pewność, iż wygenerowane zostanie opóźnienie nie krótsze niż zadane Wyjątkiem jest przekroczenie maksymalnego zakresu - wtedy wygenerowane zesłanie maksymalne możliwe opóźnienie.

Dzięki temu, że funkcje opóźnień do icj pory pisaliśmy samemu, powinieneś być w stanic zrozumieć kody zawarte w pliku <util/deiay.łi>. Zachęcam Cię do ich przejrzenia

Przykłady: hs/uig 75 oraz 77


Elektronika dla Wszystkich Maj 2006 45


Wyszukiwarka

Podobne podstrony:
Image38 (5) Programowanie ABC... C Funkcje Stworzenie nowej funkcji w C jest bardzo prosie. Tak napr
Image35 (9) ProgramowanieFunkcje niskiego poziomu Za definicją zmiennych umieścimy definicje funkcji
Image293 Możliwe jest wykorzystanie funkcji pomocniczych wyższych poziomów. Sposób ich tworzenia jes
Image3045 gradf -(lA-I-l^gradfOĄ)
Image3449 Ponieważ W(0,0) 2 0 3 -4 = -8 < O, to funkcja f niema ma w punkcie (0,0) ekstremumlokal
Do EAX lub RAX wpisujemy numer kolejnej funkcji systemowej - sys_exit, która spowoduje zamknięcie na
Zeszyt Cwiczeń FUNKCJI POZNAWCZYCH 3 (10) Powiedz, którą godzinę wskazuje zegar.
Foto3 ZADANIE „Uniwersalny fianik*_ W bloku funkcyjnym zopisoć program reoll2ujqcy funkcję Rczniko.

więcej podobnych podstron