Driver pro dotykový displej

Tomáš Hadwiger, UREL, FEEC VUT Brno xhadwi00stud.feec.vutbr.cz

Jan Nedbal, UREL, FEEC, VUT Brno xnedba02stud.feec.vutbr.cz

Obsah:

  1. Úvod

  2. Realizace

  3. Závěr

  4. Literatura

Úvod

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.

Realizace

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
                }

Přerušení ve spodní části obr. 2. Při vyvolání přerušení se nastaví příznak přerušení.


Skenování screenupravá půlka obr. 2. Vstupy komparátoru jsou přednastaveny na multiplexování a vnitřní referenci 1,23V ((bit ACME v registru SFIOR musí být nastaven, stejně tak bit ACBG v registru ACSR), je potřeba vypnout analogový komparátor (bit ADEN v registru ADCSRA je nulový). Následně se skenují postupně jednotlivé sloupce a testuje se, který z řádků je stisknut pomocí funkce F_radek.

    
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)
}

F_radek - Prochází postupně jednotlivé řádky, její návratovou hodnotou je číslice 1 až 3 v závislosti na stisknutém řádku.

        
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:

Skenování screenu

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;
}

F_radek - Prochází postupně jednotlivé řádky, její návratovou hodnotou je číslice 1 až 3 v závislosti na stisknutém řádku.

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
                        }
                }
}       

Vývojový diagram programu pro ovládání touch screenu s použitím komparátoru


Obr.2 Vývojový diagram s použitím komparátoru

Závěr


Touch screen bez problémů funguje a po přiložení prstu na plošku je na display okamžitě vypsána pozice aktuálně stisknuté plošky, bez nutnosti na ni vyvíjet nějak velký tlak. Byl vytvořen i program pro detekci stisku pomocí A/D převodníku, ale toto řešení není tak dobré jako použití komparátoru. Program byl řešen tak, že byl touch screen každých 500ms skenován a následný A/D převod trvá také děle než porovnání komparátorem. Při použití komparátoru mikrokontrolér může vykonávat jinou činnost a jen při stisku plošky je vyvoláno přerušení a spuštěna komparace na jednotlivých řádcích.

Zde je možno stáhnout oba dva kompletní a okomentované zdrojové kódy projektu.


Literatura


[1] Datasheet, ATmega 16 Atmel Dostupné na WWW: http://www.atmel.com/dyn/resources/prod_documents/doc8154.pdf