mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik SED1520: Lesen vom Display


Autor: Christian L. (logos23)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag,

ich habe mir das Adapter-Board DG-12232 von Pollin gekauft. Das Graphik 
LCD wird mittels zwei SED1520-DAA Controller angesteuert.
Hier in dem Forum gab es ja bereits einige Diskussionen darüber (Für 
mich hat das keine Hilfe gebracht).

Mein Problem liegt beim Auslesen vom Display.
Wenn ich Daten vom Display lesen möchte, wird immer 0xFF bzw. 0xD8 
gelesen. Als Test habe ich eine Spalte mit unterschiedlicher Pixelanzahl 
und -anordnung getestet.
Der einzige Beitrag, der das gleiche Problem hatte, gab als Lösung 
Zeitpausen ("nops") einfügen an.
Dies habe ich auch versucht, leider ohne Ergebnis.
Im Datenblatt (Anhang) steht der /RD Pin muss auf Low gezogen werden, 
allerdings benutze ich das Protokoll der 68er Familie und meines 
Erachtens benötigt diese den RD nicht (habe ihn auf VDD angeschlossen, 
auf Low würde er den externen Takt aktivieren).
Der Dummy Read wird im Datenblatt als Muss angegeben (wegen Interner 
Bus-Leitung?).

Der Quellcode (von hier: 
http://www.mikrocontroller.net/attachment/8373/lcd...
unsigned char GLCD_ReadData(void)
{
unsigned char tmp;

GLCD_WaitForStatus(0x80, 0);            //Busy-Flag abfragen
GLCD_WaitForStatus(0x80, 1); 
SED1520_CONTROL_PORT |= SED1520_A0;     //Daten  (nicht Befehl)
SED1520_CONTROL_PORT |= SED1520_RW;     //von Display lesen

SED1520_DATA_DDR = 0x00;           //Daten-Register auf Eingang schalten
SED1520_DATA_PORT = 0xFF;          //Interne Pull-Ups einschalten
if(lcd_x < 61)
    {
  SED1520_CONTROL_PORT |= SED1520_E1;    //Zu Beginn ein "Dummy-Read"
    asm("nop");asm("nop");             //die Daten werden dann vom nächsten
    SED1520_CONTROL_PORT &= ~SED1520_E1;  //Aufruf dann sicher abgefragt
  asm("nop");asm("nop"); 
  asm("nop");asm("nop"); 
  tmp = SED1520_DATA_PIN;  
  asm("nop");asm("nop");       //
  SED1520_CONTROL_PORT &= ~SED1520_E1; 
  }
else 
    {  
    SED1520_CONTROL_PORT |= SED1520_E2;
    asm("nop");asm("nop"); 
    SED1520_CONTROL_PORT &= ~SED1520_E2;
  asm("nop");asm("nop");
  SED1520_CONTROL_PORT |= SED1520_E2;
  asm("nop");asm("nop"); 
  tmp = SED1520_DATA_PIN;  
  SED1520_CONTROL_PORT &= ~SED1520_E2; 
  }

SED1520_DATA_DDR = 0xFF;           //Datenregister wieder auf Ausgang
lcd_x++;                   //Spaltenvektor inkrementieren
if(lcd_x > 121)                
  lcd_x = 0;
return tmp;
} 


Im Hauptprogramm:
GLCD_GoTo(0,0);           //dort befindet sich das Pixelmuster
test1 = GLCD_ReadData(); //unsigned char Ausgabe
GLCD_GoTo(0,1);          //Page 2, Spalte 0
GLCD_WriteHex(test1);    //Hexadezimale Ausgabe 
Ich habe gestern den ganzen Abend damit verbracht, den Denkfehler zu 
finden. Auch wenn es für mich keinen Sinn gemacht hat, habe ich für den 
RD Pin eine extra Leitung an meinen ATmega8 spendiert und diesen dann 
beim Auslesen auf Low gesetzt. Natürlich hat das nichts gebracht.
Kann es sein, dass man nur mit dem 80er Protokoll Daten vom Display 
auslesen kann?

Über Hilfe wäre ich euch sehr verbunden.

Wünsche noch einen schönen Tag
B. Christian

Autor: logos23 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen,

Entschuldigt die Aufdringlichkeit, aber ich würde wirklich gerne 
verstehen, warum der Read-Befehl nicht funktioniert.
Da ich Daten ans Display schicken kann und der Pin für Read bzw. Write 
der selbe ist, kann es eig. kein Hardware Problem sein, sondern muss 
einzig an der Sub-Routine ReadData() liegen.

Ich komme einfach nicht mehr weiter. Im Internet finden sich neben den 
Datenblatt leider nichts sinnvolles.

Liebe Grüße
Christian B.

Autor: Matthias K. (matthiask)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe vor längerer Zeit mal mit SED1520 gearbeitet (8051er). Read klappte 
damals. Kuck mal nach "READ-MODIFY ON". Unten paar Programmauszüge.
// ***********************************************************************
// Zeichen eines Punktes positioniert
// Übergabe: lcd_x: X-Koordinate 0...121
//           lcd_y: Y-Koordinate 0..31
//           mode:  0=Pixel löschen 1=Pixel setzen
// ***********************************************************************
void draw_clear_pixel(byte lcd_x, byte lcd_y, bit mode) {
byte code mask_bit_tab[] = {
   0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
   0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
   0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80,
   0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80}; 
byte idata mask_bit;
bit display_seite;  // 0=linke 1=rechte Displayhälfte je 0...60
  if (lcd_x < 61) {
    display_seite = 0;
    write_lcd_command(lcd_x,0);             // Colum links
    write_lcd_command(0xB8 + lcd_y/8,0);    // Zeile/Page 0...3 linke Hälfte    
  } else {
    display_seite = 1;
    write_lcd_command(lcd_x - 61,1);        // Colum rechts
    write_lcd_command(0xB8 + lcd_y/8,1);    // Zeile/Page 0...3 linke Hälfte    
  }
  mask_bit = mask_bit_tab[lcd_y];
  write_lcd_command(0xE0,display_seite);    // Read Modify ON
  read_lcd_data(display_seite); // Dumy-Read laut Datenblatt SED1520
  if (mode) {
    // Pixel setzen
    write_lcd_data(read_lcd_data(display_seite) | mask_bit,display_seite);
  } else {
    // Pixel löschen
    write_lcd_data(read_lcd_data(display_seite) & ~mask_bit,display_seite);
  }
  write_lcd_command(0xEE,display_seite);    // Read Modify END
} 
// ***********************************************************************
// Lesen eines Zeichens (Daten) vom LCD-Modul
// lesen erfolgt aus aktuelle Page/Colum Einstellung
// Übergabe: lcd_teil: 0 - linke Displayhälfte
//                     1 - rechte Displayhälfte
// Rückgabe: Byte: Gelesenes Zeichen
// ***********************************************************************
byte read_lcd_data(byte lcd_teil) {
byte idata lcd_busy = 1;
byte idata lcd_byte;

  // Testen ob LCD-Modul noch im internen Zyklus ist
   LCD_RW = 1;
   LCD_A0 = 0;
   while(lcd_busy) {
     if (!lcd_teil) LCD_E1 = 1; else LCD_E2 = 1;
     _asm nop; nop; nop; _endasm;     // Impulsverzögerung  
     if (!(LCD_DATA & 0x80)) lcd_busy = 0; // BUSY-Flag abfragen
     if (!lcd_teil) LCD_E1 = 0; else LCD_E2 = 0;
     _asm nop; nop; nop; _endasm;     // Impulsverzögerung      
   }
   _asm nop; nop; nop; _endasm;     // Impulsverzögerung (nur bei hoher Frequenz)
   // LCD-Anzeige ist zum Auslesen neuer Zeichen bereit
   LCD_RW = 1;
   LCD_A0 = 1;
   if (!lcd_teil) LCD_E1 = 1; else LCD_E2 = 1;
    _asm nop; nop; nop; _endasm;     // Impulsverzögerung
    lcd_byte = LCD_DATA; // Byte vom LCD-Display einlesen
   if (!lcd_teil) LCD_E1 = 0; else LCD_E2 = 0;
   return lcd_byte;
} 

Autor: logos23 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey, danke für die Mühe und die Antwort.

Also so wie ich deinen Code lese, hast du es ja genauso gemacht wie ich. 
Der einzige Unterschied ist der Dummy Read, den du nicht machst (aber im 
Datenblatt verlangt wird?).
Kann es möglich sein, dass das Ding in irgendeiner Form einen internen 
Defekt hat ? (Kann ich mir nur sehr schwer vorstellen)

Gruß
Christian

Autor: Matthias K. (matthiask)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>read_lcd_data(display_seite); // Dumy-Read laut Datenblatt SED1520

...und was ist das?

Autor: logos23 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Matthias K. schrieb:
>>read_lcd_data(display_seite); // Dumy-Read laut Datenblatt SED1520
>
>
>
> ...und was ist das?

Verzeihung, habe mir nur den unteren Teil angeschaut.
Also mir fällt wirklich nichts mehr ein. Weißt du noch was du mit der 
/RD Leitung (sofern die bei dir rausgeführt wurde) gemacht hast?

Fällt dir spontan sonst noch etwas ein, was falsch sein könnte. Ich bin 
sichtlich verzeifelt.

Achja. READ-MODIFY ON. Inwiefern nutzt du das ? Ich dachte das braucht 
man, nur für Curor Blinken.
Lässt du das dauerhaft auf Aktiv?

Autor: Matthias K. (matthiask)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe damals ein DIP122 von http://www.lcd-module.de mit 2x SED1520 
Controller benutzt. Ich erinnere mich noch, dass ich die Unterscheidung 
der 2 Mode 80/68 damals auch nur schwer verstanden habe.

Habe dann auch das 68-Protokoll verwendet. \RD ist dann der E-Pin und 
\WR wird zu R/W. Festgelegt wird das durch den RESET-Pin. H in diesem 
Falle für das 68er Protokoll.

READ-MODIFY ON
Legt fest ob nach Read auch die Spalte erhöht werden soll.

Autor: logos23 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ja habe ich auch so interpretiert und deshalb ist bei mir RD dauerhaft 
auf Vdd.
Habe jezt weiter mit nops gearbeitet und deine Version ebenfalls in 
abgewandelter Form versucht:
 
unsigned char GLCD_ReadData() {
  unsigned char tmp; 
  // Testen ob LCD-Modul noch im internen Zyklus ist
  SED1520_CONTROL_PORT &= ~SED1520_A0;     
  SED1520_CONTROL_PORT |= SED1520_RW;   

  GLCD_WaitForStatus(0x80, 0); 
  GLCD_WaitForStatus(0x80, 1); 
   asm("nop");asm("nop");asm("nop");       // Impulsverzögerung (nur bei hoher Frequenz)
   
   // LCD-Anzeige ist zum Auslesen neuer Zeichen bereit
    SED1520_CONTROL_PORT |= SED1520_RW;      //vermutlich überflüssig?
    SED1520_CONTROL_PORT |= SED1520_A0;
    
  if(lcd_x < 61)
    {
  SED1520_CONTROL_PORT |= SED1520_E1;    
    asm("nop");asm("nop"); asm("nop");     
  tmp = SED1520_DATA_PIN;  
  SED1520_CONTROL_PORT &= ~SED1520_E1; 
  }
  else 
    {  
  SED1520_CONTROL_PORT |= SED1520_E2;    
    asm("nop");asm("nop"); asm("nop");     
  tmp = SED1520_DATA_PIN;  
  SED1520_CONTROL_PORT &= ~SED1520_E2;  
  }
 return tmp;
} 

Im Hauptprogramm:
GLCD_WriteString("__"); 
GLCD_GoTo(0,0); 

GLCD_WriteCommand(READ_MODIFY_WRITE, 0);GLCD_WriteCommand(READ_MODIFY_WRITE, 1);
  GLCD_ReadData(); test1 = GLCD_ReadData(); 
GLCD_WriteCommand(END_READ_MODIFY, 1);GLCD_WriteCommand(END_READ_MODIFY, 1);
GLCD_GoTo(0,1); GLCD_WriteHex(test1);

Nun gibt er zwar 0x1F aus, allerding unabhägig davon was an der Stelle 
0,0 steht in dem Beispiel hier müsste eig. 0x40 rauskommen (bei 5x7 
font).

Entweder ich habe etwas elementares vergessen, oder ich muss mich 
langsam damit zufrieden geben, dass ich keine Daten einlesen kann. (was 
ziemlich demotivierend wäre)

Autor: Matthias K. (matthiask)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Das lesen muss auf jedem Fall gehen.

Was meinst Du überhaupt, mit RD dauerhaft auf H? RD ist doch der 
betreffende E Pin.

Der Controller ist eigentlich recht schnell, glaube kaum das es an 
fehlenden Nops liegt. Eventuell takte den µC mal langsamer.

> tmp = SED1520_DATA_PIN;

Sehe nicht, das Du den auf Input gesetzt hast?

Autor: logos23 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vielen Dank für deine Mühe,

hatte vorher keine Zeit zu antworten.
- Das DDR habe ich als Eingang geschalten; hatte ich vergessen in den 
Quellcode mit reinzuschreiben, das ist es also nicht.
- Ich arbeite sowieso zu Beginn immer mit dem internen 1-MHz-Takt (in 
der Hoffnung eine Fehlerquelle weniger zu haben).
- /RD ist bei mir fest auf High-Pegel.
  Datenblatt (S.21)=> E(RD) Chip interfaced with 68 family MPU:
       Enable Clock signal input for the 68 family MPU.
  Er dient nur für den einen Zweck, das LCD am Laufen zu halten.

Etwas interssantes hat sich jetzt herausgestellt, als ich im Main statt 
mit Define-Namen die Hexadezimal Sequenzen in den Aufrufen benutzt habe.
GLCD_WriteCommand(0x00, 0); //SpaltenCursor
GLCD_WriteCommand(0xB8, 0); //ZeilenCursor

GLCD_WriteCommand(0xE0, 0); GLCD_WriteCommand(0xE0, 1);    //Modify
GLCD_ReadData(); test1 = GLCD_ReadData(); 
GLCD_WriteCommand(0xEE, 0);  GLCD_WriteCommand(0xEE, 1);  //Modify aus
Er ließt mir dann 0xE0 aus, also die letzte Zahl vor dem Read

GLCD_WriteCommand(0x00, 0); //SpaltenCursor
GLCD_WriteCommand(0xB8, 0); //ZeilenCursor

//GLCD_WriteCommand(0xE0, 0); GLCD_WriteCommand(0xE0, 1);    //Modify
GLCD_ReadData(); test1 = GLCD_ReadData(); 
//GLCD_WriteCommand(0xEE, 0);  GLCD_WriteCommand(0xEE, 1);  //Modify aus
Hier ließt er 0xB8, auch wieder die lezte Hexadezimal Zahl.

Dachte schon mein A0 ist in irgendeiner Form invertiert, allerdings wird 
bei einem A0 =0 in der Read-Funktion immer 0x40 ausgegeben. Scheint also 
schon zu passen.
Stellt sich bei der Schilderung eine mögliche Fehlerquelle heraus?

Anmerk.: Der Übersicht wegen, habe ich hier nur den Cursor der linken 
Hälfte, aus der ich auch lesen will reinkopiert.

Autor: Matthias K. (matthiask)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ohne Deinen vollständigen Quellcode und Schaltplan ist alles nur 
Rätselraten und Zeitverschwendung.

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>- /RD ist bei mir fest auf High-Pegel.
>  Datenblatt (S.21)=> E(RD) Chip interfaced with 68 family MPU:
>       Enable Clock signal input for the 68 family MPU.
>  Er dient nur für den einen Zweck, das LCD am Laufen zu halten.

Und was ist dann dein SED1520_E1/SED1520_E2?

MfG Spess

Autor: logos23 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Verzeihung,
im Anhang der Quellcode,
die Anschaltung:
/*
µC:   ATmega8
f_CPU:  1Mhz

1 A0        -  PC0
2 CS2       -  PC1
3 CS1       -  PC2
4 CL        -  not connected
5 /RD(E)    -  5 V
6 /WR (R/W) -  PC4
7 Vss       -  GND
8-15 DB0-7  -  PD0-7
16 Vdd      -  5 V
17 Res      -  PC5
18 VEE      -  -3.0 V

19,20 EL-Hintergrundbeleuchtung - not connected
*/

Autor: logos23 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
spess53 schrieb:
> SED1520_E1/SED1520_E2?
E1 = CS1, E2 = CS2

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>> SED1520_E1/SED1520_E2?
>E1 = CS1, E2 = CS2

Das ist Blödsinn. CS1/CS2 sind die Chipselect Signale um jeweils einen 
1520 auszuwählen.

Schreiben: Fallende Flanke von E -> 1520 übernimmt Daten vom Bus
Lesen    : Steigende Flanke von E -> 1520 legt Daten auf den Bus

MfG Spess

Autor: logos23 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Datenblatt z.B Seite 9
Für die 68er Family gibt es (wenn ich es richtig interpretiere) nur den 
A0 und RW Pin als Steuerleitungen, daneben noch CS1/2 für chip select.
Ich bin dir dankbar, wenn du mich aufklärst
Liebe Grüße
Christian

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Für die 68er Family gibt es (wenn ich es richtig interpretiere) nur den
>A0 und RW Pin als Steuerleitungen, daneben noch CS1/2 für chip select.

Dann sieh dir mal S.36 im Datenblatt an. Dort ist das Timing.

Mit den CS-Leitungen wählst du den 1520 aus, auf den du Schreiben oder 
von dem du Lesen willst. Mit E wird der Datenverkehr gesteuert. Bei der 
Initialisierung kannst du übrigens beide Chips auswählen und beide 
Controller parallel initialisieren.

MfG Spess

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Datenblatt z.B Seite 9

Dort steht:

The SED1520 uses a combination of A0, E, R/W, (RD, WR) to identify a 
data bus signal

MfG Spess

Autor: logos23 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hm, das klingt für mich logisch.
Nur wenn ich den /RD Pin (PB1), was ja im 68er der scheinbare E-Pin ist 
an meinen ATmega führe und ihn in der Read-Funktion mit unterbringe. 
Wird nichts mehr ab dem Zeitpunkt auf dem Display angezeigt.
 DDRB |= (1<<PB1); PORTB |= (1<<PB1); //E im Init 
  
PORTB &= ~(1<<PB1); //schneller Test  
PORTB |= (1<<PB1);

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>Hm, das klingt für mich logisch.

Ist es auch.

>Nur wenn ich den /RD Pin (PB1), was ja im 68er der scheinbare E-Pin ist
>an meinen ATmega führe und ihn in der Read-Funktion mit unterbringe...

Du wirst da etwas mehr überarbeiten müssen. Deine Write-Funktion ist ja 
auch nicht ganz richtig.

MfG Spess

Autor: logos23 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Ok,

ich habe den Code jetzt bearbeitet.
Ich habe bisher eig. nur Librarys nachvollzogen und nicht selbst etwas 
alleiniger Hilfe vom Datenblatt geschrieben.
Bezogen auf Seite 36 vom Datenblatt (danke spess53) habe ich versucht 
eine Funktion zu erstellen:
unsigned char GLCD_ReadData(void)
{
unsigned char tmp;

GLCD_WaitForStatus(0x80, 0); 
GLCD_WaitForStatus(0x80, 1);        //Busy-Flag abfragen

SED1520_CONTROL_PORT |= SED1520_CS1| SED1520_CS2| SED1520_E;  //Vor-Initialisierung  
asm("nop");asm("nop"); 

SED1520_CONTROL_PORT &= ~SED1520_E;  
SED1520_CONTROL_PORT |= SED1520_A0;     //Daten  (nicht Befehl)
SED1520_CONTROL_PORT |= SED1520_RW;     //von Display lesen
 
if(lcd_x < 61) SED1520_CONTROL_PORT &= ~SED1520_CS1; 
 else SED1520_CONTROL_PORT &= ~SED1520_CS2; 

asm("nop");asm("nop");

SED1520_DATA_DDR = 0x00;           //Daten-Register auf Eingang schalten
SED1520_DATA_PORT = 0xFF;          //Interne Pull-Ups einschalten
asm("nop");asm("nop"); 

SED1520_CONTROL_PORT |= SED1520_E;      //Positive Flanke für Befehlsübernahme
tmp = SED1520_DATA_PIN;  
asm("nop");asm("nop");

SED1520_CONTROL_PORT &= ~SED1520_E; 
SED1520_DATA_DDR = 0xFF;           //Datenregister wieder auf Ausgang

asm("nop");asm("nop");
SED1520_CONTROL_PORT &= ~SED1520_A0 & ~SED1520_RW;  
SED1520_CONTROL_PORT |= SED1520_CS1 | SED1520_CS2;
return tmp;
} 

Vorab, so funktioniert es auch nicht. Aber passt zumindest die Logik 
dahinter? Habe ich die Time Charakteristika richtig gelesen?

Wünsche noch eine gute Nacht und danke für die Geduld
Christian

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Vorab: Ich bin notorischer Assemblerprogrammierer und kann mit deinem 
Code nur bedingt etwas anfangen.

>SED1520_CONTROL_PORT |= SED1520_CS1| SED1520_CS2| SED1520_E; 
//Vor->Initialisierung
>asm("nop");asm("nop");

Du solltest deine Routinen etwas hierarchischer aufbauen. Um ein Byte zu 
lesen (oder zu schreiben) ist es egal, welcher SED1520 ausgewählt ist. 
D.h. in der untersten Ebene hat die CS1/2-Ansteuerung nichts zu suchen.
CS1 oder CS2 werden anhand der Spaltenadresse (Column) gesetzt und 
danach die Read/Write-Routine aufgerufen.
Die 'nop's' kannst du dir auch sparen.

Falls es dir hilft, meine 'Read'-Routine für den SD1520 (Stand 
25.3.1999)
;                  Daten lesen
;                  out      : r17 byte
;                  changed : -
;
rd_dat:            push r16
                   rcall rwst_check             ;lcd bereit?
                   ldi r16,$00
                   out dat_dir,r16              ;porta Input
                   cbi ctl_out,enab             ;disab.Anz.
                   sbi ctl_out,rw               ;lesen
                   sbi ctl_out,cd               ;Daten
                   sbi ctl_out,enab             ;Daten gültig
                   nop
                   nop
                   nop
                   in r17,dat_in
                   cbi ctl_out,enab             ;disp.disab.
                   pop r16
                   ret

MfG Spess

Autor: Christian L. (logos23)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hey Spess,

danke für den Code-Schnipsel. Ich kann ihn nachvollziehen, und habe ihn 
in C mitbenutzt, leider auch wieder ohne Erfolg.
unsigned char GLCD_ReadData(void)
{
unsigned char tmp;
GLCD_WriteCommand(0xE0, 0);          //Modify on
GLCD_WaitForStatus(0x80, 0); 
GLCD_WaitForStatus(0x80, 1);        //Busy-Flag abfragen
SED1520_DATA_DDR = 0x00;           //Input

SED1520_CONTROL_PORT &= ~SED1520_E;  
SED1520_CONTROL_PORT |= SED1520_RW;     //von Display lesen
SED1520_CONTROL_PORT |= SED1520_A0;     //Daten  (nicht Befehl)
 
if(lcd_x < 61) SED1520_CONTROL_PORT &= ~SED1520_CS1; 
 else SED1520_CONTROL_PORT &= ~SED1520_CS2; 
asm("nop");asm("nop");asm("nop");

SED1520_CONTROL_PORT |= SED1520_E;      //Positive Flanke für Befehlsübernahme
tmp = SED1520_DATA_PIN;  
SED1520_CONTROL_PORT &= ~SED1520_E; 
SED1520_CONTROL_PORT |= SED1520_E;
SED1520_DATA_DDR = 0xFF;           //Datenregister wieder auf Ausgang
GLCD_WriteCommand(0xEE, 0);          //Modify out 
return tmp;
} 

Ich verstehe, das nach dem Datenblatt zum Schluss Enable wieder auf Low 
gesetzt werden sollte, allerdings führt dass bei mir zu einem nicht 
weiter beschreibbaren Display ab dem Zeitpunkt, wo Enable nicht wieder 
auf High gesetzt wird.
Ich habe jetzt über eine Woche versucht den Code anzupassen und bin 
dementsprechend ziemlich angepisst.
Wäre es möglich, dass du mir deine asm-lib schicken könntest und ich die 
einmal testen könnte?

Anm: Das mit der Hierarchie und so weiter leuchtet mir ein, ich wollte 
aber erst mal auf Funktionalität testen.

Mfg
Logos

Autor: spess53 (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi

>allerdings führt dass bei mir zu einem nicht
>weiter beschreibbaren Display ab dem Zeitpunkt, wo Enable nicht wieder
>auf High gesetzt wird.

Das kann möglicherweise auch an dem fehlenden Schreibzyklus liegen. Lass
doch einfach mal alles Unwichtige, wie CS-Umschaltung und 
Read-Modify-Write,
weg. Also einfach Adresse auf Null setzen. Byte schreiben. Adresse 
wieder
auf Null. Dummybyte lesen. Byte lesen. Wenn das klappt kannst du dich um
den Rest kümmern.

>Wäre es möglich, dass du mir deine asm-lib schicken könntest und ich die
>einmal testen könnte?

Wie gesagt. Ich habe die Datei vor fast 11 Jahren das letzte mal 
angefasst.
 Und ich kann beim besten Willen, jetzt auch nicht genau sagen, ob alles
bis zum Letzten getestet ist. Ansonsten kein Problem.

MfG Spess

Autor: Christian L. (logos23)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Abend Spess,

ich versuche jetzt von Null anzufangen, was bedeutet für dieses "banale" 
Problem noch mehr Zeit zu investieren. Ich hasse es, das ich das 
unbedingt verstehen will, aber es ist nun mal so.
Wenn es für dich keine Umstände macht, wäre ich dankbar für die Dateien. 
Wenn dies dann wirklich funktioniert, ist die Fehlersuche einfacher bzw. 
schneller und ich kann mit den. eig. Dingen anfangen.

Als dann nur noch mal Danke zu sagen bleibt.
Schöne Grüße
Logos

Autor: spess53 (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hi

Anbei alles was ich zu dem Thema habe. Wie gesagt, ohne Gewähr.

MfG Spess

Autor: Matthias K. (matthiask)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Christian L. schrieb:
> ich versuche jetzt von Null anzufangen

Ich hänge mal meinen SED1520-Code an. Ist für DIP122 von EA. Hat aber 
einen PIN weniger rausgeführt. Gerade nochmal ausprobiert. Läuft hier 
selbst mit 18MHz Quarz ohne weitere Delays auf Atmega644. Auch 
read-Funktion ist ok.

Autor: Matthias K. (matthiask)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Das Bild sollte Klärung bringen für den 68 Mode bei Deinem Display. Du 
muss die CS-Signale noch jeweils in die write und read-Funktionen 
einbinden, je nachdem welche Hälfte aktiviert wird. Alles andere kann 
bleiben A0 R/W und E ist wohl intern parallel geschaltet.

Und nicht vergessen, RES auf H zu setzen, oder besser eine L/H Flanke 
erzeugen und den RES-Pin dann dauerhaft auf H lassen (aktiviert den 68er 
Mode).

Autor: Christian L. (logos23)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Tag,

also das letzte Aufgebot. Danke für eure Quellcodes, leider haben, die 
mich auch nicht weiter gebracht. Heute ist der letzte Tag, den ich an 
das Display verschwenden werde.
Eine Verständnisfrage hätte ich noch. Wenn man sich das Datenblatt 
anschaut und das Timing Diagramm für den "68" Modus, würde ich mein 
Read() verbal so ablaufen lassen:

- DDR_Daten auf Eingang schalten
- E_low setzen
- RW_high setzen
- CS1 oder CS2_low setzen
- evtl. hier einen nop einfügen
- E_high setzen
- evtl. hier einen nop einfügen
- daten = Daten_PIN
- evtl. hier einen nop einfügen

- Alle vorherigen Einstellungen rücksetzen (RW_low, CS1/2 _high, E_high)
- DDR Daten auf Ausgang rückstellen

Wenn mir nur jemand noch sagen könnte, ob das wenigstens so passt, wäre 
ich schon froh.

Schöne Grüße
Logos

Autor: Matthias K. (matthiask)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Christian L. schrieb:
> - DDR_Daten auf Eingang schalten
> - E_low setzen
> - RW_high setzen
> - CS1 oder CS2_low setzen
> - evtl. hier einen nop einfügen
> - E_high setzen
> - evtl. hier einen nop einfügen
> - daten = Daten_PIN
> - evtl. hier einen nop einfügen
> - Alle vorherigen Einstellungen rücksetzen (RW_low, CS1/2 _high, E_high)
> - DDR Daten auf Ausgang rückstellen

Du hast einiges der Signalreihenfolge und der Aktivitätspolaritäten 
durcheinander gebracht, versuchs mal so:

Ausgangszustand:
- RES ganz am Anfang auf High und immer so lassen (68er Mode)
- RW beliebig
- A0 beliebig
- CS1 high
- CS2 high
- E low

READ:
Zum testen gar nicht warten auf Busy, sondern erstmal ein
_delay_ms(10); verwenden, dann:

- DDR_Daten auf Eingang schalten
- Pullups zuschalten
- RW_high setzen
- A0_high setzen
- CS1 oder CS2_low setzen
- _delay_us(1);
- E_high setzen
- _delay_us(1);
- daten = Daten_PIN
- _delay_us(1);
- E_low setzen
- CS1/2_high setzen
- Pullups abschalten
- DDR Daten auf Ausgang rückstellen

Autor: Christian L. (logos23)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...und ich wollte wirklich aufgeben.

Matthias K. schrieb:
> Ausgangszustand:
> - RES ganz am Anfang auf High und immer so lassen (68er Mode)
> - RW beliebig
> - A0 beliebig
> - CS1 high
> - CS2 high
> - E low

Wenn es nicht so ewig lang gedauert hätte, würde ich lachen. So bin ich 
einfach nur dankbar, dass ich endlich aufhören kann, darüber 
nachzudenken.

Mein Fehler war, dass ich den Rest der Funktionen, die vermeintlich 
funktionierenden Methoden so belassen habe, wie sie in der von mir 
übernommenen Bibliothek vorhanden waren.
Ich habe deine Reihenfolge mit dem Zeitdiagramm peinlich befolgt und 
zwar jetzt bei allen !!!
Ergebnis ist jetzt, das alles funktioniert.
Jetzt gehts an die Optik und die Zeitoptimierung.

Ich danke euch beiden vielmals für die Geduld und die Hilfe.
Ich hoffe jetzt habe ich das geschnallt.

Ich wünsche noch einen schönen Sonntag
Christian

Autor: Matthias K. (matthiask)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
freut uns...

Hoffentlich setzt Du das Programm dann in die Codesammlung, zu der 
SED1520 Display-Variante mit den 2 rausgeführetn CS-Anschlüssen gibt 
hier gelegentlich Unklarheiten.

Autor: Christian L. (logos23)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Natürlich,

Die Bibliothek, die ich hier aus dem Forum habe, ist dementsprechen 
inkorrekt:
Beitrag "SED1520 Lib von avr-lcd.de?"
Solange man nicht vom Display Daten lesen möchte funktioniert sie, 
solange man den beim Code nicht berücksichtigten E(/RD)-Pin auf High 
Pegel zieht.

Ich kenne nicht wirklich die Regeln und Normen von solchen Programmen.
Von daher sei dann eher auf Inhalt Wert gelegt als auf das Äußere ^^.

Autor: Matthias K. (matthiask)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Man kann auch ganz ohne READ klarkommen, wenn zB. im RAM eine Art 
Bildspeicher vorhält und alle Änderungen erstmal dort macht und dann zum 
Display überträgt, wie beim PC praktisch. Belegt natürlich 122x4 Byte 
SRAM. Busy-Zustand müsste man dann über großzügige Delays regeln. Die 
READ-Variante ziehe ich aber auch vor.

Autor: Christian L. (logos23)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Naja der ATmega8 ist ja nicht unbedingt ein Speicherwunder. Mir ging es 
aber auch eher ums Prinzip und Verständnis.
Habe das Ganze jetzt in die Codesammlung gestellt
Beitrag "DG-12232 Ansteuerung von 2xSED1520 Controller"

Ich habe auch für mich eine Zusammenfassung geschrieben, die ich dann 
doch online stellen wollte. Für diejenigen, die auch länger für sowas 
brauchen. Dabei habe ich deine Anmerkung

Matthias K. schrieb:
> READ:
> Zum testen gar nicht warten auf Busy, sondern erstmal ein
> _delay_ms(10); verwenden, dann:
>
> - DDR_Daten auf Eingang schalten
> - Pullups zuschalten
> - RW_high setzen
> - A0_high setzen
> - CS1 oder CS2_low setzen
> - _delay_us(1);
> - E_high setzen
> - _delay_us(1);
> - daten = Daten_PIN
> - _delay_us(1);
> - E_low setzen
> - CS1/2_high setzen
> - Pullups abschalten
> - DDR Daten auf Ausgang rückstellen

mit reingenommen. Wenn du das als störend oder unpassend empfindest, 
sage mir bitte Bescheid.

Schönen Abend noch

Autor: Matthias K. (matthiask)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gut gemacht, die .doc ist sicher auch hilfreich. Der Code sieht ganicht 
so schlecht aus, von der Form her. Da wurden hier schon deutlich 
schlechtere Dinge abgeliefert.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.