|
 |
 |
 |
 | Ansteuerung eines EAeDIP160-7/240-7 Touch-Displays mit einem XMega |
|
rolfdegen
Mitglied

Dabei seit: 11.07.2008
Beiträge: 1.121
Wohnort: Wuppertal
 |
|
.
Das EA eDIP160-7/240-7 ist ein intelligentes LCD Touch Display mit einer Auflösung von 160x104 Pixel bzw. 240x128 Pixel. Es ist mit diversen Grafikfunktionen ausgestattet und besitzt 8 eingebaute Zeichenfonts. Zusätzlich können die Zeichenfonts von 2-40mm gezoomt und um 90/160/270 Grad gedreht werden.
Das Model eDip240-7 unterscheidet sich vom Model eDIP160-7 durch eine höhere Auflösung und einen anderen Versorgungsspannungsbereich. Während das kleinere eDip160-7 mit einer Versorgungsspannung von 3,3V – 5V betrieben werden kann, funktioniert das eDIP240-7 nur mit 5Volt. Die LED-Hintergrundbeleuchtung lässt sich über die Software regeln.
Die Datenübertragung erfolgt entweder über das RS-232 Format oder synchron via SPI oder I²C. Die Schnittstellenauswahl erfolgt über die Anschlussbelegung am Displayport.
Das Analoge Touch-Panel hat ein variables Raster und frei definierbare Tasten und Schalter. Durch Berühren des Displays können hier Eingaben gemacht und Einstellungen per Menü oder Bargraph getätigt werden. Das Zeichnen der einzelnen "Tasten" und Bargraph, sowie das Beschriften wird von der Software im Display übernommen.
Bild 1: EAeDIP160-7 Touch-Display am XMega

Applikationsbeispiel für den SPI Anschluss am XMega
Das eDip160-7/240-7 Display unterstützt insgesamt 4 Anschlussmöglichkeiten u.a. RS-232, RS-485 , USB und SPI. Ich habe mich für den SPI Anschluss entschieden, weil der XMega diese Schnittstelle zur Verfügung stellt und die Datenübertragungsrate zum eDIP-Display laut Herstellerangaben bis zu 3MHz betragen kann. Dabei sollte aber berücksichtigt werden , das zwischen den einzelnen Bytes während der Übertragung Pausen von jeweils min. 100us eingehalten werden müssen.
Bild 2: SPI Anschluss des EADIP160-7 Displays am XMega

Die SPI Datenübertragung
SPI steht für Serial Periphal Interface. Der SPI-Bus besitzt als Zweidrahtbussystem zwei Leitungen für Daten, eine dritte Leitung für den Takt und die vierte Leitung für Slave-Select.
· SDO (Serial Data Out, Datenausgang), auch MOSI genannt (Master Out Slave In)
· SDI (Serial Data In, Dateneingang), auch MISO genannt (Master In Slave Out)
· SCK bzw. CLK (Serial Clock, Takt)
· SS (Slave Select)
Bild 3: Der SPI BUS

Der SPI-Bus arbeitet im Vollduplex-Betrieb. Daten können gleichzeitig in beide Richtungen übertragen werden. Zudem existieren eine Menge Einstellmöglichkeiten für den Bus. Man kann beispielsweise entscheiden, mit welcher Taktflanke eingegeben bzw. ausgelesen werden soll oder auch, ob das MSB (mostsignificant bit, höherwertigstes Bit) oder LSB (least significant bit, niederwertigstes Bit) zuerst übertragen werden soll. Ich habe mich für die Übertragungsart im Rot markierten Rechteck entschieden.
Des Weiteren sind Taktfrequenzen bis in den MHz-Bereich zulässig. Man sollte aber nicht zu lange Leitungen benutzen. In meiner Schaltung takte ich den SPI-Bus mit 1MHz und habe ein ca. 20cm langes ungeschirmtes Verbindungskabel zwischen dem Display und XMega angeschlossen ohne das es zu Übertragungsproblemen kommt.
Im Nächsten Beitrag möchte ich die Ersten Schritte der Programmierung für das Display erklären. Das Abendessen ruft.. bis dahin alles Gute.
Liebe Grüße Rolf
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von rolfdegen: 23.03.2012 18:59.
|
|
23.03.2012 18:55 |
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
rolfdegen
Mitglied

Dabei seit: 11.07.2008
Beiträge: 1.121
Wohnort: Wuppertal
Themenstarter 
 |
|
Datenübertragung zum Display mit aktivierten SMALL PROTOKOLL
Für eine sichere Datenübertragung zum Display ist es empfehlenswert, das SMALL PROTOKOLL zu aktivieren (PIN 17 am Display nicht angeschlossen).
Das Senden von Nutzdaten an das Display ist eingerahmt von <DC1>, der Anzahl der Daten "len" und der Prüfsumme "bcc". Werden die jeweiligen Nutzerdaten übertragen, so sendet das Display als Antwort ein <ACK> zurück.
Um eine Antwort (ACK) vom Display zu empfangen, muss ein Dummy-Byte (zB 0x00) an das Display gesendet werden. Mit dem senden des Dummy-Bytes auf der MOSI-Leitung wird gleichzeitig auf der MISO-Leitung das Quittierungs-Byte vom Display zum XMega zurückgesendet und kann im Anschluss aus dem SPI-Datenregister gelesen werden.
Bild 10: Daten zum Display senden

Bild 11: Dekleration der Steuercodes fürs Display
| php: |
1:
2:
3:
4:
|
#define ESC 0x1B
#define ACK 0x06
#define DC1 0x11
#define DC2 0x12 |
|
Bild 12: Speichert die Empfangsquittierung (ACK) vom Display für die spätere Auswertung
| php: |
1:
|
uint8_t lcd_ack =0; // Empfangsquitierung vom Display |
|
Bild 13: Textstring generieren: "Textstring",Länge, X-Position, Y-Position
| php: |
1:
|
send_string("AEeDIP160-7 mit XMega",21, 17, 20); |
|
Bild 14: Daten in ein Array schreiben
| php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
|
// Datensequenz fürs Display in ein Array schreiben
void send_string(char *string, unsigned char len, unsigned char xpos, unsigned char ypos){
unsigned char buffer[5+len]; // buffer Länge
buffer[0] = ESC; // ESC Steuercode
buffer[1] = 'Z'; // 'Z' für Zeichenkette ausgeben
buffer[2] = 'L'; // 'L' für Linksbündig
buffer[3] = xpos; // x-Position
buffer[4] = ypos; // y-Position
// inc buffer-Pointer für Text-String
volatile uint8_t i; // volatile verhindert hier Optimierungsprobleme des Compilers
for(i=0; i<len; i++)
{
buffer[5+i]=*string++;
}
buffer[5+i]=0; // Textende = 0x00
SendData(buffer,6+len); // Daten ans Display senden
while(lcd_ack!=ACK){ // Quittierung vom Display auswerten
_delay_ms(2000); // wenn ungleich ACK dann nach 2sec Pause nochmal senden-
SendData(buffer,6+len); // bis ein ACK empfangen wurde
}
lcd_ack=0; // Quittierung löschen
} |
|
Bild 15: Datenpaket fürs SMALL PROTOKOLL generieren und zum Display senden
| php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
|
// Datenpaket generieren und zum Display senden
void SendData(unsigned char *buffer, unsigned char len){
volatile unsigned char i, bcc;
PORTC.OUTCLR = (1 << SPI_SS); // SPI_SS Pin auf 0
spi_send(DC1); // send DC1
bcc = DC1;
spi_send(len); // send data length
bcc = bcc + len;
for(i=0; i < len; i++) // Send buf
{
spi_send(buffer[i]);
bcc = bcc + buffer[i];
}
spi_send(bcc); // send checksum
PORTC.OUTSET = (1 << SPI_SS); // SPI_SS Pin auf 1
_delay_us(12); // warten (min. 6us) bis Daten im Display bereit zum senden
PORTC.OUTCLR = (1 << SPI_SS); // SPI_SS Pin auf 0
spi_send(0x00); // ein Dummy-Byte senden um Quittierung (ACK) vom Display zu empfangen
PORTC.OUTSET = (1 << SPI_SS); // SPI_SS Pin auf 1
lcd_ack = SPIC.DATA; // Quittierung speichern
} |
|
Bild 16: Ein Byte ans Display senden
| php: |
1:
2:
3:
4:
5:
6:
|
// Ein Byte über SPI ans Display senden
void spi_send (unsigned char data){
_delay_us(100); // warte bis Display bereit (nur notwendig wenn SPI-Datentransfer schneller als 100KHz)
SPIC.DATA = data; //Sendet ein Byte
while(!(SPIC.STATUS & (1 << SPI_IF_bp))){} //Wartet bis Byte gesendet wurde
} |
|
Gruß Rolf
Dieser Beitrag wurde 4 mal editiert, zum letzten Mal von rolfdegen: 26.03.2012 11:11.
|
|
26.03.2012 10:51 |
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
rolfdegen
Mitglied

Dabei seit: 11.07.2008
Beiträge: 1.121
Wohnort: Wuppertal
Themenstarter 
 |
|
Hallo zusammen und Frohe Ostern
Wie in meinem vorletzten Beitrag erwähnt, möchte ich hier als kleines Beispiel die Initialisierung und Abfrage eines Touch-Schalters auf dem eDIP-Display erklären. Ich habe versucht, die Programmroutinen übersichtlich darzustellen, so das sie für jeder man leicht zu verstehen sind. Wer Fehler findet oder einen besseren Vorschlag hat, kann mich gerne kontaktieren oder hier posten. Ich bin für alles offen.
Als Erstes muss ein Touch-Schalter defeniert werden und die Daten dafür an das Display gesendet werden.
Bild 17: Display-Befehle um Touch-Taster oder Schalter zu definieren

Programmaufruf zur Initialisierung eines Touch-Schalters
| php: |
1:
2:
|
// Initialisiere Touchkey (Schalter-Funktion)
init_touchkey('K',60, 32, 100, 72, 0x01, 0x02, "OK", 2); |
|
Die eigentliche Initialisierungsroutine für einen Touchkey
| php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
|
// init LCD-Touchkey
void init_touchkey(char typ, unsigned char x1, unsigned char y1, unsigned char x2, unsigned char y2, unsigned char down_code,
unsigned char up_code, char *string, unsigned char len){
unsigned char buffer[9+len]; // Buffer Länge
buffer[0] = ESC; // ESC
buffer[1] = 'A'; // Befehl für Touch-Panel
buffer[2] = typ; // Funktion als Touch-Schalter
buffer[3] = x1; // Bereich von x1,y1 nach x2,y2 wird als Schalter definiert.
buffer[4] = y1;
buffer[5] = x2;
buffer[6] = y2;
buffer[7] = down_code; // Rückgabewert beim Drücken der Taste
buffer[8] = up_code; // Rückgabewert beim Loslassen der Taste
// inc Buffer-Pointer für Text-String
volatile uint8_t i=0; // "volatile" verhindert hier Optimierungsprobleme des Compilers
for(i=0; i<len; i++)
{
buffer[9+i]=*string++;
}
buffer[9+i]=0; // Text-String mit einem 0 Byte abschließen
SendData(buffer,10+len); // Daten ans Display senden
while(lcd_ack!=ACK){ // Quittierung vom Display auswerten
_delay_ms(2000); // wenn ungleich ACK dann nach 2sec Pause nochmal senden-
SendData(buffer,10+len); // bis ein ACK empfangen wurde
}
lcd_ack=0; // Quittierung löschen
} |
|
Nach der Initialisierung sollte auf dem Display ein Touch-Schalter wie hier im Bild 18 zu sehen sein.
Bild 18: Touch-Schalter im Display

Bei jeder Betätigung des Schalters wird eine Antwort bzw Rückmeldung im Sendepuffer des Displays gespeichert. Diese Rückmeldung kann über das Small-Protokoll aus dem Display-Sendepuffer gelesen werden.
Bild 19: Daten vom Sendepuffer anfordern

Den Erste Schritt, um Daten aus dem Sendepuffer des Displays zu lesen, ist das senden eines Daten-Strings bestehend aus "<DC2>,1,S,Prüfsumme".
| php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
|
// Inhalt des Sendepuffers anfordern
void lcd_cmdreadpuf(void){
lcd_cmdreadpuf1:
PORTC.OUTCLR = (1 << SPI_SS); // SPI_SS Pin auf 0
spi_send(DC2); // send DC2
spi_send(0x01); // send 1
spi_send('S'); // send 'S'
spi_send(0x66); // send checksum (bcc)
PORTC.OUTSET = (1 << SPI_SS); // SPI_SS Pin auf 1
_delay_us(12); // warten bis Daten im Display bereit zum senden
PORTC.OUTCLR = (1 << SPI_SS); // SPI_SS Pin auf 0
spi_send(0x00); // ein Dummy-Byte senden
while(SPIC.DATA!=ACK){ // Quittierung vom Display auswerten
PORTC.OUTSET = (1 << SPI_SS); // SPI_SS Pin auf 1
_delay_ms(2000); // wenn ungleich ACK dann nach 2sec Pause nochmal senden-
goto lcd_cmdreadpuf1; // bis ein ACK empfangen wurde
}
PORTC.OUTSET = (1 << SPI_SS); // SPI_SS Pin auf 1
lcd_ack=0; // Quittierung löschen
} |
|
Bild 20: Touchkey-Rückmeldungen im Display-Sendepuffer

Der nächste Schritt ist das Auslesen des Sendepuffers im Display
| php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
|
// Daten aus dem Sendepuffer des Displays lesen
void lcd_readpuf(void){
uint8_t len; // Anzahhl Daten im Sendepuffer
uint8_t bcc; // Prüfsumme
uint8_t data; // Daten
lcd_readpuf1:
PORTC.OUTCLR = (1 << SPI_SS); // SPI_SS Pin auf 0
spi_send(0x00); // ein Dummy-Byte senden
if(SPIC.DATA!=DC1) goto lcd_readpuf1; // Puffer leeren bis DC1 empfangen wurde
bcc = bcc+DC1; // Zur Prüfsumme
spi_send(0x00); // ein Dummy-Byte senden
len = SPIC.DATA; // Anzahl der Daten im Sendepuffer speichern (ohne Prüffsumme und DC1)
if (len==0) // Prüfe Anzahl der Daten
{
touch_kennung = 0; // keine Daten vorhanden touch_kennung=0
spi_send(0x00); // ein Dummy-Byte senden
bcc = SPIC.DATA; // Prüefsumme verwerfen
return; // Routine beenden
}
spi_send(0x00); // ein Dummy-Byte senden
data = SPIC.DATA; // ESC lesen und verwerfen
spi_send(0x00); // ein Dummy-Byte senden
touch_kennung=SPIC.DATA; // Touchkennung speichern
switch(touch_kennung){
case 'A': // Rückgabewert von Taster/Schalter
spi_send(0x00); // ein Dummy-Byte senden
touch_anz = SPIC.DATA; // Rückgabewert: 0x01
spi_send(0x00); // ein Dummy-Byte senden
touch_code = SPIC.DATA; // Rückgabewert: Tasten-Code
break;
}
spi_send(0x00); // ein Dummy-Byte senden
bcc = SPIC.DATA; // Prüefsumme verwerfen
PORTC.OUTSET = (1 << SPI_SS); // SPI_SS Pin auf 1
} |
|
Auswertung des Touch-Schalters erfolgt dann im Main-Programm
| php: |
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
|
// Touch-Taste im Display abfragen
void lcd_getkey(void){
lcd_cmdreadpuf(); // Inhalt des Sendepuffers anfordern
lcd_readpuf(); // Displaydaten lesen
}
while(1){
// Touch-Taste abfragen
lcd_getkey();
switch (touch_kennung){
case 'A':
if (touch_code == 0x02){
lcd_font(4);
send_string("PRESS FOR LED ON ", 17, 32, 10);
LED_OUT = 0xFF;
}
if (touch_code == 0x01){
lcd_font(4);
send_string("PRESS FOR LED OFF", 17, 32, 10);
LED_OUT = 0x00;
}
break;
}
_delay_ms(50);
}
} |
|
Gruß Rolf
|
|
07.04.2012 16:40 |
E-Mail |
Beiträge des Benutzers |
zu Buddylist hinzufügen
|
|
|
Impressum - Datenschutzerklärung
|
|  |