Maticový touchscreen

Petr Marcoň, UREL, FEEC, VUT Brno
xmarco00feec.vutbr.cz

Martin Ryšánek, UREL, FEEC, VUT Brno

Obsah:

  1. Obecné informace o modulu PG240128WRF-ATA-H-Y7
  2. Řadič T6963c
  3. Dotykový panel
  4. Testovací program
  5. Závěr
  6. Literatura

Obecné informace o modulu PG240128WRF-ATA-H-Y7

LCD modul firmy Powertrip: PG240128WRF-ATA-H-Y7 se skládá z černobílého grafického LCD displeje v provedení FSTN s bílým podsvícením (LCD), inteligentního řadiče T6963c a digitálního odporového dotykového panelu (DP). Rozlišení displeje je 240 x 128 bodů a rozlišení DP je 10 x 5 bodů. Použitý digitální DP pracuje na principu skenování řádků a sloupců.

Dotykový displej

Obr. 1: Modul PG240128WRF

 Projekt je rozdělen na dvě části. V první části je to komunikace MCU s řadičem T6963c a druhá část je komunikace MCU s DP. Modul byl připojen k vývojové desce s MCU ATmega16.

 

ŘADIČ T6963c

 Při programování je nutno nejprve provést inicializaci řadiče. To znamená vyhrazení určité oblasti v paměti pro grafická data, určité oblasti pro text, výběr fontu pro textovou oblast (8x8 nebo 7x5 bodů) a nastavení módu zobrazování displeje. Podrobnější popis programování a příkazů řadiče naleznete přímo v technické dokumentaci k řadiči T6963c [. Po zapnutí napájení se doporučuje provést RESET (alespoň 2 ms) a pak do řadiče zapsat inicializační řetězec (viz tab. 1). Pokud má příkaz parametr, vyšle se nejprve nižší byte dat, poté vyšší byte dat a nakonec příkaz. Princip komunikace mikroprocesoru s řadičem, zápis příkazu a dat je na obr. 1.

Příkaz

Kód

Parametry

Funkce

TEXT HOME ADRESS

40h

0x00, 0x00

Začátek textové oblasti paměti displeje na adrese 0x00.

TEXT AREA

41h

0x1E, 0x00

Počet znaků na řádek 30 = 0x1E, při FS= „L“.

GRAPHIC HOME ADRESS

42h

0x00, 0x02

Začátek textové oblasti paměti displeje na drese 200h.

GRAPHIC AREA

43h

0x1E, 0x00

Délka řádky v pocelech 240/8=30 = 0x1E.

MODE SET

81h

 

Textový mód EXOR

ADRESS POINTER SET

24h

0x00, 0x00

Umístění adresového ukazatele na místo kde budete číst či zapisovat.

DISPLAY MODE SET

98h

 

Zobrazení textu vypnuto, grafická oblast zapnuta.

Tab. 1:          Příklad inicializaci řadiče T6963.

Zápis příkazu či dat probíhá tak, že se nejprve testuje tzv. Status (STA0=1 a STA1=1 pro normální režim nebo STA2=1 a STA3=1 pro režim auto) pro připravenost zápisu bytu do displeje. Jakmile je podmínka Status splněna, tak se nastaví pin C/D, vyšle byte na sběrnici a nastavením WR=„ L“ a po minimálně 150ns WR=„ H“ se data odešlou do řadiče.

 

Obr 2:         Vývojové diagramy.

V projektu byly použity již vyvinuté ovladače pro řadič T6963c (viz [2]). Knihovny byly upraveny pro displej s rozlišením 240x128 pixelů. Do hlavního souboru se připojí klasicky:

#include<t6963c.h>

Jako datová sběrnice byl zvolen PORTA MCU ATmega16. Datová sběrnice je obousměrná, musí se přepínat směrový registr DDRA dle požadovaného směru toku dat. To je ovšem již vyřešeno v knihovně t6963c.h, kde stačí k jednotlivým portům a pinům přiřadit definice. Pro řídící signály je zvolen PORTC, který je pouze jednosměrný, výstupní, DDRC = 0xFF. Pro náš případ stačí v hlavičkovém souboru t6963c uvést následující definice:

// definice datového portu
#define GLCD_DATA_PORT PORTA 			// PORTA 
#define GLCD_DATA_PIN PINA
#define GLCD_DATA_DDR DDRA
// definice portu, kde jsou umístěný řídící signály
#define GLCD_CTRL_PORT PORTC 			// řídící signály 
#define GLCD_CTRL_PIN PINC
#define GLCD_CTRL_DDR DDRC
// definice jednotlivých řídícíh signálů
#define GLCD_WR 	PC2
#define GLCD_RD 	PC3
#define GLCD_CE 	PC0
#define GLCD_CD 	PC1
#define GLCD_RESET 	PC4
#define GLCD_FS 	PC5
// parametry displeje
#define GLCD_NUMBER_OF_LINES 128
#define GLCD_PIXELS_PER_LINE 240
#define GLCD_FONT_WIDTH 8
Dotykový panel

Princip snímání dotyku je naznačen na obr. 3. Jednotlivé řádky jsou nastaveny jako výstupy MCU a jednotlivé sloupce jsou připojeny jako vstupy, u kterých jsou aktivovány pull-up rezistory. Princip funkce spočívá v tom, že MCU cyklicky vysílá signál „L“ do jednotlivých řádků (do řádků které mají být aktivní) ostatní řádky jsou v úrovni „H“. V místě dotyku se propojí vrstva příslušného řádku a sloupce. Tím se dostane úroveň „L“ do sloupce, ve kterém byl proveden dotyk, který vyhodnotí MCU.

R1C1

R1C2

R1C3

R1C4

R1C5

R1C6

R1C7

R1C8

R1C9

R1C10

R2C1

R2C2

R2C3

R2C4

R2C5

R2C6

R2C7

R2C8

R2C9

R2C10

R3C1

R3C2

R3C3

R3C4

R3C5

R3C6

R3C7

R3C8

R3C9

R3C10

R4C1

R4C2

R4C3

R4C4

R4C5

R4C6

R4C7

R4C8

R4C9

R4C10

R5C1

R5C2

R5C3

R5C4

R5C5

R5C6

R5C7

R5C8

R5C9

R5C10

Obr 3:         Princip snímání dotyku na digitálním odporovném DP.

Úkolem projektu bylo napsat knihovnu pro DP. Ta byla napsána co možná nejuniverzálněji. Pro vstupy byl použit PORTB a částečně PORTD, pro výstupy byl použit PORTD. Definice jednotlivých vstupů a výstupů:

#define TOUCH_COL_PORT PORTB 		// definování portu pro sloupce 
#define TOUCH_COL_PIN PINB		
#define TOUCH_COL_DDR DDRB 		// všechny sloupce jsou nastaveny jako vstupní

#define TOUCH_CLRW_PORT PORTD 		// port pro sloupce i řádky
#define TOUCH_CLRW_PIN PIND
#define TOUCH_CLRW_DDR DDRD 		// A[0..4] výstupy, A[6,7] vstupy

#define COL_1 PB0			// definice sloupců
#define COL_2 PB1
#define COL_3 PB2
#define COL_4 PB3
#define COL_5 PB4
#define COL_6 PB5
#define COL_7 PB6
#define COL_8 PB7
#define COL_9 PD6 			
#define COL_10 PD7

#define ROW_1 PD0			// definice řádků
#define ROW_2 PD1
#define ROW_3 PD2
#define ROW_4 PD3
#define ROW_5 PD4

Testovací program

void touch_init( void ) 
{
	TOUCH_COL_DDR = 0x00; 	// Port pro sloupce je definován jako vstupní
	TOUCH_CLRW_DDR = 0x00; 	// Port pro sloupce je definován jako vstupní 
	// Nastavení řádků jako výstupy
	TOUCH_CLRW_DDR = ((_BV(5))|(_BV(ROW_1))|(_BV(ROW_2))|(_BV(ROW_3))|(_BV(ROW_4))|(_BV(ROW_5)));TOUCH_COL_PORT = 0xFF; // Nastavení pull up rezistorů pro všechy vstupy
	TOUCH_CLRW_PORT = 0xFF; // Nastavení pull up rezistorů pro všechy vstupy a zároveň 
				// vyslání logických jedniček na výstupy
}
Hlavním úkolem bylo vytvořit knihovnu pro ovládání touchscreenu. Funkce jsou napsány co možná nejuniverzálněji a je hojně využito bitových "kouzel". Funkce využívá dvě proměnné třídy extern int Tx,Ty, takže po připojení knihovny jsou tyto proměnné vidět i v hlavním souboru. Proměnné Tx a Ty udávají souřadnice stisknuté pozice na displeji. Pro zjištění dotyku je třeba nejdříve touchscreen inicializovat funkcí touch_init():
Když je provedena inicializace, stačí k určení místa  dotyku použít funkci touch():

void touch ( void )
{Tx = 0;
 Ty = 0;

	TOUCH_CLRW_PORT |= (_BV(ROW_5)); 	// nulování prvního řádku
	TOUCH_CLRW_PORT &= ~(_BV(ROW_1));
	Toch_Col_Test ();
	if (Tx) { Tx=0;
	Toch_Col_Test ();
	if (Tx) Ty=1;
	TOUCH_CLRW_PORT |= (_BV(ROW_1)); 	// nastavení prvního řádku
	}
	else
		{
		TOUCH_CLRW_PORT |= (_BV(ROW_1)); // nulování druhého řádku
		TOUCH_CLRW_PORT &= ~(_BV(ROW_2));
		Toch_Col_Test ();
		if (Tx) { Tx=0;Ty=0;
		Toch_Col_Test ();
		if (Tx) Ty=2;
		TOUCH_CLRW_PORT |= (_BV(ROW_2)); // nastavení prvního řádku
		}
		else
			{
			TOUCH_CLRW_PORT |= (_BV(ROW_2)); // nulování třetího řádku
			TOUCH_CLRW_PORT &= ~(_BV(ROW_3));
			Toch_Col_Test ();
			if (Tx) 
			{ Tx=0;Ty=0;
			Toch_Col_Test ();
			if (Tx) Ty=3;
			TOUCH_CLRW_PORT |= (_BV(ROW_3)); // nastavení prvního řádku
			} 
			else
				{
				TOUCH_CLRW_PORT|= (_BV(ROW_3)); // nulování čtvrtého řádku
				TOUCH_CLRW_PORT &= ~(_BV(ROW_4));
				Toch_Col_Test ();
				if (Tx) 
				{ Tx=0;Ty=0;
				Toch_Col_Test ();
				if (Tx) Ty=4;
				TOUCH_CLRW_PORT |= (_BV(ROW_4)); // nastavení prvního řádku
				} 
				else
					{
					TOUCH_CLRW_PORT |= (_BV(ROW_4)); // nulování pátého řádku
					TOUCH_CLRW_PORT &= ~(_BV(ROW_5));
					Toch_Col_Test ();
					if (Tx) 
					{ Tx=0;Ty=0;
					Toch_Col_Test ();
					if (Tx) Ty=5;
					TOUCH_CLRW_PORT |= (_BV(ROW_5)); // nastavení prvního řádku
					} 
					} //else 4
				} // else 3
		} // else 2
	} //else */
}
/***********************************************************************
Funkce pro testování sloupců
************************************************************************/
void Toch_Col_Test (void)
{ _delay_ms( 100 ) ; 				    // zpoždění 100ms, kvůli ošetřeni stisku
	if bit_is_clear (TOUCH_COL_PIN,COL_1) Tx=1; // testování vstupů
	if bit_is_clear (TOUCH_COL_PIN,COL_2) Tx=2;
	if bit_is_clear (TOUCH_COL_PIN,COL_3) Tx=3;
	if bit_is_clear (TOUCH_COL_PIN,COL_4) Tx=4;
	if bit_is_clear (TOUCH_COL_PIN,COL_5) Tx=5;
	if bit_is_clear (TOUCH_COL_PIN,COL_6) Tx=6;
	if bit_is_clear (TOUCH_COL_PIN,COL_7) Tx=7;
	if bit_is_clear (TOUCH_COL_PIN,COL_8) Tx=8;
	if bit_is_clear (TOUCH_CLRW_PIN,COL_9) Tx=9;
	if bit_is_clear (TOUCH_CLRW_PIN,COL_10) Tx=10;
_delay_ms( 10 );
}

Funkce touch(); Naplní hodnotu Tx a Ty souřadnicemi stisknutého dotykového bodu, od bodu Tx=1, Ty=1 do Tx=10, Ty=5.

Příklad využití vytvořených funkcí (podrobnosti najdete přímo v přiložených souborech):

#include "T6963C\t6963c.h"
#include "TOUCH\touch.h"

int main(void)
{
touch_init();          				// Inicializace dotykového panelu
GLCD_InitalizeInterface();
GLCD_Initalize();                               // Initalizace LCD displeje
GLCD_ClearText();                               // Smazání texthové oblasti
GLCD_ClearGraphic();                            // Smazání grafickí paměti

//---------- Výpis textu na displej---------
GLCD_TextGoTo(6,1);                             // nastavení pozice kurzoru
GLCD_WriteString("Touchscreen test");           // write text
GLCD_TextGoTo(8,3);                             // nastavení pozice kurzoru
GLCD_WriteString("MMIA PROJEKT");        	// write text
GLCD_TextGoTo(1,4);                             // nastavení pozice kurzoru
GLCD_WriteString("---------------------------");

GLCD_TextGoTo(1,6); 
GLCD_WriteString("Souradnice stisknute pozice:"); 

GLCD_TextGoTo(1,8); 
GLCD_WriteString("Souradnice x:"); 
GLCD_TextGoTo(1,10); 
GLCD_WriteString("Souradnice y:"); 

//- Smyčka ve které se testuje místo dotyku -
while (1)
{
	touch();                                        // funkce která vrácí informaci o stisku
	lcd_buffer[0]=Tx+48;                            // převedení čísel na CHAR
	lcd_buffer[1]=Ty+48;
	GLCD_TextGoTo(15,8);
	if (lcd_buffer[0] == 58) GLCD_WriteString("10"); // nastavení pozice výpisu souřadnice X
	else GLCD_WriteChar(lcd_buffer[0]);             // vypsání souřadnice X 
	GLCD_WriteString(" ");
	GLCD_TextGoTo(15,10);                           // nastavení pozice výpisu souřadnice Y
	GLCD_WriteChar(lcd_buffer[1]);                  // vypsání souřadnice Y
	
	if (Tx!=0) PORTD |=_BV(5);                      // Pro kontrolu se při jakémkoli stisknu
	else PORTD &= ~(_BV(5));                        // rožne dioda D3 na vývojové desce
} //while 
Na následujícím obrázku je vidět naprogramovaná testovací aplikace, kdy jsou vypisovány souřadnice stisknutého dotykového bodu:
Testovací aplikace na dotykovém displeji

Obr. 4: Testovací aplikace.

Rovněž bylo natočeno video (bohužel nekvalitní, ale vidět jednotlivé souřadnice lze), jak dotykový panel funguje.
Na závěr je ještě uvedena fotka zapojení a schéma zapojení, úmyslně není využito sběrnic, aby bylo vidět co kam je připojeno.
zapojení k vývojové desce
Obr. 5: Připojení modulu k vývojové desce.
schema zapojeni
Obr. 6: Schéma připojení modulu k vývojové desce.
Zde je možné si stáhnout přímo zdrojové soubory jednotlivých knihoven a rovněž testovací program:
Hlavičkový soubor pro řadič T6963c: t6963c.h
Knihovna pro řadič T6963c: t6963c.c		
Hlavičkový soubor pro touchscreen: touch.h
Knihovna pro touchscreen:touch.c
Testovací program (viz obr. 4 a video): Testovací program		

Závěr

Dle zadání byla napsána knihovna pro ovládání dotykového displeje. Byl napsán testovací program, ve kterém se na displeji vypisují souřadnice stisknutého dotykového bodu. Pro zapojení LCD modulu do vývojové destičky (schéma na disku "L" v předmětu MMIA) pouze pomocí drátků. Jelikož připojení dotykového panelu k MCU zabere 15 pinů je lépe použít multiplexor. U displeje není dle mého názoru vhodná vícenásobná manipulace s konektorem (tedy zasunutí a opět vysunutí). Nanesený kovový materiál tvořící konektory totiž je velmi náchylný na mechanické zacházení a snadno se naruší. Proto by bylo dobré, kdyby se vytvořila destička třeba přímo pro vývojovou desku v laboratoři a byl zde displej pevně osazen i s konektorem pro DP, který by se již nevytahoval a nebyl nijak mechanicky namáhán. Přesto že s konektorem bylo zacházeno šetrně, vždy zanechá konektor nějakou stopu. Rovněž tyto materiály nanesené na plastové podložce tvořící konektory jsou velmi náchylné na teplotu=>pokud se bude pájet konektor v desce (samice)  musí být samec vyndán. Deska plošný spojů v tomto projektu vytvořena nebyla, protože to nebylo v zadání a navíc spoustu času zabralo vůbec displej "rozchodit". Při vložení do vlastní aplikace je dobré promyslet časování a případně využít Timer counter a povolit od něj přerušení. Potom vždy když nastane přerušení, zkontrolovat dotyk funkcí touch(). Musí se počítat s tím, že průběh funkce trvá asi 110ms kvůli ošetření zákmitů.

Literatura

[1] Datalist řadiče T6963C. [online]. 2009 – [cit.25. duben 2009]. Dostupné na WWW:  < http://www.alldatasheet.com/datasheet-pdf/pdf/143332/TOSHIBA/T6963CDS.html >.

[2] Knihovny k řadiči T6963C. [online]. 2009 – [cit. 25. duben 2009]. Dostupné na WWW:  < http://en.radzio.dxp.pl/t6963/ >.