Kurs AVR GCC Wyświetlacz LCD od Nokii 3310


1 z 11
Artykuł pochodzi ze strony XYZ HOBBY ROBOT (xyz.isgreat.org)
Kurs AVR-GCC Wyświetlacz LCD od Nokii_3310
26.04.11 ABXYZ
Niniejszy tekst jest dodatkiem poszerzajÄ…cym tematykÄ™
publikowanego na tej stronie kursu AVR-GCC.
Jak mówią, jeden obraz wart jest tysiąca słów, dlatego warto
zainteresować się wyświetlaczami graficznymi. W tym artykule
zajmiemy się wykorzystaniem wyświetlaczy LCD od popularnych
niegdyś telefonów komórkowych Nokia 3310/3410. Pewnie
niektórzy czytelnicy zastanawiają się, czemu nie wybrałem du\ego,
kolorowego wyświetlacza o rozdzielczości QVGA. Przede wszystkim
ze względu na cenę, szkoda montować w ka\dym urządzeniu
modułu LCD kosztujący ponad 100zł, zaś wyświetlacze od starych
komórek praktycznie nic nie kosztują i te\ są fajne:)
Wyświetlacz LCD od telefonu Nokia 3310 posiada
monochromatyczny ekran o rozdzielczość 84x48 (wymiary
czynnego pola ekranu 30x20mm). Wyposa\ony jest w sterownik
PCD8544(lub podobny) z szeregowym interfejsem SPI. Dostępny
jest wyłącznie tryb graficzny, ale mo\na łatwo programowo
zaaran\ować tryb tekstowy; przykładowo mo\na pokazać sześć linii
tekstu, ka\da po 14 znaków wielkości 6x8 pikseli.
Wyświetlacz od telefonu nokia 3310 wraz z oryginalną ramką. Identycznie wygląda
wyświetlacz od noki 3410.
Wyświetlacz od telefonu nokia 3310 wydobyty z ramki.
Wyświetlacz od Nokii3410 wygląda identycznie jak wyświetlacz od
Nokii3310, ten sam układ wyprowadzeń złącza, ale ma nieco
większą rozdzielczość: 96x65 (mo\na pokazać 8 linii tekstu, ka\da
po 16 znaków 6x8). Wyświetlacz od Nokii3410 wyposa\ony jest
2 z 11
w kontroler "Philips OM6206", który programuje się prawie w ten
sam sposób jak kontroler PCD8544 z Nokii3310. Do obsługi obu
typów wyświetlaczy będziemy wykorzystywać te same funkcje
napisane w języku C.
LCD Nokia 3310 LCD Nokia 3410
Rozdzielczość 84x48 96x65
kontroler PCD8544 OM6206
cena <10zł <10zł
Monochromatyczne wyświetlacze LCD od telefonów nokia 3310/3410
Podłączenie wyświetlacza do mikrokontrolera AVR
Wyświetlacz jest delikatnym elementem, dlatego lepiej jest
pozostawić go w jego oryginalnej ramce. Ramkę mo\na
odpowiednio przyciąć i wraz z wyświetlaczem przykręcić wkrętami
do jakieś płytki, albo przykleić.
Na tylnej stronie ramki wyświetlacza dostępne jest złącze; w
telefonie miedziane styki złącza przylegają do ście\ek na płytce
drukowanej.
Złącze na tylnej stronie wyświetlacza.
Nr
Sygnał kierunek Opis
styku
1 VDD zasilanie Zasilanie 2.7 .. 3.3 V
Serial clock. Sygnał zegarowy taktujący
2 SCLK wejście
dane na linii SDIN
Wejście danych synchronizowane
3 SDIN wejście
sygnałem SCLK
Wejście wyboru rodzaju danych
4 D/C wejście wprowadzanych do sterownika
(wyświetlane-1,sterujące -0)
Wejście aktywujące interfejs
5 SCE wejście
szeregowy(aktywny stan niski)
6 GND zasilanie Masa zasilania
Ouptut voltage. Kondensator
7 VOUT zasilanie elektrolityczny 1-10 uF między VOUT i
GND.
8 /RES input Reset LCD (aktywny stan niski)
Opis wyprowadzeń w złączu wyświetlacza od noki 3310/3410
Najprostszym sposobem przyłączenia wyświetlacza jest przylutować
przewody bezpośrednio do miedzianych styków złącza, bez
rozbierania ramki. Ale trzeba lutować szybko i zdecydowanie,
inaczej plastykowa listwa, na której osadzone są miedziane styki
złącza mo\e się pod wpływem ciepła roztopić i odkształcić.
3 z 11
Najprostszym sposobem przyłączenia wyświetlacza jest przylutować przewody do
miedzianych styków złącza, bez wyciągania wyświetlacza z oryginalnej ramki.
Wyświetlacz z przewodami przystosowanymi do podłączenia do płytki stykowej.
Wyświetlacz wymaga napięcia zasilania 2.7-3.3 VDC, zatem
najprościej jest zasilać całość: mikrokontroler i wyświetlacz
napięciem 3.3V. W takim przypadku wejścia sygnałowe
wyświetlacza mo\na podłączyć bezpośrednio do wyprowadzeń
portów we/wy mikrokontrolera. Na schematach wejścia sygnałowe
wyświetlacza połączone są do wyprowadzeń mikrokontrolera
skojarzonych ze sprzętowym interfejsem SPI AVRa atmega.
W przykładowych programach, które będziemy dalej uruchamiać,
mo\na wybrać sprzętowe lub programowe SPI; w przypadku wyboru
programowego SPI, sygnały sterujące wyświetlaczem mo\na
przyłączyć do dowolnych porów we/wy AVRa.
Schemat 1 Sposób przyłączenia wyświetlacza od nokii3310/3410 do interfejsu SPI
mikrokontrolera atmega8(88) zasilanego napięciem 3.3V
4 z 11
Nie wszystkie wersje AVR mogą być zasilane napięciem 3.3V,
schemat nr 2 pokazuje, jak mo\na podłączyć wyświetlacz zasilany
napięciem 3.3V do mikrokontrolera zasilanego napięciem 5V.
Wyświetlacz od Nokii 3310 zu\ywa minimalne ilości prądu, napięcie
3.3V do jego zasilania mo\na uzyskać stosując dzielnik napięcia:
rezystor i dioda zenera 3.3V. Na schemacie wejścia sterujące
wyświetlacza połączono z portami we/wy AVRa poprzez bufor
74ls07. Scalony układ 74LS07 zawiera sześć cyfrowych buforów
z wyjściami typu otwarty kolektor, wyjścia te zostały podciągnięte
rezystorami 330 do napięcia 3.3V.
Schemat 2 Sposób przyłączenia wyświetlacza od nokii3310/3410 zasilanego napięciem
3.3V do mikrokontrolera zasilanego napięciem 5V
Komunikacja z wyświetlaczem
Wyświetlacz od Nokii 3310 wyposa\ony jest kontroler PCD8544 z
szeregowym interfejsem SPI(Serial Peripheral Interface). Interfejs
posiada cztery wejścia:
SDIN - szeregowe wejście danych,
SCLK - sygnał zegarowy taktujący dane na linii, SDIN
/SCE - wejście aktywujące interfejs szeregowy,
D/C - wejście wyboru rodzaju danych (wyświetlane lub
sterujÄ…ce).
Komunikacja przebiega tylko w jednym kierunku, od
mikrokontrolera do wyświetlacza. Zale\nie od stanu linii D/C, bajty
danych wysyłane do wyświetlacza, mogą być interpretowane przez
kontroler jako komendy do wykonania albo dane zapisywane do
pamięci RAM obrazu; stan wysoki na linii D/C sygnalizuje daną,
stan niski komendÄ™.
Rys.1 pokazuje przebieg transmisji jednego bajtu danych od
mikrokntrolera do wyświetlacza Komunikację rozpoczyna się od
ustawienia linii /SCE w stan niski, co aktywuje interfejs SPI. Jeśli
wysyłany bajt jest komendą, linię D/C ustawia się w stan niski,
a jeśli zwykłą daną - w stan wysoki Następnie, linią SDIN,
szeregowo(bit po bicie) przesyła się 8 bitów danej, zaczynając od
bitu najbardziej znaczÄ…cego. Transmisja szeregowa jednego bitu
przebiega w następujący sposób: Wpierw na linii danych SDIN
ustawia się stan niski lub wysoki, zale\nie od wartości przesyłanego
bitu; następnie na linii SCLK podaje się impuls: 0-1-0 - kontroler
odczytuje kolejne bity danych przy rosnącym zboczu sygnału SCLK.
Zmiana na linii /SCE stanu niskiego na wysoki sygnalizuje
zakończenie transmisji.
Rys.1 Przesłanie jednego bajtu do wyświetlacza przez SPI.
A oto funkcja "lcd_write_byte" realizująca w sposób programowy
przesłanie jednego bajtu z mikrokontrolera do wyświetlacza:
void lcd_write_byte( char c_d, unsigned char data )
(unsigned , )
( , )
( , )
{
{
{
{
unsigned char m;
;
;
;
LCD_CE_CLR
if( )
(c_d)
( )
( )
5 z 11
LCD_DC_SET
else
LCD_DC_CLR
for( =0x80; m; m>>= )
(m= ; ; >>=1)
( = ; ; >>= )
( = ; ; >>= )
{
{
{
{
if( & m)
(data & )
( & )
( & )
LCD_DATA_SET
else
LCD_DATA_CLR
LCD_CLK_SET
LCD_NOP
LCD_CLK_CLR
}
}
}
}
LCD_CE_SET
}
}
}
}
Listing nr 1. Funkcja przesyłająca szeregowo jeden bajt danych z mikrokontrolera do
wyświetlacza LCD poprzez interfejs SPI zrealizowany programowo.
Pierwszy argument funkcji "lcd_write_byte" wskazuje czy wysyłana
jest komenda, czy bajt zwykłych danych (1-komend, 0-zwykła
dana); drugi argument to kod komendy lub bajt danych. U\yte w
funkcji makrodefinicje: LCD_x_SET, LCD_x_CLR ustawiajÄ… na
liniach sygnałowych stan wysoki lub niski, a makro LCD_NOP to
krótkie opóznienie w programie.
Mikrokontrolery atmega wyposa\one są w sprzętowy interfejs SPI,
który mo\emy wykorzystać do sterowania naszym wyświetlaczem.
Poni\ej znajduje siÄ™ listing drugiej wersja funkcji "lcd_write_byte",
która wysyła do wyświetlacza jeden bajt z wykorzystaniem
sprzętowego interfejsu SPI.
/**/
SPCR =(1<< )|(1<< )|(1<< );
=( << )|( << )|( << );
=( <=( << )|( << )|( << );
/**/
void lcd_write_byte( char c_d, unsigned char data )
(unsigned , )
( , )
( , )
{
{
{
{
LCD_CE_CLR
if( )
(c_d)
( )
( )
LCD_DC_SET
else
LCD_DC_CLR
SPDR = data;
= ;
= ;
= ;
while(!( & (1<< )));
(!(SPSR & ( <(!( & ( << )));
(!( & ( << )));
LCD_CE_SET
}
}
}
}
Listing nr 2. Funkcja przesyłająca szeregowo jeden bajt danych z mikrokontrolera do
wyświetlacza poprzez sprzętowy interfejs SPI AVRa atmega.
Do kontroli sprzętowego interfejsu SPI AVRa atmeaga wykorzystuje
siÄ™ trzy rejestry IO :
SPDR -SPI Data Register,
SPCR -SPI Control Register,
SPSR -SPI Status Register.
Sprzętowy interfejs SPI mikrokontrolera atmega ma szerokie
mo\liwości konfiguracji, ale do sterowanie naszym wyświetlaczem
pasują ustawienia domyślne. Pozostaje tylko wybrać szybkość
działania interfejsu SPI, tzn. częstotliwość sygnału taktującego na
linii SCLK. SÅ‚u\Ä… do tego celu bity SPR0, SPR1 rejestru SPCR(SPI
Control Register) oraz bit SPI2X rejestru SPSR(SPI -Status
Register), tabela poni\ej:
SPI2X SPR1 SPR0 SCK Frequency
0 0 0 fosc/4
0 0 1 fosc/16
0 1 0 fosc/64
0 1 1 fosc/128
1 0 0 fosc/2
1 0 1 fosc/8
1 1 0 fosc/32
1 1 1 fosc/64
Wybór częstotliwości sygnału taktującego na linii SCLK interfejsu SPI mikrokontrolera
atmega
W naszych przykładach transmisja przez sprzętowy interfejs SPI
będzie przebiegać z częstotliwością fosc/16, czyli przy częstotliwości
pracy mikrokontrolera 16MHz sygnał taktujący na wyjściu SCLK
będzie mieć częstotliwość 1MHz.
Ustawienie bitów SPE i MSTR w rejestrze SPCR(SPI Control
Register) włącza interfejs SPI AVRa w trybie MASTER. Wysłanie
6 z 11
bajtu następuje po zapisaniu danej do rejestru SPDR(SPI Data
register), a ustawiony bit SPIF w rejestrze SPSR(SPI Status
Register) sygnalizuje zakończenie transmisji.
Inicjalizacja wyświetlacza
Poni\ej znajduje się listing funkcji inicjującej wyświetlacz. Na
początku funkcji program resetuje wyświetlacz ustawiając linie
/RES w stan niski na ok 15ms, po resecie funkcja wysyła kilka
instrukcji inicjujących wyświetlacz.
/* Inicjuje wyświetlacz */
void lcd_init( )
(void)
( )
( )
{
{
{
{
LCD_RST_CLR;
;
;
;
// < 30ms
_delay_ms( );
(15);
( );
( );
LCD_RST_SET
LCD_CE_SET
lcd_write_byte( , 0x21); // Function set - extended instruction set
(LCD_CMD, );
( , );
( , );
lcd_write_byte( , 0x13); // Bias - 1:48
(LCD_CMD, );
( , );
( , );
lcd_write_byte( , 0x06); // Temperature Control
(LCD_CMD, );
( , );
( , );
lcd_write_byte( , 0xa5); // Set Vop
(LCD_CMD, );
( , );
( , );
lcd_write_byte( , 0x20); // Function set - basic instruction set, horizontal addressing
(LCD_CMD, );
( , );
( , );
lcd_write_byte( , 0x0C); // Display control - normal mode
(LCD_CMD, );
( , );
( , );
}
}
}
}
Listing nr 3. Funkcja inicjująca wyświetlacz.
Pamięć RAM obrazu wyświetlacza
Ka\demu pikselowi na ekranie wyświetlacza odpowiada jeden bit
w pamięci RAM obrazu. Ekran wyświetlacza od Nokii 3310 ma
rozdzielczość 84x48, zatem, aby zapamiętać cały obraz, kontroler
wyświetlacza potrzebuje mieć 4032 bity pamięci RAM obrazu. Bity
w pamięci obrazu pogrupowane są w komórki po 8 bitów(bajty),
zapisując dane do pamięci obrazu zmieniamy od razu cały
bajt(osiem pikseli na ekranie wyświetlacza). Niestety nie ma
mo\liwości odczytu danych z pamięci RAM obrazu :( Komórki
pamięci RAM obrazu są ponumerowane, numer komórki w pamięci
nazywany jest jej adresem. Kolejnym ośmiu bitom ka\dej komórki
pamięci RAM obrazu, odpowiada osiem kolejnych pikseli na ekranie
LCD, ALE w kierunku pionowym, LSB na górze, MSB na dole ,patrz
rys. 2. Przykładowo, jeśli gdzieś w pamięci RAM obrazu zapisana
zostanie bajt o wartości 0xff, to w odpowiednim miejscu na ekranie
wyświetlacza pojawi się pionowa kreska | o wysokości 8 pikseli,
patrz rys.2.
Rys.2 Tak mo\na wyobrazić sobie pamięć obrazu wyświetlacza od nokii 3310, widzimy
tablicę: 6 wierszy i 84 kolumny - ka\da kratka w tabeli to jeden bajt w pamięci RAM obrazu.
Dodatkowo, obok pamięci RAM obrazu, kontroler wyświetlacza
posiada rejestr: licznik_adresu. Liczniku_adresu zawiera adres
wskazujący na komórkę w pamięci RAM obrazu, gdzie zostanie
zapisany następny bajt danych wysyłany do wyświetlacza, gdy na
linii D/C występuje stan wysoki. Ka\dorazowo po zapisaniu bajtu
danych w pamięci obrazu, licznik adresu zwiększa się
automatycznie o jeden i wskazuje na następną komórkę w pamięci
RAM obrazu. Wysyłając do wyświetlacza komendy:
Set_Y_address_of_RAM i Set_X_address_of_RAM mo\na ustawić
zawartość licznika_adresu tak, aby skazywał na dowolną komórkę
w pamięci RAM obrazu.
Komendy kontrolera
Jak pisałem wcześniej, bajty danych wysyłane do wyświetlacza
mogą być interpretowane przez kontroler wyświetlacza jako
7 z 11
komendy do wykonania albo jako dane kopiowane do pamięci RAM
obrazu - zale\nie od stanu linii sygnału D/C. Bajty danych
i komendy będziemy wysyłać do LCD omawianą wcześniej funkcją:
void lcd_write_byte(unsigned char c_d, unsigned char byte )
Parametr "c_d" to stan linii D/C, parametr "byte" to wysyłany bajt
danych albo kod komendy.
Zbiór wszystkich komend wyświetlacza mo\na znalezć
w dokumentacji kontrolera PCD8544. W naszych przykładach
będziemy najczęściej wysyłać do LCD komendy
Set_Y_address_of_RAM i Set_X_address_of_RAM", \eby ustawić
zawartość licznika_adresu.
Wszystkie komendy kontrolera majÄ… rozmiar jednego bajta(osiem
bitów). Na bitach 6..0 kodu komendy Set_X_address_of_RAM
kodowana jest współrzędna X, która mo\e przyjmować wartości od
0 do 83, patrz rys.2.
1 X X X X X X X
Na bitach 2..0 kodu komendy Set_Y_address_of_RAM kodowana
jest współrzędna Y, która mo\e przyjmować wartości od 0 do 5,
patrz rys.2
0 1 0 0 0 Y Y Y
W przypadku wyświetlacza od Nokii3410 z kontrolerem OM6206
mo\na ustawić współrzędną Y na wartości 0..7, a współrzędną X na
wartości 0..96
I to jest wszystko, co potrzebujemy wiedzieć, aby wykorzystać
wyświetlacz od Nokii_3310. W dalszej części artykułu uruchomimy
kilka przykładowych programików. Wszystkie przykłady są
maksymalnie uproszczone, bo jak wiadomo, dobry przykład, to
prosty przykład:)
Przykład pierwszy. Jak wyświetlić obrazek
W programie MicroLCD narysowałem przykładowy obrazek w dwóch
kolorach, który zostanie pokazany na ekranie naszego
wyświetlacza. Obrazek ma wymiary 84x48 - zajmie cały ekran
wyświetlacza.
Przykładowy obrazek do pokazania na wyświetlaczu narysowany w programie MicroLCD.
Dane obrazka wyeksportowałem do pliku tekstowego "hello_img.c",
wybierajÄ…c w menu programu MicroLCD opcjÄ™:
File->Export (.C hex file)
Plik z danymi obrazka zostaje dołączony do programu instrukcją
preprocesora #include "hello_img.c", dane obrazka trafiÄ… do tablicy
typu char.
unsigned char hello_img[] PROGMEM = {
[] = {
[] = {
[] = {
#include "hello_img.c"
};
};
};
};
Słówko PROGMEM w deklaracji tablicy decyduje, \e tablica zostanie
utworzona w pamięci programu (we FLASHu AVRa).
8 z 11
Teraz, aby pokazać obrazek na ekranie, wystarczy przekopiować
dane z tablicy we FLASHu AVRa do pamięci RAM obrazu
wyświetlacza, robi to funkcja "lcd_image".
/* */
void lcd_image( char img[], x0, y0, w, h)
(unsigned [],char ,char ,char ,char )
( [], , , , )
( [], , , , )
{
{
{
{
unsigned int i, ,k;
,j, ;
, , ;
, , ;
for( =0, =0, =0; i< ; i++)
(i= ,j= ,k= ; ( = , = , = ; < ; ++)
( = , = , = ; < ; ++)
{
{
{
{
/* Komenda LCD "Set Y address of RAM" */
lcd_write_byte( , 0x40|( +y0));
(LCD_CMD, |(i+ ));
( , |( + ));
( , |( + ));
/* Komenda "Set X address of RAM"*/
lcd_write_byte( , 0x80|( ));
(LCD_CMD, |(x0));
( , |( ));
( , |( ));
/* Kopiowanie z FLASH do pamięci obrazu LCD */
for( =0; j< ; j++, ++)
(j= ; ( = ; < ; ++, ++)
( = ; < ; ++, ++)
lcd_write_byte( , pgm_read_byte(& [k]));
(LCD_DATA, (&img[ ]));
( , (& [ ]));
( , (& [ ]));
}
}
}
}
}
}
}
}
Listing nr 4. Funkcja wyświetlająca obrazek na ekranie LCD.
Pierwszy argument funkcji "lcd_image" to tablica we FLASHu
z danymi obrazka; kolejne dwa argumenty (x0,y0), to poło\enie
górnego lewego rogu obrazka na ekranie LCD; argument czwarty
i piąty to szerokość i wysokość obrazka. Parametry: y0 i wysokość
obrazka trzeba podać w bajtach (osiem pikseli pionowo, patrz
rys.2); na przykład, jeśli obrazek ma wysokość 48 pikseli, to nale\y
wstawić 6.
A oto główny pliku pierwszego przykładu. Najpierw funkcja
"lcd_init" inicjuje wyświetlacz, następnie funkcja "lcd_image"
kopiuje dane obrazka z tablicy we FLASHu do pamięci RAM obrazu
wyświetlacza.
/*
Plik "main.c"
*/
#include
#include
#include "lcd.h"
/* Dołącza dane z obrazkiem, obrazek zostanie
umieszczony w pamięci programu, we FLASHu */
unsigned char hello_img[] PROGMEM = {
[] = {
[] = {
[] = {
#include "hello_img.c"
};
};
};
};
int main( )
(void)
( )
( )
{
{
{
{
/* Inicjuje wyświetlacz */
lcd_init();
();
();
();
/* Wyswietla obrazek */
lcd_image( ,0, ,84, );
(hello_img, ,0, ,6);
( , , , , );
( , , , , );
/* Zatrzymanie programu */
while( );
(1);
( );
( );
return 0;
;
;
;
}
}
}
}
Listing nr 5. Główny plik przykładu pierwszego.
Przykładowy obrazek pokazany na ekranie LCD od Nokii_3310
Katalog z plikami przykładu pierwszego mo\na pobrać klikają w link
poni\ej, sÄ… dwie wersje: wersja a - z programowym SPI, wersja
b - wykorzystująca sprzętowy interfejs SPI AVRa atmega. Katalogi z
plikami zródłowymi przykładów zawierają tak\e plik Makefile, który
nale\y dostosować: wybrać typ AVRa, częstotliwość pracy
mikrokontrolera, typ programatora -przykłady były testowane na
atmega8 16MHz.
Przykład drugi. Tekst na ekranie LCD
Nasz wyświetlacz nie udostępnia trybu tekstowego, zatem aby
napisać na ekranie tekst, trzeba samemu rysować litery. W
programie MicroLCD przygotowałem obrazek ze wzorami liter, cyfr
i innych znaków z tablicy kodów ASCII, ka\dy znak narysowany jest
9 z 11
na polu o wymiarach 6x8 punktów. Dane obrazka ze wzorami
znaków wyeksportowałem do pliku tekstowego i dołączyłem do
programu komendÄ… preprocesora #include "font6x8p.c". Wzory
znaków trafią do tablicy o nazwie "font" umieszczonej w pamięci
programu (we FLASHu)
Obrazek ze wzorami znaków dla wyświetlacza.
Aby tekst pojawił się na ekranie wyświetlacza, program będzie
kopiował wzory znaków z tablicy "font" do odpowiedniego miejsca
w pamięci RAM obrazu wyświetlacza. Ekran wyświetlacza
podzielony jest na linie tekstowe o wysokości ośmiu punktów, taka
jest organizacja pamięci RAM obrazu naszego wyświetlacza, patrz
rys.2. śeby narysować jeden znak o wymiarach 6x8, trzeba
skopiować sześć kolejnych bajtów; ka\dy bajt to osiem uło\onych
pionowo punków na ekranie wyświetlacza. Wyświetlacz Noki_3310
ma rozdzielczość 84x48, zatem mo\na na nim pokazać 6 linii teksu,
po 14 znaków 6x8. A to jest funkcja pisząca na ekranie
wyświetlacza tekst:
/*
Wyświetla tekst - znaki 6x8
s - ciąg znaków zakończony zerem
x - pierwsza kolumna 0..84(96)
y - wiersz 0..5(7)
*/
void lcd_text( s[], unsigned char x, unsigned char y)
(char [], , )
( [], , )
( [], , )
{
{
{
{
unsigned int c, ;
,j;
, ;
, ;
unsigned char i, ;
,k;
, ;
, ;
/* Kody polskich literek z ogonkami */
char pl[] = {'ą', ,'ę', ,'ń', ,'ś', ,'\', ,'Ć', ,'A', ,'Ó', ,'y', };
[] = { ,'ć', ,'ł', ,'ó', ,'z', ,'', ,'', ,'C', ,'Ś', ,'ś'};
[] = { , , , , , , , , , , , , , , , , , };
[] = { , , , , , , , , , , , , , , , , , };
/* Ustawia poło\enia pierwszej litery tekstu na ekranie LCD */
lcd_write_byte( , LCD_SETY|( ));
(LCD_CMD, |(y));
( , |( ));
( , |( ));
lcd_write_byte( , LCD_SETX|( ));
(LCD_CMD, |(x));
( , |( ));
( , |( ));
/* Rysuje znak po znaku */
for( =0; (c = s[ ]); k++)
(k= ; ( = [k]); ++)
( = ; ( = [ ]); ++)
( = ; ( = [ ]); ++)
{
{
{
{
/* Dopasowuje kody znaków z ogonkami */
for( =0; (i< ) && (pl[ ]!=c); i++) ;
(i= ; ( <18) && ( [i]!= ); ++) ;
( = ; ( < ) && ( [ ]!= ); ++) ;
( = ; ( < ) && ( [ ]!= ); ++) ;
if( <18) c= 0x80+ ;
(i< ) = +i;
( < ) = + ;
( < ) = + ;
/* Kopiuje jeden znak(6x8) z FLASH do pamięci obrazu LCD */
for( =0, j=( -32)* ; i< ; i++, ++)
(i= , =(c- )*6; <6; ++,j++)
( = , =( - )* ; < ; ++, ++)
( = , =( - )* ; < ; ++, ++)
lcd_write_byte( , pgm_read_byte(& [j]));
(LCD_DATA, (&font[ ]));
( , (& [ ]));
( , (& [ ]));
}
}
}
}
}
}
}
}
Listing nr 6. Funkcja wyświetlająca ekranie LCD tekst
Pierwszym argumentem funkcji lcd_text jest ciąg znaków
zakończony zerem, tekst mo\e zawierać polskie znaki z ogonkami.
Drugi i trzeci argument to poło\enie tekstu na ekranie LCD; x mo\e
przyjmować wartości 0..84, y-wartości 0..5.
A to jest główny plik drugiego przykładu:
/*
Plik "main.c"
LCD od nokia3310 przykład 2
KURS AVR-GCC www.abxyz.bplaced.net
testowane na atmega8 (16MHz)
*/
#include
10 z 11
#include
#include "lcd.h"
/* */
int main( )
(void)
( )
( )
{
{
{
{
/* Inicjuje wyświetlacz */
lcd_init();
();
();
();
/* Czyści ekran */
lcd_clear();
();
();
();
/* Wyświetla tekst */
lcd_text( AVR-GCC", 1* , 0);
("Kurs , *6, );
( , * , );
( , * , );
lcd_text( :)", 4* , 1);
("ABXYZ , *6, );
( , * , );
( , * , );
lcd_text( , *6, );
("Wyświetlacz", 1* , 3);
( , * , );
( , * , );
lcd_text( , 5* , 4);
("LCD", *6, );
( , * , );
( , * , );
lcd_text( Nokii 3310", 0* , 5);
("od , *6, );
( , * , );
( , * , );
/* Zatrzymanie programu */
while( );
(1);
( );
( );
return 0;
;
;
;
}
}
}
}
Listing nr 7. Główny plik przykładu drugiego.
Przykładowy tekst na ekranie wyświetlacza od Nokii 3310.
Katalog z plikami przykładu drugiego mo\na pobrać klikają w link
poni\ej: sÄ… dwie wersje: wersja a - z programowym SPI, wersja
b - wykorzystująca sprzętowy interfejs SPI AVRa atmega.
Przykład trzeci. Płynący tekst.
Przykład trzeci. Obrazek na górze ekranu, płynący tekst na dole.
/*
Plik "main.c"
LCD od Nokii_3310 przykład 3
KURS AVR-GCC www.abxyz.bplaced.net
testowane na atmega8 16(MHz)
*/
#include
#include
#include
#include
#include "lcd.h"
// Dane obrazka "avr_gcc"
unsigned char screen[] PROGMEM = {
[] = {
[] = {
[] = {
#include "avr_gcc.c"
};
};
};
};
// Wzory znaków 6x8 dla funkcji "scroll"
extern unsigned char font[] PROGMEM;
[] ;
[] ;
[] ;
// Tekst płynącego napisu
unsigned char tekst[] PROGMEM = " Internetowy kurs programowania mikrokontrolerów AVR w języku C
[] =
[] =
[] =
// Funkcja tworzy na ekranie LCD płynący napis
void scroll( char txt[], unsigned char line)
(unsigned [], )
( [], )
( [], )
{
{
{
{
unsigned int j, ,k, ;
,l, ,n;
, , , ;
, , , ;
unsigned char c, ,m;
,i, ;
, , ;
, , ;
// Kody polskich literek z ogonkami
unsigned char pl[] = {'ą', ,'ę', ,'ń', ,'ś', ,'\', ,'Ć', ,'A', ,'Ó', ,'y', };
[] = { ,'ć', ,'ł', ,'ó', ,'z', ,'', ,'', ,'C', ,'Ś', ,'ś'};
[] = { , , , , , , , , , , , , , , , , , };
[] = { , , , , , , , , , , , , , , , , , };
11 z 11
// liczenie znaków w tekście
for( =0; (&txt[ ]);n++);
(n= ;pgm_read_byte(& [n]); ++);
( = ; (& [ ]); ++);
( = ; (& [ ]); ++);
for( =0; j<( -(LCD_X/ ))*6 ;j++)
(j= ; <(n-( /6))* ; ++)
( = ; <( -( / ))* ; ++)
( = ; <( -( / ))* ; ++)
{
{
{
{
LCD_GOTO( , line)
(0, )
( , )
( , )
for( =0, =j; i< ;i++, ++)
(i= ,l= ; ( = , = ; < ; ++, ++)
( = , = ; < ; ++, ++)
{
{
{
{
c = pgm_read_byte(& [ (l/ ) ]);
= (& [ ( / ) ]);
= (&txt[ ( /6) ]);
= (& [ ( / ) ]);
// Dopasowuje kody polskich znaków z ogonkami
for( =0; (m< ) && (pl[ ]!=c); m++) ;
(m= ; ( <18) && ( [m]!= ); ++) ;
( = ; ( < ) && ( [ ]!= ); ++) ;
( = ; ( < ) && ( [ ]!= ); ++) ;
if( <18) c= 0x80+ ;
(m< ) = +m;
( < ) = + ;
( < ) = + ;
k = (c- )*6+( %6);
= ( - )* +( % );
= ( -32)* +(l% );
= ( - )* +( % );
lcd_write_byte( , pgm_read_byte(& [k]));
(LCD_DATA, (&font[ ]));
( , (& [ ]));
( , (& [ ]));
}
}
}
}
_delay_ms( );
(70);
( );
( );
}
}
}
}
}
}
}
}
/* MAIN */
int main( )
(void)
( )
( )
{
{
{
{
// Inicjuje LCD
lcd_init();
();
();
();
// Obrazek w górnej części ekranu
lcd_image( ,0, ,84, );
(screen, ,0, ,5);
( , , , , );
( , , , , );
// PÅ‚ynÄ…cy napis w linii nr 5
while( )
(1)
( )
( )
scroll( ,5);
(tekst, );
( , );
( , );
return 0;
;
;
;
}
}
}
}
Listing nr 8. Główny plik przykładu drugiego.
Katalog z plikami przykładu trzeciego mo\na pobrać klikają w link
poni\ej: sÄ… dwie wersje: wersja a - z programowym SPI, wersja
b - wykorzystująca sprzętowy interfejs SPI AVRa atmega.
26.04.11 ABXYZ
Copyright © 2009-2011 ABXYZ - Wszelkie prawa zastrze\one


Wyszukiwarka

Podobne podstrony:
XYZ Hobby Robot Kurs AVR GCC Gamepad od PlayStation
Kurs AVR GCC cz 5
Kurs AVR GCC, cz 3
Kurs AVR GCC cz 2
Kurs AVR GCC Dekoder RC5
Kurs AVR GCC cz 3
Kurs AVR GCC cz 1
Kurs AVR GCC, cz 1
Kurs AVR GCC, cz 5
Kurs AVR GCC, cz 4
Kurs AVR GCC, cz 2
Kurs AVR GCC cz 4
Using the EEPROM memory in AVR GCC
Wyświetlacz LCD
AVR GCC w Linuksie przykład instalacji ze źródeł

więcej podobnych podstron