Kompatibilní zapojení: LCD panel s ATmega8

Ke stažení: LCD_002.c == LCD_002.pdf == LCD_002.htm


/*
Minule jsme na přípravku ATmega_LCD_uni vyzkoušeli displej, a nyní se pokusíme
"oživit" i klávesnici.
*/
/*
Obslužné rutiny pro klávesnici jsou uloženy v souboru "kbd_2x3dm.c". Tento
soubor je opět závislý na konfiguraci uložené v souboru "atmega_lcd_uni_cfg.c"
a je proto nutné, aby soubor "atmega_lcd_uni_cfg.c" byl vložen ještě před
souborem "kbd_2x3dm.c".
Soubor "kbd_2x3dm.c" obsahuje následující dvě rutiny:

void kbd_ini(void)	//inicializace klávesnice (nastavení vstupních a výstupních pinů)
unsigned char kbd_read(void) //tato funkce "přečte" klávesnici, kdykoli je
volána, a vrátí hodnotu právě stisknutých tlačítek

Funkce "kbd_read(void)" vrací hodnotu kláves které jsou stisknuty právě v tom
okamžiku, kdy je volána. Pokud tedy chceme na stisk klávesy reagovat okamžitě,
je vhodné tuto funkci volat přibližně 10 - 20 krát za vteřinu.
Jinak by bylapatrná prodleva, kdy je potřeba tlačítko chvíli držet, než si
toho procesor "všimne".

Soubor "kbd_2x3dm.c" také obsahuje dvě zajímavé konstanty, které řídí chování
klávesnice, pokud je tlačítko drženo déle.
Tyto konstanty jsou:

KBD_SKIP
KBD_ACC

Konstanta "KBD_SKIP" určuje, kolik cyklů se má vynechat, pokud je stisknuto
stále totéž tlačítko. To znamená, že když funkce "kbd_read()" zjistí, že je
stisknuto stejné tlačítko (nebo stejná tlačítka), jako když byla volána minule,
vrátí místo hodnoty tohoto tlačítka nulu (jako kdyby nebylo stisknuto žádné
tlačítko). Konstanta "KBD_SKIP" tedy určuje, kolikrát má funkce "kbd_read()"
toto tlačítko ignorovat, než opět vrátí jeho hodnotu.
Pokud je tlačítko drženo i nadále, poté co funkce "kbd_read()" již podruhé
vrátila jeho hodnotu, začíná se uplatňovat konstanta "KBD_ACC". Tato konstanta
určuje, o kolik cyklů se má vynechat méně před každým dalším navrácením hodnoty
téhož tlačítka.

Výsledkem tedy je, že pokud uživatel stiskne a drží tlačítko, vrátí se jeho
hodnota, čeká se podle "KBD_SKIP", znovu se vrátí jeho hodnota, čeká se
o "KBD_ACC" méně, zase se vrátí hodnota, čeká se o další "KBD_ACC" méně,
a tak to jde až do doby, kdy se vrací hodnota drženého tlačítka při každém
cyklu (volání funkce "kbd_read()"), nebo dokud uživatel tlačítko opět neuvolní.

Tato funkce se nazývá "autorepeat" a hodí se například, pokud je potřeba
nastavit nějakou proměnnou ve velkém rozsahu.
*/
/*
Nyní se tedy můžeme pustit do psaní programu. Náš program bude jednoduše
vypisovat kódy stisknutých tlačítek na displej. Tento program bude pro nás
velmi užitečný, protože až budeme později potřebovat, aby program reagoval
na dané tlačítko, budeme potřebovat vědět, jaké číslo (kód) toto tlačítko
představuje.
Čtení klávesnice bude probíhat vždy jednou za 100 ms (10x za vteřinu), což
zajistíme pomocí časovače. pro čtení klávesnice nám bude stačit jednoduchý
časovač TC0\.
Zároveň budeme na displej vypisovat proměnnou "opakovani" která se pokaždé,
když je navrácen kód tlačítka zvýší o jednnu. Je to proměnná typu unsigned
char - bude se tedy zvyšovat jen do 255, protože pak přeteče a začíná
opět od nuly.
*/

#define F_CPU 1000000  // Taktovací frekvence procesoru 1 MHz

#include <avr/io.h>			//Knihovna vstupů a výstupů
#include <avr/interrupt.h>  //Knihovna přerušení

#include "atmega_lcd_uni_cfg.c" //konfigurace vstupů a výstupů pro přípravek ATmega_lcd_uni
#include "lcd.c"					//Obslužné rutiny pro display
#include "kbd_2x3dm.c"		//Obslužné rutiny pro klávesnici

#define TCNT0VAL	(256-(F_CPU/1024/10))//Hodnota, od které bude časovač
                    //počítat, než přeteče a vyvolá přerušení.
                    //256 => maximum čítače + 1 = přetečení
                    //1024 => dělička,
                    //10 => přerušení se vyvolá 10x za vteřinu

volatile unsigned char tlacitko=0;//Globální proměnná obsahující kód stisknutého

                    //tlačítka. Používá se v main() a přerušení.

//vektor přerušení vykoná se vždy když přeteče časovač TC0 (cca 10x za vteřinu)
ISR(TIMER0_OVF_vect)
{
TCNT0=TCNT0VAL; //nastavení hodnoty, od které časovač počítá
                //(jinak by počítal od nuly)
tlacitko=kbd_read();	//přečti klávesnici a hodnotu ulož do "tlacitko"
}

int main(void)
{
unsigned char opakovani=0; 	//proměnná, která se pokaždé po vrácení kódu
                            //tlačítka zvýší o 1

TCCR0=0B00000101;	//zapnout TC0 s předděličkou 1024
setb (TIMSK,0);		//povol přerušení při přetečení TC0 (TCNT0==0x100)
SREG  |= (1<<7);	//povolení globálního přerušení
TCNT0=TCNT0VAL;		//resetTC

lcd_ini();	//inicializace displeje (nastavení výstupních pinů a zahájení komunikace)
kbd_ini();	//inicializace klávesnice (nastavení vstupních pinů)

cls();		//smazání displeje

gotoxy(1,1);	//kurzor na začátek prvního řádku
lcd_text("Tlacitko:");	//napíšeme text
gotoxy(2,1);	//kurzor na začátek druhého řádku
lcd_text("Opakovani:");	//napíšeme text

while(1)	//hlavní smyčka
    {
    if(tlacitko)	//pokud je stisknuté nějaké tlačítko ("tlacitko" není nula)
        {
        gotoxy(1,13);	//nastavení kurzoru za text (abychom jej nepřepsali)
        lcd_byt(tlacitko);	//vypiš kód tlačítka
        tlacitko=0;			//hodnotu tlačítka už nepotřebujeme
        gotoxy(2,13);		//nastavení kurzoru za text
        lcd_byt(opakovani);	//vypiš číslo opakování
        opakovani++;
        }

    }
}
//konec programu

//Pro radioklub OK1KVK naspal Vašek Král