Politechnika Lubelska w Lublinie |
Laboratorium układów mikroprocesorowych |
||
Imię i Nazwisko Piotr Kliza |
Semestr IX |
Grupa ED 9.8 |
Rok akademicki 2007/2008 |
Temat ćwiczenia: Obsługa klawiatury i wyświetlacza LCD w AtMega32. |
Data wykonania: 11.12.07 |
Ocena: |
Treść programu z opisem.
#include <avr/io.h>
// stała czasowa
#define ms 2000
// ustawienie bitu E
char setE(char bajt)
{
return bajt |= (1<<1);
}
// wartość rejestru 0b01010101
// wartość (1<<1) 0b00000010
// suma bitowa 0b01010111
// wyzerowanie bitu E
char clrE(char bajt)
{
return bajt &= ~(1<<1);
}
// wartość rejestru 0b01010111
// wartość ~(1<<1) 0b11111101
// suma bitowa 0b01010101
// ustawienie bitu RS
char setRS(char bajt)
{
return bajt |= 1;
}
// wyzerowanie bitu RS
char clrRS(char bajt)
{
return bajt &= ~1;
}
// procedura odczekania
void czekaj(int czas)
{int i;
for (i=0;i<czas;i++)
asm ("nop");
};
// zapis instrukcji na lcd
void instnalcd(char znak)
{
char pom; // zmienna pomocnicza
pom = (znak & 0b11110000); // zapisanie 4 starszych bitów
pom = setE(pom); // ustawienie E = 1
pom = clrRS(pom); // ustawienie RS = 0
PORTD = pom; // gotowe na port
czekaj(ms); // odczekanie na ustabilizowanie wartości na porcie
PORTD = clrE(pom); // zapis na lcd; ustawienie E = 0
czekaj(ms); // odczekanie na potrzeby odczytu przez LCD
pom = (znak << 4); // zapisanie 4 młodszych bitów
pom = setE(pom); // ustawienie E = 1
pom = clrRS(pom); // ustawienie RS = 0
PORTD = pom; // gotowe na port
czekaj(ms); // odczekanie na ustabilizowanie wartości na porcie
PORTD = clrE(pom); // zapis na lcd; ustawienie E = 0
czekaj(ms); // odczekanie na potrzeby odczytu przez LCD
}
// zapis danych na lcd
void danenalcd(char znak)
{
char pom;
pom = (znak & 0b11110000); // analogicznie jak powyżej
pom = setE(pom);
pom = setRS(pom); // RS = 1 - transmisja danych
PORTD = pom;
czekaj(ms);
PORTD = clrE(pom);
czekaj(ms);
pom = (znak << 4);
pom = setE(pom);
pom = setRS(pom);
PORTD = pom;
czekaj(ms);
PORTD = clrE(pom);
czekaj(ms);
}
// inicjalizacja lcd
void initlcd()
{
DDRD = 0b11111111; // port D jako w całości wyjściowy
PORTD = 0b00100010; // ustawienie LCD jako 4 bitowy
czekaj(ms);
PORTD = 0b00100000; // transmisja na LCD
czekaj(ms);
instnalcd(0b00001110); // właczenie LCD
instnalcd(0b00000001); // czyszczenie LCD
instnalcd(0b00000110); // konfiguracja sposobu wyświetlania
}
// procedura obslugi klawiatury
char klaw()
{
unsigned char stan, znak=0x00; // stan - stan portu klawiatury
unsigned int ile=0; // ile - min liczba wciśniętych klawiszy
PORTA = 0b01111111; // podanie 0 na wiersz 1
stan = PINA; // sczytanie stanu portu
if(stan!=0b01111111) // jeśli cos wciśnięto to wykonaj
{
ile++; // zwiększ ile
switch(stan) // rozpoznanie który klawisz wciśnięty
{
case 0b01110111: znak='0'; break; // 1 wiersz 1 kolumna
//przypisanie znaku do klawisza
case 0b01111011: znak='1'; break; // 1 wiersz 2 kolumna
case 0b01111101: znak='2'; break; // 1 wiersz 3 kolumna
case 0b01111110: znak='3'; break; // 1 wiersz 4 kolumna
default: ile++; // inny stan tj. więcej jak jeden przycisk
};
};
PORTA = 0b10111111; // sprawdzenie wciśnięcia klawiszy z 2 wiersza
stan = PINA;
if(stan!=0b10111111)
{
ile++;
switch(stan)
{
case 0b10110111: znak='4'; break;
case 0b10111011: znak='5'; break;
case 0b10111101: znak='6'; break;
case 0b10111110: znak='7'; break;
default: ile++;
};
};
PORTA = 0b11011111; // z 3 wiersza
stan = PINA;
if(stan!=0b11011111)
{
ile++;
switch(stan)
{
case 0b11010111: znak='8'; break;
case 0b11011011: znak='9'; break;
case 0b11011101: znak='A'; break;
case 0b11011110: znak='B'; break;
default: ile++;
};
};
PORTA = 0b11101111; // z 4 wiersza
stan = PINA;
if(stan!=0b11101111)
{
ile++;
switch(stan)
{
case 0b11100111: znak='C'; break;
case 0b11101011: znak='D'; break;
case 0b11101101: znak='E'; break;
case 0b11101110: znak='F'; break;
default: ile++;
};
};
if (ile!=1) return 'x'; // jeśli ilość klawiszy wciśniętych różna od 1
else return znak; // w przeciwnym razie
//zwróć kod ASCII znaku
}
// program glowny
int main(void)
{
unsigned char pom, poprzedni=0x00; // pom - pomocnicza; poprzedni - poprzedni znak z klaw.
DDRA = 0xf0; // ustawienie portu A - klawiatura 4x4
PORTA = 0xff;
DDRB = 0xff; // ustawienie portu B - diody
PORTB = 0x00;
initlcd(); // inicjalizacja wyświetlacza
while (1) // pętla główna
{
pom = klaw(); // przypisz pom wartość z klawiatury
if (pom!='x') // jeśli różna od błędnej to
{
PORTB = pom; // kod znaku na diody
if (pom!=poprzedni) // jeśli różna od poprzedniej to
{
danenalcd(klaw()); // wyświetl znak przypisany klawiszowi
poprzedni=pom; // zapamiętaj ostatnio wyświetlony
};
}
else PORTB = 0x00; // w przeciwnym razie zgas diody
};
};
Efekt działania programu.
Po uruchomieniu należy odczekać czas potrzebny na konfiguracje portów i inicjalizacje wyświetlacza LCD. Po tym czasie wciśnięcie klawisza na klawiaturze spowoduje wyświetlenie na diodach wartości bitowej znaku ASCII przypisanego do klawisza, a na wyświetlaczu LCD pojawi się ten znak. Wynikiem przytrzymania klawisza, będzie świecenie diod do czasu jego puszczenie. Aby na wyświetlaczu pojawił się znak uprzednio wciśnięty, należy wcisnąć klawisz powtórnie. Przytrzymanie klawisza nie powoduje wyświetlania się na LCD ciągu tych samych znaków. W przypadku nie wciśnięcia żadnego lub po puszczeniu klawisza na wyświetlaczu nie zachodzą zmiany, a wszystkie diody są wygaszone. Wynikiem wciśnięcia większej niż jeden liczby klawiszy jest wyświetlenie na LCD znaku `x' i jego odpowiednika bitowego na diodach.