+++ title = "AVR - LCD panel - #2 Program" perex_e = " Kompatibilní zapojení: LCD panel s ATmega8 Ke stažení: LCD_002.c == LCD_002.pdf == LCD_002.htm . . " tags = ["Článek", "Bastlení", "Konstrukce", "2012"] +++ Kompatibilní zapojení: LCD panel s ATmega8 Ke stažení: LCD_002.c == LCD_002.pdf == LCD_002.htm . . * * * <title>Untitled</title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <meta name="generator" content="SynEdit HTML exporter"> <style type="text/css">&lt;!-- body { color: #000000; background-color: #FFFFFF; } .cpp1-assembler { } .cpp1-brackets { } .cpp1-comment { color: #008000; font-style: italic; } .cpp1-float { color: #000080; } .cpp1-hexadecimal { color: #000080; } .cpp1-character { } .cpp1-identifier { } .cpp1-illegalchar { } .cpp1-number { color: #000080; } .cpp1-octal { color: #0000FF; } .cpp1-preprocessor { } .cpp1-reservedword { font-weight: bold; } .cpp1-space { color: #008080; } .cpp1-string { color: #800000; } .cpp1-symbol { } --&gt;</style> ``` /* 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 ```