Tomáš Hadwiger, UREL, FEEC VUT
Brno xhadwi00stud.feec.vutbr.cz
Jan Nedbal, UREL, FEEC, VUT Brno
xnedba02stud.feec.vutbr.cz
Projekt se zabývá návrhem programu pro ovládání touch screenu. Pro detekci stisknutých plošek byl nejprve použit A/D převodník, po konzultaci byl zvolen komparátor. První část se zabývá návrhem vhodného zapojení touch screenu, v další části je popsán algoritmus pro ovládání touch screenu.
Touch screen
Na display je přilepen touch screen o patnácti polích rozdělených do třech řádků po pěti sloupcích. Je z něj vyvedeno osm vodičů. První vodič je pro první sloupec, další tři jsou pro řádky a poslední čtyři pro druhý až pátý sloupec. Rozdělení screenu a připojení k mikrokontroléru je zobrazeno na obr. 1.
Obr.1 Schéma zapojení.
V takovémto zapojení je možno pomocí přepínání prvních tří pinů portu A indikovat stisknutý řádek. Jednotlivé sloupce se pak adresují logickou 1 (5V) na portech PA3 až PA7 a tím se detekuje sloupec se stisknutou ploškou. Pro připojení je potřeba použít port A, zde se totiž nacházejí A/D převodníky. Pro detekci byl zvolen komparátor, vyhodnocení pomocí něj je rychlejší, než použití A/D převodníku a následné porovnávání. Další výhodou komparátoru je vyvolání přerušení při detekci napětí na pinu AIN0 většího, než referenční napětí na pinu AIN1. K získání referenčního napětí je použit odporový trimr R4. Toto referenční napětí bylo nastaveno na hodnotu 1,8V. Na pin AIN0 jsou přes schottkyho diody svedeny všechny tři řádky touch screenu.
Při stisku plošky se vyvolá díky tomuto zapojení přerušení, v přerušení se nastaví příznak a následuje skenování klávesnice. Pro skenování je nutno přednastavit oba vstupní signály komparátoru. Místo původního referenčního napětí je připojen jeden z prvních třech pinů A/D převodníku a místo diod je připojeno vnitřní referenční napětí 1,23V. Při aktivaci tohoto napětí je potřeba vyčkat 70µs. Toto zapojení je znázorněno na obr. 1.
Pomocí rezistorů o odporu 2,2 kΩ a odporu mezi jednotlivými sloupci a řádky je vytvořen jednoduchý odporový dělič. Sloupce jsou pomocí mikrokontroléru připojeny na 5V, aby bylo možno stiskem vyvolat přerušení. Vzhledem k tomu že pokud není ploška stisknuta, je odpor mezi řádkem a sloupcem značný a děličem tak teče zanedbatelný proud. Po stisknutí plošky se odpor mezi řádkem a sloupcem pohybuje kolem hodnoty 2 kΩ a je tak možno indikovat napětí kolem 3V, při kterém je splněna komparační podmínka a komparátor vyvolá přerušení. Pro indikaci stisknutého tlačítka byla zvolena hranice 1.8V. V datasheetu displeje je uvedeno že se odpor mezi daným řádkem a sloupcem ve stisknutém stavu pohybuje mezi 300 Ω až 10 kΩ. Přičemž minimální proud, který mezi nimi protéká, má být v rozmezí 10 μA až 10 mA.
Výpočet uzemňovacích rezistorů:
Minimální hodnota:
kde Ru je odpor uzemňovacího rezistoru, Rt je odpor touch screenu, Rc je celkový odpor děliče, U je napájecí napětí a Imax je maximální proud mezi řádkem a sloupcem.
Maximální hodnota:
kde Ru je odpor uzemňovacího rezistoru, Rt je odpor touch screenu, Rc je celkový odpor děliče, U je napájecí napětí a Imin je minimální proud mezi řádkem a sloupcem.
Použitý uzemňovací rezistor musí být tedy vybrán z tohoto rozmezí. Měřením odporu mezi řádkem a sloupcem při stisknuté plošce bylo zjištěno, že se tato hodnota pohybuje kolem 2 kΩ. Proud děličem byl zvolen 1 mA (použitelné rozmezí proudů touch screenem je 10 μA až 10 mA). Napětí mezi řádkem a sloupcem po stisknutí je:
kde Ut je napětí na touch screenu.
Toto napětí je zhruba polovina celkového napětí na dělič (5V), z toho důvodu bylo rozhodnuto o zvolení uzemňovacího rezistoru velikosti 2,2 kΩ.
Algoritmus detekce stisknutého tlačítka pomocí komparátoru:
Main – v levé části obr. 2. Zde je potřeba nastavit jako vstupy komparátoru piny AIN0 a AIN1 (bit ACME v registru SFIOR musí být nulový, stejně tak bit ACBG v registru ACSR), aby bylo možno stiskem plošky vyvolat přerušení. Přerušení bylo nastaveno na reakci na nástupnou hranu (bity ACIS1 a ACIS0 v registru ACSR jsou oba nastaveny na jedničky). Dále je potřeba připojit napájení komparátoru (bit ACD v registru ACSR musí být nulový) Na závěr bylo povoleno přerušení komparátorem a globální přerušení. Nyní se čeká jen na přerušení mikrokontrolérem.
for(;;) { if (j>0) //cekani dokud nepretece casovac = dobe 500ms { ks0108ClearScreen(); //mazani LCD j=0; //nulovani promenne na rizani casu vypisu } if(preruseni==1) //pokud nastalo preruseni komparatorem { cli(); //globalni zakazani preruseni vypis=F_stlaceno(); //funkce vracici cislo stlacene plosky preruseni=0; //vynulovani priznaku preruseni sei(); //globalni povoleni preruseni }//if(preruseni==1) ks0108GotoXY(40,40); //pozice vypisu itoa(vypis, vypis_T, 10); //pretypovani cisla na retezec ks0108Puts(vypis_T); //vypis cisla stlacene plosky }
unsigned int F_stlaceno (void) { volatile unsigned char stlaceno=0; //nulovani promenne stlaceno unsigned char sloupec=0; SFIOR |= ( 1 << ACME ); //povoleni multiplexovani komparatoru ACSR |= ( 1 << ACBG ); //zapnuti vnitrni reference 1,23V _delay_ms ( 1 ); //cekani na nabeh vnitrni reference for(sloupec=1;sloupec<6;sloupec++) //for cyklus adresujici postupne vsech 5 sloupcu touch screenu { PORTA = 0; //nulovani celeho portu A if (sloupec==1) //testovani prvniho sloupece { PORTA |= ( 1 << PORTA3 ); //nastaveni pinu PA3 na logickou 1 (adresace 1 sloupce) if (F_radek()>0) //testovani, jestli je stisknut nejaky radek v tomto sloupci { stlaceno=F_radek(); //pokud ano, zapise se do promenne stlaceno cislo plosky (1 az 3) break; //ukonci se for cyklus, aby se neprochazely dalsi sloupce } } . . . PORTA = 0; if (sloupec==5) { PORTA |= ( 1 << PORTA7 ); if (F_radek()>0) { stlaceno=12+F_radek(); break; } } } SFIOR &= ~ ( 1 << ACME ); //zakazani multiplexovani komparatoru, - pripojeni na AIN1 ACSR &= ~ ( 1 << ACBG ); //vytpnuti vnitrni reference 1,23V, + pripojeni na AIN0 PORTA |= ( 1 << PORTA3 )|( 1 << PORTA4 )|( 1 << PORTA5 )|( 1 << PORTA6 )|( 1 << PORTA7 ); //aktivace vsech sloupcu, aby bylo mozno detekovat dotyk return stlaceno; //navratova hodnota funkce (cislo stlacene plosky) }
unsigned int F_radek(void) //podprogram zjistujici radek, ktery byl stisknut { for(unsigned char i=0;i<3;i++) //postupna adresace jednotlivych radku { ADMUX = i; //vyber kanalu prevodniku PA0 az PA2 _delay_ms ( 5 ); //cekani nez se vybere if((ACSR & 32)==0) //pri stisku tlacitka se ACSR=0 { return i+1; //navratova hodnota = cislo radku 1 az 3 break; //ukonceni cyklu pri detekci stisknuteho radku } } } Pro srovnání je zde uveden i zdrojový kód pro skenování stisku pomocí A/D převodu:
unsigned int F_stlaceno (void)
{
volatile unsigned char stlaceno=0; //nulovani promenne stlaceno
unsigned char k;
PORTA = 0; //nulovani celeho portu A
for(k=0;k<6;k++) //for cyklus adresujici postupne vsech 5 sloupcu touch screenu
{
if (k==1) //prvni sloupec
{
PORTA |= ( 1 << PORTA3 ); //nastaveni pinu PA3 na logickou 1
if (F_radek()>0) //testovani, jestli je stisknut nejaky radek v tomto sloupci
{
if (F_radek()>0) //nova kontrola jestli je jeste radek stale stisknut
{
stlaceno=F_radek(); //pokud ano, zapise se do promenne stlaceno cislo radku (1 az 3)
break; //ukonci se for cyklus, aby se neprochazely dalsi sloupce
}
}
}
.
.
.
PORTA = 0;
if (k==5)
{
PORTA |= ( 1 << PORTA7 );
if (F_radek()>0)
{
if (F_radek()>0)
{
stlaceno=12+F_radek();
break;
}
}
}
}
return stlaceno;
}
unsigned int F_radek(void) //podprogram zjistujici radek, ktery byl stisknut
{
for (unsigned int i = 0x40; i < 0x43; i++) //cyklem se realizuje postupny vyber jednoho ze tri prvnich A/D prevodniku
{
ADMUX= i; //nastaveni parametru prevodu
if(read_adc()>100) //pokud je na odporovem delici napeti, znamena to stisknutou plosku touch screenu
{
return i-0x40+1; //navratova hodnota - cislo 1,2,3
break; //ukonceni for cyklu, pokud byl nalezen stisknuty radek
}
}
}