Politechnika Lubelska w Lublinie |
|||
Laboratorium Układów Mikroprocesorowych |
|||
Wykonał: Emil Leńczuk |
Gr: ED 9.7 |
Data: 12.01.2009 |
Ocena:
|
Temat: oprogramowanie AVR -obsługa klawiatury i wyświetlacza LCD |
Cel:
zaprogramowanie mikrokontrolera AVR Atmega32 do obsługi dużej klawiatury numerycznej i wyświetlacza. Program na bieżąco monitoruje stan pinów Avr podłączonych do klawaitury, następnie wyświela nazwę wciśniętego klawisza na ekranie LCD. Program ten może stać się bazą do stworzenia programu który mógłby działać jako kalkulator.
Kod źródłowy:
#include <avr/io.h>
#include <avr/delay.h>
#define OUT DDRA = 0x0F //ustaw PA0...3 jako wyjscia, PA4...7 jako wejscia - na L298
#define INI_NULL PORTA = 0xF0 //ustaw wejscia na 1
#define LCD PORTB //LCD
#define E 3
#define RS 2
#define SET_E LCD |= _BV(E)
#define CLR_E LCD &= ~_BV(E)
#define SETRS LCD |= _BV(RS)
#define CLR_RS LCD &= ~_BV(RS)
//Podlaczenie:
// ***************
// PD7 <----> W1(4)
// PD6 <----> W2(3)
// PD5 <----> W3(2)
// PD4 <----> W4(1)
// PD3 <----> K1(4)
// PD2 <----> K2(3)
// PD1 <----> K3(2)
// PD0 <----> K4(1)
// ***************
// RS <----> PB2
// E <----> PB3
// D4 <----> PB4
// D5 <----> PB5
// D6 <----> PB6
// D7 <----> PB7
//-----------------
void init()
{
OUT;
INI_NULL;
// KEY_I;
// PULLUP;
DDRB = 0xFF;
PORTB = 0xFF;
}
//zapisu bajtu do LCD
void zapis_lcd(char x)
{
SET_E;
_delay_ms(1);
LCD = ((LCD & 0x0F) | (x & 0xF0)); //pierwsza polówka bajtu
_delay_ms(1);
CLR_E; //zapis do LCD zboczem opadajacym
_delay_ms(1);
SET_E;
_delay_ms(1);
LCD = ((LCD & 0x0F) | ((x & 0x0F)<<4)); // druga polowka bajtu
_delay_ms(1);
CLR_E; //zapis do wyswietlacza zboczem opadajacym
_delay_ms(1);
}
//zapis instrukcji do LCD
void zapis_inst(char x)
{
CLR_RS; //zapis instrukcji, niski stan linii R
zapis_lcd(x); //zapis do LCD
}
//zapisu danej do LCD
void zapis_danej(char x)
{
SETRS; //zapis danej, wysoki stan linii R
zapis_lcd(x); //zapis do LCD
}
//zapis tekstu do LCD
void zapis_text(char * s)
{
while(*s) //jesli nie zero
{
zapis_danej(*s); // wyslij znak do LCD
s++; //kolejny znak
}
}
//inicjalizacja LCD
void lcd_init(void)
{
_delay_ms(20); //czekaj na ustalenie sie napiecia zasilajacego
CLR_E; //E = 0
CLR_RS; //RS = 0
char i;
for(i = 0; i < 3; i++) // wyslij 3x instrukcje
{
SET_E; // E = 1
LCD &= 0x3F; //
CLR_E; // E = O
_delay_ms(5); // czekaj
}
SET_E;//E=1
LCD &= 0x2E;
CLR_E; //E = 0
_delay_ms(1);
zapis_inst(0x28); // interfejs 4-bity, 2-linie, znak 5x7
zapis_inst(0x08); // wylacz LCD, kursor i miganie
zapis_inst(0x01); // czysc LCD
zapis_inst(0x06); // bez przesuwania w prawo
zapis_inst(0x0C); // wlacz LCD, bez kursora i mrugania
}
//obsluga klawiatury 4x4
unsigned char keypad()
{
unsigned char temp3=0;
unsigned char temp1=0xff,temp2=0xff;
DDRD=0b00001111; //D0-D3 - Wiersze //\\D4-D 7 - Kolumny
PORTD=0b11110000;
_delay_ms(20);
do
{
while(PIND==0b11110000){
//pisz_seg(temp3);
};
_delay_ms(10);
//wiersz 0
if(!(PIND&(1<<4)))
{temp1=0;}
//wiersz 1
else if(!(PIND&(1<<5)))
{temp1=1;}
//wiersz 2
else if(!(PIND&(1<<6)))
{temp1=2;}
//wiersz 3
else if(!(PIND&(1<<7)))
{temp1=3;}
else {temp1=0;}
DDRD=0b0000000; //zamiana wiesze z kolumnami
PORTD=0b00001111;
DDRD=0b11110000;
PORTD=0b00001111;
_delay_ms(10);
//kolumna 0
if(!(PIND&(1<<0)))
{temp2=1;}
//kolumna 1
else if(!(PIND&(1<<1)))
{temp2=5;}
//kolumna 2
else if(!(PIND&(1<<2)))
{temp2=9;}
//kolumna 3
else if(!(PIND&(1<<3)))
{temp2=13;}
else {temp2=0;}
//czekaj na puszczenie klawisza
while(PIND!=0b00001111){};
temp3=temp1+temp2; //wynik jako wiersz+kolumna
}
while(temp3==0);
return temp3;
}
// + | 0 1 2 3
//--------------------
// 1 | 1 2 3 4
// 5 | 5 6 7 8
// 9 | 9 10 11 12
// 13 | 13 14 15 16
//funkcja wyswietlajaca wcisnieta liczbe na wyświetlaczu
void wyswliczbe(char x)
{
switch (x)
{
case 1: {
zapis_text("*");
break;
}
case 2: {
zapis_text("7");
break;
}
case 3: {
zapis_text("4");
break;
}
case 4: {
zapis_text("1");
break;
}
case 5: {
zapis_text("0");
break;
}
case 6: {
zapis_text("8");
break;
}
case 7: {
zapis_text("5");
break;
}
case 8: {
zapis_text("2");
break;
}
case 9: {
zapis_text("#");
break;
}
case 10: {
zapis_text("9");
break;
}
case 12: {
zapis_text("3");
break;
}
case 13: {
zapis_text("D");
break;
}
case 14: {
zapis_text("C");
break;
}
case 15: {
zapis_text("B");
break;
}
case 16: {
zapis_text("A");
break;
}
default: {
zapis_text("6");
break;
}
}
}
void main()
{
unsigned char sw;
init();
lcd_init();
zapis_text("czesc dzialam");
zapis_inst(0x0C);
_delay_ms(2000);
zapis_inst(0x01);
while(1)
{
sw=keypad();//sprawdz kolejne przyciski i przypisz funcje - tabela
zapis_inst(0x01);
zapis_text("Wybrano:");
wyswliczbe(sw);
}
}
//--------------------------------------------------------------------------------------
Zasada działania programu:
po wstępnej inicjalizacji wyświetlacza LCD i zasygnalizowaniu że program działa
program wchodz nam w nieskończoną pętlę while gdzie za każdym obrotem pętli skanuje klawiaturę za pomoca funkcji keypad() ta następnie zwraca wartość do funkji drukującej która wyświetla uprzednio wciśnięty klawisz.
Dokładne działanie poszczególnych funkcji programu opisane są w komentarzach (tekst zakolorowany na zielono w kodzie źródłowym).
Wnioski.
W wyniku pracy w AVRstudio udało się stworzyć prgram do detekcji i sygnalizowania aktualnie wciśniętych klawiszy klawiatury. Może on posłużyć jak baza do napisania programu liczącego jak kalkulator arytmetyczny. Program za każdym wciśnięciem klawisza odświerza wyświetlaną wartość na LCD.