Programowanie
dodawanie przed nazwą funkcji nazwy pliku oraz znaku podkreślenia. Mogą być to zarówno duże, jak i małe litery. Dla porządku staraj się jednak przyjąć jedną wersje w obrębie całego programu. Stwórz plik Icd. c i skopiuj do niego napisane przy okazji zeszłego kursu funkcje obsługi wyświetlacza. Przyjęty sposób oznaczań wymaga zmiany nazw wszystkich znajdujących się tutaj funkcji wyświetlacza. Pomocna w tym przypadku będzie komenda „Edit->Replace” Programmers Notepada. Nie pozwalaj jednak na w pełni automatyczną zamianę, ponieważ w ten sposób pozmieniasz
także nazwy wszystkich stałych. Nie ma tego dużo, dlatego też sprawdzenie każdej proponowanej zmiany nie zajmie dużo czasu.
Przyjrzyj się listingowi 39. Ramkami zaznaczyłem miejsca gdzie dodane zostały nowe elementy. Wprowadzone zostały obie funkcje piszące tekst, które utworzyliśmy ostatnio. Dodatkowo utworzono funkcję wypisującą podaną liczbę. Jej działanie opiera się na funkcji itoa, którą opisuje odpowiednia ramka.
Poza tymi drobnymi funkcjami z pliku zostały usunięte definicje komend, opóźnień
Sting 37 - plik makra.h
// Makra upraszczające dostęp do portów
łdefine NOPO {asm volatile(„nop„::);} łendif //MAKRA_H_INCL UDEO
#include cavr\io.h> łinclude <avr\pgmspace.h>
Listing 38 - plik harddef.h
interfejs I2C #define t2C_SDAPORT D #define I2C_SDA 6
łdefine I2c_sclport d łdefine I2C_SCL 5 łdefine I2C_SPEEO 100000
// Oefinlcje wyprowadzeń wyśw
#define LCD_RS 2
łdefine LCD_RSPORT b
Sdefine lcd_e 1
łdefine LCD_EP0RT B
#define LCD_DP0RT B
#define LCD_D4 4 //D5.D6.D7 k
Hf //HARDDEF_H_INCl.UDED
void lcd_home(void)
// Funkcje niskiego poziomu #define lcd_EPULSEO \
{portClcd_eport) I = 1«lcd_e; \ delay250ns(); \
PORT(LCD_EPORT) &= ~(1«LCD_E) ;}
oid lcd_sendHalf(uint8_i
data - (data & 0*0F) « PORT (LCD DPORT) -(port(lcd_dport) & ~(OxOF«LCD_D4)) | d; lcd_epulseO i
oid lcd_send(uint8_t data!
lcd_sendHalf (data»4) ; lcdsendHalf(data); delayus8(120);
data) t LCD_D4 i
oid lcd_init(void)
delaylOOus8(150);
PORT (LCD RS PORT) 4= ~(1«LCD_RS) ;
1od_sendHa1f(LCDC FONClLCDC F0NC8b); delayl00us8(41);
lcd_aendHai f (LCDC FONClLCDC FUNCBb) ; delaylOOus8(2);
lcd_sendHalf(LCDC FUNClLCDC FUNC4b); delaylOOus8(2);
// Teraz jest już 4b lcd_comitiand(DCDC_FUNC | LCDC F0NC4b| LCDC_FUNC2L|LCDC FUNC5x7); led coitmand(LCDC On5 i led_cls()J
led command(LCDC_MODE | LCDC MODER)J ^ lcd~oommand(LCDC_ON | LCDC_0«DISPLAY) i
//.Funkcje piszące
uoi d lcd_str_P(prog_char* str)
char znak;
while(0 I■ (znak-pgm_read_byte(sfcr++' lcd_data(znak);
oraz makr pomocniczych. Zamiast tego wprowadzone zostały odpowiednie nagłówki.
Definicje komend oraz wszystkich funkcji, które chcemy udostępnić na zewnątrz, znajdują się na listingu 40. Wpisz jego zawartość do pliku Icd.h.
Podczas pisania tego fragmentu programu podpierałem się dokumentacją avr300 dostępną kiedyś na stronie firmy ATMEL. Zawarto w niej informacje o realizacji programowego interfejsu I2C. Mimo że dokumentacja ta zniknęła ze strony producenta AVR-ów, nadal można znaleźć ją za pomocą większości wyszukiwarek internetowych. Pomocna okazała się także dokumentacja przetwornika PCF8591. Wszystkie te materiały są udostępnione na Elportalu.
jest dwuliniowym interfejsem synchronicznym. Wykorzystywane linie to linia danych (SDA) oraz linia zegara (SCL). Odpowiednie wyjścia układów powinny być wyprowadzeniami typu otwarty kolektor, podciąganie linii do stanu „1” (będącego stanem spoczynkowym) odbywa się za pomocą zewnętrznych rezystorów (rzędu 4,7k£2). W sieci tworzonej za pomocą interfejsu I2C istnieją dwa typy urcądzeń: urządzenia MASTER (nadrzędne) i SLAVE (podrzędne). To MASTER inicjuje transmisje, wybiera układ oraz przesyła do niego dane. SLAVE może wysterować linię danych, tylko jeśli otrzyma odpowiednie polecenie. Tylko MASTER może generować sygnał zegarowy.
>id lcd_dataCuint8_t
data)
1«LCD_R
yoi d lcd_str(char* atr)
while(n0iti- (znak - *(=tr++)) ) lcd_data(znak);
Listing 40 - plik tciLh
#ifndef lcd_h_incluoed #defi ne lcd_h_incluoed
U Komendy sterujące tfdefi ne LCDC_CLS łdefine LCDC_HOME łdefine LCDC_MODE
#define lcdc_moder
łdefine LCDC_M0DEL #define LCDC_MODEMOVE łdefi ne lcdc_on
#define lcdc_ONDISPLAV #define lcdc_oncursor łdefine lcdc_onblink łdefine LCDC_SHIFT
łdefine LCDC_SHIFTDXSP #de fi ne LCDC_SHIFTR
#define 1_CDC_SHIFTL #define LCDC_FUNC
łdefine LCDC_FUNC8b łdefine LCDC_FUNC4b łdefine LCDC_FUNC2L łdefine lcdc_func1l łdefine LCDC_FUNC5xl0 (łdefine LCDC_FUNC5x7 łdefine LCDC_CGA łdefine lcdc_DDA
// Deki ar void iod_
void
void
void
-acje funkcji comnand(uint8_t <
VOid icd_sr.tr p(prog_char* stx)| void icd si-(char* ser); void icc_dec(int val);
łendif /./LCD_H_INCLUDED
Elektronika dla Wszystkich Grudzień2005 39