HD44780+PIC18F25k22 Rise Time Probleme?

OP #5306969
Lesenswert?

Hi,

ja wieder Einer der..... ;P
Pople nun schon seit >10h an meiner LCD_Lib rum, ich will nich 
mehr....
100x überprüft, gesucht, geändert, kein(en wirklichen) Fehler gefunden 
o. ich bin Betriebsblind.
Der Pic18F25k22 ist auf ein BrakeoutBoart (ink. 1x100nF) gelötet, 
Steckbrett.

Stromversorgung OK, Protokoll OK(?), alle Timings ausgemessen OK, 
Letzer Prüfung  RiseTime FALED!
Ja kruzefix, kann ja wohl nich sein. Hat ja im Normalfall auch 
(scheinbar) keiner.

Obiges OsziBild zeigt einen belasteten Port, ~25ns. Ohne geht die 
RiseTime auf ~20ns runter.
Pic Dabla sagt bei 5V Typ., 15ns Max. 32ns. Was ja dann eigentlich des 
öfteren Probleme geben sollte, is ja nu nich außergewöhnlich langsam???
A-Karte gezogen?

Das Display zeigt auch unterschiedliches Verhalten, Balken weg, Cursor 
ja/nein, irgendwo einzelne Zeichen,... Zeigt aber nie das an was es 
soll.

Wie was nu! Kann es wirklich daran liegen?
Oder doch "Betriebsblind" und wenn nich, auf gut Glück nen neuen 
auflöten?
(Der Trigger sitzt vor Enable o. vor der Bussy-Prüfung.)
Angehängte Dateien:
#5307300
Lesenswert?

Hi,
kenne das Problem zur Genüge. Bin schon seit 2008 mit dem Thema 
LCD-Initialisierung befasst.
Was @Peda sagt, ist absolut essenziell.
Das eine Missverständnis bei der Doku ist:
Die Befehlsliste ist nicht die Reihenfolge, mit der das LCD 
initialisiert werden muss. (Die Befehlsliste listet nach aufsteigendem 
Bit-Wert.)
Und:  Busy-Flag-Abfrage kann in der ersten Phase des Init nicht laufen.
Dann:
Der Power on self reset initialisiert das LCD von alleine, schaltet aber 
die Anzeige ab. Dann muss "softwaremäßig" noch einmal initialisiert 
werden.
Der POSR braucht eine innerhalb eines definierten Zeitintervalls 
ansteigende Versorgungsspannung. Ist ein "dicker" Elko direkt an den 
Versorgungsspannungsanschlüssen des LCD, kann es in bestimmten Fällen 
vorkommen, dass der POSR nicht oder nicht richtig ausgeführt wird.
Dann gibt es im Vierbitmodus schon kleine Missverständnisse.
Der Befehlssatz am Anfang 3 mal hex 30 (oder je nach Lib
hex 03) impliziert, dass die untersten vier Ports auf GND und somit 
logisch "Null" stehen. So ist das sowohl beim Achtbitmodus wie 
Vierbitmodus am Anfang egal, ob nun die unteren vier Ports schon fest 
auf GND verdrahtet sind oder nicht. Aber das LCD kann im Vierbit-Modus 
nur D4 bis D7 lesen. Wurde oben schon gesagt.
Dann ist der HD44780-Controller so konfiguriert, dass er zuerst das 
obere Nibble des 8-Bit Datenbytes verlangt. Das wird beim "Swappen" oft 
missverstanden.  Dann kommen aber auf jeden Fall irgendwelche Characters 
z.b. ein Sigma.

Und noch etwas Prosa dazu:
Beitrag "Re: Atiny2313  4313  LCD Displaytech 204B/ DCF77"

sorry für ATMEL AVRs, PICS sind für mich "böhmische Dörfer".
Die Initialisierungssequenzen sind aber sicher leicht portierbar.

ciao
gustav
OP #5307356
Lesenswert?

Bernd S. schrieb:
> Wo ich gerade D0,D1,D2,D3 in deinem LA-Plot sehe. Nutzt der 4-bit Mode
> vom HD44780 nicht D4 bis D7?

Das passt schon, ist nur mit D0-D3 gedankenlos benannt worden,

Karl B. schrieb:
> Das eine Missverständnis bei der Doku ist:
> ...

Nö, kein Missverständnis. Is ja auch nich mein erstes, wenn auch in C.

Peter D. schrieb:
> Kein
> Zugriff darf ohne Wartezeit direkt auf den vorherigen folgen.
> Insbesondere im 4Bit-Mode ist ein sauberes Init essentiell.

Wie geschrieben, alle geprüft und iO.
Nur die Übertragung des zweiten (unteren) Nibble ist unklar im Dabla.
Hatte da aber auch schon erfolglos die Wartezeit variiert.

Volker S. schrieb:
> Da schließe ich mal den anderen an und sage nein.

Hab ich befürchtet, nur warum seh ich den Fehler nich.

Volker S. schrieb:
> Ein LCD-Testprojekt für den 25K22 kannst du hier finden:
> http://picforum.ric323.com/viewtopic.php?f=40&t=210
>
> (Zum Testen des Displays, Vergleichen der Initialisierung...)
> ((ist ein bisschen speziell, weil die Pins für die Daten frei wählbar
> sein sollten))

THY
OP #5307378
Lesenswert?

Ich dachte zwar das der LA-Plot besser zu lesen ist, als sich durch mein 
C zu wühlen. Aber hier mal den relevanten Code.
1
#include "mcc_generated_files/mcc.h"
2
#include "HD44780.h"
3

4
void LCD_Init(void) {
5
        TRIGGER // <----------  T R I G G E R 
6
    LCD_PORT_LAT = 0x03;
7
    __delay_ms(17);
8
    TRIGGER // <----------  T R I G G E R         
9
    LCD_ENABLE;
10
    __delay_us(4500);
11
    TRIGGER // <----------  T R I G G E R 
12
    LCD_ENABLE; //   LCD_PORT_LAT = 0x03;
13
    __delay_us(110);
14
    TRIGGER // <----------  T R I G G E R 
15
    LCD_ENABLE; //   LCD_PORT_LAT = 0x03;
16
    // Bussy Flag is avidable
17
    LCD_PORT_LAT = 0x02;
18
    TRIGGER // <----------  T R I G G E R 
19
    TRIGGER // <----------  T R I G G E R 
20
    LCD_Bussy();
21
    LCD_ENABLE;
22
    LCD_Write(LCD_FUNKTION_SET, INSTRUCTION);
23
    LCD_Write(LCD_DISPLAY_OFF, INSTRUCTION);
24
    LCD_Write(LCD_DISPLAY_CLEAR, INSTRUCTION);
25
    LCD_Write(LCD_ENTRY_MODE_SET, INSTRUCTION);
26
    LCD_Write(LCD_FUNKTION_SET, INSTRUCTION);
27
}
28

29
void LCD_Write(unsigned char data, unsigned char RS) {
30
    LCD_RS_LAT = RS;
31
    LCD_PORT_LAT = (LCD_PORT_LAT & 0xf0) | (data >> 4);
32
        TRIGGER // <----------  T R I G G E R 
33
    LCD_Bussy();
34
    LCD_ENABLE;
35
    LCD_PORT_LAT = (LCD_PORT_LAT & 0xf0) | (data & 0x0f);
36
     __delay_us(1);
37
    LCD_ENABLE;
38
}
39

40
void LCD_Bussy(void) {
41
    unsigned char dummy;
42
    dummy = LCD_RS_LAT;
43
    LCD_RS_SetLow();
44
    //    __delay_us(1); // tAS
45
    LCD_READ_MODE; // ersetzt Delay tAS
46
    LCD_ENABLE;
47
    while (LCD_BUSSY_PORT) {
48
        __delay_us(1);
49
        LCD_ENABLE;
50
    }
51
    LCD_RS_LAT = dummy;
52
    LCD_WRITE_MODE;
53
}
54
//------------------------------------------------
55
#include "mcc_generated_files/mcc.h"
56
#include "HD44780.h"
57

58
void main(void) {
59
    // Initialize the device
60

61
    SYSTEM_Initialize();
62
    LCD_Init();
63
    LCD_Write(LCD_DISPLAY_ON, INSTRUCTION);
64
    LCD_Write('A', DATA_MODE);
65
    LCD_Write('H', DATA_MODE);
66
    LCD_Write( 0x38, DATA_MODE);
67

68
    while (1) {
69

70
        LED_TEST_LAT = ~LED_TEST_LAT;
71
        __delay_ms(500);
72

73
    }
74
}
Hier noch die Macros.
Rest egal, es werden definitiv keine falschen Pins angesteuert.
1
#define LCD_ENABLE {LCD_Enable_SetHigh(); __delay_us(1);LCD_Enable_SetLow();}// delay=tDDR
2
//#define LCD_READ_MODE {LCD_PORT_TRIS |= 0x0f; LCD_RW_SetHigh();}
3
#define LCD_READ_MODE {LCD_D0_SetDigitalInput();LCD_D1_SetDigitalInput(); \
4
        LCD_D2_SetDigitalInput();LCD_D3_SetDigitalInput(); LCD_RW_SetHigh();}
5
//#define LCD_WRITE_MODE {LCD_PORT_TRIS &= 0xf0; LCD_RW_SetLow();}
6
#define LCD_WRITE_MODE {LCD_D0_SetDigitalOutput();LCD_D1_SetDigitalOutput(); \
7
        LCD_D2_SetDigitalOutput();LCD_D3_SetDigitalOutput(); LCD_RW_SetLow();}
8

9
#define TRIGGER {TEST_Trigger_SetHigh(); TEST_Trigger_SetLow();}
#5307403
Lesenswert?

Eine kleine Erfahrung meinerseits, ohne das Datenblatt des LCD genauer 
betrachtet zu haben.
-Nach dem Reset/powerup dauert es ueblicherweise
 sehr lange bevor man ueberhaupt zugreifen darf.
 Das kann in die Hunderten von ms gehen.
-dann kommt das Reset Command, und wieder dauert
 es sehr lange bis man weitermachen darf.

-die Adresse der zweiten Zeile beginnt bei 0x40

-Ready ist nicht noetig, ich verwende einen festen
 timerinterrupt und schreibe meinen Buffer periodisch
 in den Display.

-Dann muss die Kontrastspannung im richtigen Bereich
 liegen.
#5307443
Lesenswert?

Zwölf M. schrieb:
> -Nach dem Reset/powerup dauert es ueblicherweise
>  sehr lange bevor man ueberhaupt zugreifen darf.
>  Das kann in die Hunderten von ms gehen.

Da werden wohl die 17ms dafür da sein.
Ich benutze 15ms und das funktioniert "bisher" mit allen Displays.

Zwölf M. schrieb:
> -dann kommt das Reset Command, und wieder dauert
>  es sehr lange bis man weitermachen darf.

4500us bei Teo, 5ms bei mir. Bin mir aber wegen den TRIGGER und 
LCD_ENABLE nicht 100% sicher, wie oft das RESET bei Teo dann geschrieben 
wird.

Bei mir sieht das so aus:
1
void LCD_Init(void)
2
{
3
    LCD_RW = 0; LCD_RW_DIR = 0;
4
    LCD_RS = 0; LCD_RS_DIR = 0;
5
    LCD_E  = 0; LCD_E_DIR  = 0;
6

7
    LCD_PINS_DIGITAL();
8
    LCD_DIR_OUT();
9

10
    LCD_busy_cnt = 1;    // busy_flag time out counter
11

12
    LCD_DELAY_5MS();LCD_DELAY_5MS();LCD_DELAY_5MS();    // wait for 15ms
13
// display reset procedure
14
    LCD_Write_Nibble(LCD_RESET);    LCD_DELAY_5MS();
15
    LCD_Write_Nibble(LCD_RESET);    LCD_DELAY_5MS();
16
    LCD_Write_Nibble(LCD_RESET);    LCD_DELAY_5MS();
17

18
    LCD_Write_Nibble(FOUR_BIT); while(LCD_Busy()){;} // wait
19

20
    LCD_Command(FOUR_BIT_TWO_LINE);
21

22
    LCD_Command(DISPLAY_CTRL + DISPLAY_ON);// + BLINK_ON);
23
    LCD_Command(ENTRY_MODE + CURSOR_INC + DSHIFT_OFF);
24
    LCD_Clear();
25
    LCD_Home();
26
}
OP #5307444
Lesenswert?

Zwölf M. schrieb:
> Eine kleine Erfahrung meinerseits, ohne das Datenblatt des LCD genauer
> betrachtet zu haben.

Na dann danke für die guten Tips. ;)
Ja alles schon mal gemacht und funst. Gefällt mir aber nicht!

Zwölf M. schrieb:
> -die Adresse der zweiten Zeile beginnt bei 0x40
???

Vielen Dank für die Anfänger-Tips.
ABER eigentlich hoffe ich das sich das mal einer ernsthaft ansieht.
Sicher irgend ein DUMMER Fehler wirds schon sein, nur ICH erkenne ihn 
nicht.

Teo D. schrieb:
> Karl B. schrieb:
>> Das eine Missverständnis bei der Doku ist:
>> ...
>
> Nö, kein Missverständnis.

Das ist leider nur die Hoffnung eines Unwissenden Selbstzweiflers....
OP #5307474
Lesenswert?

Volker S. schrieb:
> Da werden wohl die 17ms dafür da sein.
> Ich benutze 15ms und das funktioniert "bisher" mit allen Displays.

Ob 15ms oder 1h sollte egal sein. Hatte da auch erst 15ms, dann aber zur 
Sicherheit verlängert.

Volker S. schrieb:
> 4500us bei Teo, 5ms bei mir. Bin mir aber wegen den TRIGGER und
> LCD_ENABLE nicht 100% sicher, wie oft das RESET bei Teo dann geschrieben
> wird.

Dito.
Enable rüttelt nur am Enable-Pin, mit 1µs Pause.
#define LCD_ENABLE 
{LCD_Enable_SetHigh();__delay_us(1);LCD_Enable_SetLow();}// delay=tDDR

Der TRIGGER ist nur zur besseren Orientierung im LA-Plot eingefügt.
Rüttelt auch nur an einem Pin. Tut nichts am LCD, verlängert nur etwas 
das Timing.
#define TRIGGER {TEST_Trigger_SetHigh(); TEST_Trigger_SetLow();}
#5307512
Lesenswert?

Dein LCD_Küsschen ist falsch. Es müssen beim Busy-Test immer 2 Nibble 
gelesen werden, sonst bist Du aus dem Takt.  Das BF ist im ersten Nibble 
(Seite 22, Figure 9 4-Bit Transfer Example).
Und mitten drin im LCD_WRITE geht schonmal gar nicht, sondern nur 
danach.
Der Busy-Test geht frühestens auf den ersten Befehl nach dem Setzen des 
4Bit-Mode. D.h. bis einschließlich des 4Bit-Kommandos darf nur mit Delay 
gearbeitet werden.
Gast #5307553
Lesenswert?

Peter D. schrieb:
> Nö.
> Die Hauptfehlerursache (zu 99,99%) ist eine fehlerhafte Initsequenz.
> Das original HD44780 Datenblatt ist da leider etwas unpräzise. Kein
> Zugriff darf ohne Wartezeit direkt auf den vorherigen folgen.
> Insbesondere im 4Bit-Mode ist ein sauberes Init essentiell.

nö, auf Seite 45 ist es eindeutig beschrieben !!
Angehängte Dateien:
OP #5307574
Lesenswert?

Peter D. schrieb:
> Dein LCD_Küsschen ist falsch. Es müssen beim Busy-Test immer 2 Nibble
> gelesen werden, sonst bist Du aus dem Takt.

Ich denk auch das war der Fehler.

Völlig aus den Augen verloren, das mit dem Synchron bzw. immer 
Paarweise auslesen/schreiben der Nibble. Erklärt auch das 
unterschiedliche verhalten, je nach dem wann er dann halt aus dem Tritt 
kommt.
War mir da nie sicher (hab das anfänglich so gemacht, im laufe der 
Fehlersuche/Tests...) und sah ES Antwortet ja. Das dies eventuell 
nur die halbe Wahrheit ist.... Ojeh, was für ne Dummheit.
(Wenns das aber doch nich bringt, geht was kaputt!)

DANKE!


PS: Kann erst Heut Abend weiter testen...
PPS:
Stephan schrieb:
> die anderen Wartezeiten stehen bei der "Befehlsübersicht".
> Damit ist ein exaktes Timing kein Problem.
> Bleibt nur die Frage ob der Controller auf dem Display auch original
> ist...

Hab das Original Dabla vom Modul. War einer der ersten Prüfungen.
#5307578
Lesenswert?

Stephan schrieb:
> nö, auf Seite 45 ist es eindeutig beschrieben !!

Falsches Bild, da: "Figure 23 8-Bit Interface"

Und genau das ist die Stelle, die viele falsch verstehen:
"BF can be checked after the following instructions."
Soll heißen, erst nach den nächsten!
In dem Bild fehlt also ein weiteres "Wait for more than 100 μs" vor dem 
letzten Block.
OP #5307593
Lesenswert?

Peter D. schrieb:
> Soll heißen, erst nach den nächsten!
> In dem Bild fehlt also ein weiteres "Wait for more than 100 μs" vor dem
> letzten Block.

Ty.
Sieht im Dabla schon merkwürdig aus, nach dem ersten Bussy-Test nur 
ein Nibble zu übertragen. Hielt aber die Lücke für eindeutig. :(

Dann werd ich mal IMMER paarweise rütteln und den ersten Bussy-Test 
durch ein Delay >100µs ersetzen.
OP #5307617
Lesenswert?

Ich habs doch gewusst.
Das kann ja wohl nich angehen!
Wie DÄMLICH muss man eigentlich sein, um zu glauben das nach dem ersten 
auslesen des Bussy, durch auslesen des OBERN Nibble, der nächste 
Lesebefehl WIDER das OBERE Nibble liefert?

Ich mach den Scheiß einfach viel zu selten, völlig eingerostet der 
Denkapparat.

Nochmals VIELEN DANK, für den Tritt in den Ars..! :D
#5307630
Lesenswert?

Peter D. schrieb:
> Und genau das ist die Stelle, die viele falsch verstehen:
> "BF can be checked after the following instructions."
> Soll heißen, erst nach den nächsten!
> In dem Bild fehlt also ein weiteres "Wait for more than 100 μs" vor dem
> letzten Block.

Uuups, hab ich so auch noch nicht gelesen.
Also es funktioniert zwar seit 20 Jahren ohne, aber vielleicht nur 
Glück?

Scheint auch nicht bei allen "kompatiblen" so zu sein.
Im Datenblatt von einem ST7036 gibt es keinen solchen Hinweis.
#5307635
Lesenswert?

Teo D. schrieb:
> Wie DÄMLICH muss man eigentlich sein, um zu glauben das nach dem ersten
> auslesen des Bussy,

Wenn ich mich richtig erinnere, bin ich darauf vor vielen Jahren auch 
mal reingefallen, als ich meine Bibliothek von Assembler auf C 
umgestellt habe und dachte:
"Wozu lese ich das eigentlich noch mal, das brauch ich ja gar nicht"
Hat natürlich gleich aufgehört zu funktionieren ;-)
OP #5307641
Lesenswert?

Volker S. schrieb:
> Uuups, hab ich so auch noch nicht gelesen.
> Also es funktioniert zwar seit 20 Jahren ohne, aber vielleicht nur
> Glück?

Das Bussy auszulesen ist ja auch nich wirklich der Bringer.
Nur mit Delays hat man das Problem ja nicht und auch nur in der Init und 
da werden die meisten erstmal durchwegs Delays nutzen!?

Deswegen hat ja bei mir mit Assembler ja immer funktioniert.
OP #5307656
Lesenswert?

Volker S. schrieb:
> "Wozu lese ich das eigentlich noch mal, das brauch ich ja gar nicht"
> Hat natürlich gleich aufgehört zu funktionieren ;-)

Ich denke wenn der erste Enable ein Ready liefert, kann darauf ein 
Schreibbefehl folgen.
Nur wenn der Bussy gesetzt ist, MUSS natürlich erstmal noch das untere 
Nibble ausgelesen werden, bevor man wieder das obere inkl. Bussy erhält.
#5307663
Lesenswert?

Hi,
Bildchen dazu.
Die Kanallegende zeigt RS, wo ich R/WQuer vermute.
R/WQuer für die Busyflag-Abfrage.
(Die kommt zu früh.)
Nach jedem Befehl einen Enable Impuls.
Beim Vierbit-Modus dann pro Byte  zweimal.
Oder besser, pro Nibble jedesmal einen.

(Das ist in der Doku im Timingdiagramm auch ein wenig missverständlich 
formuliert. SEite 22, Figure 9)
"...The busy flag must be checked (one instruction) after the 4-bit data 
has been transferred twice. Two more 4-bit operations then transfer the 
busy flag and address counter data..."

(Muss noch ein anderes Datenblatt heraussuchen, da ist es etwas 
deutlicher beschrieben, was damit gemeint ist.)

ciao
gustav
Angehängte Dateien:
OP #5308267
Lesenswert?

Funst! :D

So das war ja wieder mal wat.
(Hab natürlich erst mal nach links geshiftet, natürlich erstmal 
aufgeregt...:)

Peter D. schrieb:
> Und genau das ist die Stelle, die viele falsch verstehen:
> "BF can be checked after the following instructions."
> Soll heißen, erst nach den nächsten!
> In dem Bild fehlt also ein weiteres "Wait for more than 100 μs" vor dem
> letzten Block.

Hab das nu MIT Bussy-Prüfung an dieser Stelle am laufen.
Das Dabla scheint da keines Wegs missverständlich zu sein. Antwortzeit 
~32ms.

Das mit dem IMMER paarigen auslesen des Bussy-Flags ist auch nicht 
nötig.
Das umschalten der Register, resetet das wie erwartet.


Vielen Dank nochmals an ALLE!
Habt mich da wirklich aus ner Endlosschleife gerettet, das hätte noch 
Tage dauern können.


PS: Wenn's nich so umständlich und unelegant geschrieben wäre, würde ich 
die Init ja mal posten. So aber nur unter Waffenandrohung. :)
#5308503
Lesenswert?

Teo D. schrieb:
> Das mit dem IMMER paarigen auslesen des Bussy-Flags ist auch nicht
> nötig.
> Das umschalten der Register, resetet das wie erwartet.

Bei manchem Clone mag das gehen, bei einem original HD44780 aber nicht.
Setzt man immer nur den gleichen LCD-Typ ein, ist das kein Problem. Will 
man aber universell bleiben, sollte man auf diese minimale 
Codeeinsparung besser verzichten.
Man liest hier oft Fragen, warum eine LCD-Lib bei anderen LCDs plötzlich 
nicht mehr funktioniert. Es wird dann gerne mal auf den Händler 
geschimpft, warum der defekte LCDs liefert. Dabei sitzt das Problem vor 
dem PC.

Ich benutze allerdings immer nur 6 IO-Pins zum LCD, d.h. RW liegt fest 
auf GND. Oder 3 IO-Pins und einen 74HC164.
#5308538
Lesenswert?

Stephan schrieb:
> wie ich auch. Ich schreibe immer nur. In einer Schleife im Int.das
> Display liegt 1:1 im RAM und ich muss mich nur um den RAM kümmern. der
> Rest läuft allein.

Das ist schon gut, aber in der Lehre ein wenig zu viel des Guten ;-)
Wenn jemand der mit Mikrocontrollern gerade angefangen hat zu arbeiten 
und das erste mal ein LCD benutzen soll, dazu vorher erst mal das Abbild 
im RAM anlegen soll und den Timer, der dann immer zeichenweise für die 
Auffrischung sorgt...
#5308561
Lesenswert?

Teo D. schrieb:
> Das mit dem IMMER paarigen auslesen des Bussy-Flags ist auch nicht
> nötig.

Ok,
wenn es bei Dir klappt. Gratulation.
OT/(Google Übersetzer liefert mir bei "bussy" nichts nur bei 
"busy"=beschäftigt. Das nur ganz nebenbei. Hätte ja auch etwas sein 
können, was ich noch nicht kenne. Bei den "neudeutschen" Begriffen muss 
man höllisch aufpassen.)/OT
Das "Ich-bin-noch-beschäftigt-Signal" macht, wenn man die Forenbeiträge 
durchliest, garnicht so selten Probleme.
Dazu möchte ich etwas weiter ausholen:
Die HD44780-Schnittstelle lehnte sich zu Entwicklerzeiten an die damals 
üblichen Centronics-Drucker-Parallelschnittstellen an. Dazu unterschied 
man zwei Gruppen von Signalen: "Reine" Daten- und die 
Datenfluss-Kontroll-Bits.
Für letztere benutzt ein Drucker "Acknowledge" (Input) und 
"Busy"(Output).
Also beim HD44780-Standard "Enable"(Input) und "Busy"(Output).
Da man aber Portbits einsparen wollte, kam man auf die Idee, durch 
Umkonfigurieren des Ports das Busy-Signal softwaremäßig auszulesen.

Der Vorteil, dass das Display dadurch schneller würde, ist für die 
meisten Anwendungszwecke derart gering, dass er oft gar nicht ausgenutzt 
wird.
(Hätten die HD44780-Standard-Entwickler geahnt, dass das so ist, hätten 
sie doch lieber hardwaremäßig ein Portbit mehr spendiert, könnte ich mir 
gut vorstellen.)
Wieso?
Das ist für mich der größte Knackpunkt, man muss die Ports bidirektional 
ausführen und softwaremäßig im Programm zwischen "Eingang" und "Ausgang" 
umkonfigurieren. Ich brauche dazu das R/WQuer-Portbit zusätzlich, im 
anderen Falle kann ich es einfach auf GND legen, brauche kein 
MCU-Portbit zu opfern. Das Programm wird dadurch auch umfangreicher. Ob 
das den Zeitgewinn rechtfertigt, weiß ich nicht.
Der unbestrittene Vorteil: Der Displaycontroller bestimmt den Datenfluss 
selbst und ist nicht auf externe, ungenauere Zeitschleifen im Programm 
angewiesen. Diese sind aber bei der Initialisierung so oder so 
notwendig.


Meine Standard-Portbelegung ist:
PB7 PB6 PB5 PB4 PB3 PB2 PB1 PB0    R/Wquer=GND
D7  D6  D5  D4  LED n/c ENA RS

(Damit kann ich sogar mit einem Terminalprogrämmchen via PC im 
Vierbit-Modus über den UART mit 9k6-8N1 direkt auf das Display 
schreiben. Ohne dass ich den Eindruck gewinne, dass Zeichen verschluckt 
würden. So schnell ist die Anzeige.)

ciao
gustav
OP #5308815
Lesenswert?

Karl B. schrieb:
> OT/(Google Übersetzer liefert mir bei "bussy" nichts nur bei
> "busy"=beschäftigt. Das nur ganz nebenbei. Hätte ja auch etwas sein
> können, was ich noch nicht kenne. Bei den "neudeutschen" Begriffen muss
> man höllisch aufpassen.)/OT

OT/
Ja ich bin ein Trottel.
Danke für die Belehrungen, ich bin wirklich ein Ahnungsloser, kann ja 
garnicht anders sein, kann ja nich mal richtig schreiben und bilde mir 
ein, ich könne einen µC Programmieren. Ein naiver Trottel halt..
/OT

Karl B. schrieb:
> (Das ist in der Doku im Timingdiagramm auch ein wenig missverständlich
> formuliert. SEite 22, Figure 9)

Dafür hübsch gezeichnet.
Wenn man Enable hoch zieht steht (meist) wenige ns (lieber 500ns 
warten)das BF an.
Lesen muss (sollte) man logischerweise wenn Enable Hi ist. Auch wenn die 
Daten noch nach der fallenden Flanke von Enable noch anstehen, sicher is 
das nich.
Das scheinen viele so zu machen, rütteln->lesen, kann natürlich schnell 
zu Timing Probleme kommen.
Beim Schreiben is es ja egal wenn die Daten schon vorher anliegen und 
gerüttelt wird.

Karl B. schrieb:
> Der Vorteil, dass das Display dadurch schneller würde, ist für die
> meisten Anwendungszwecke derart gering, dass er oft gar nicht ausgenutzt
> wird.

Teo D. schrieb:
> Das Bussy auszulesen ist ja auch nich wirklich der Bringer.

Tja, is halt nur Spielzeug, will ich haben, selber gemacht.
Bei mir kommt außer Pommes auch kein TK Misst auf den Tisch.

Volker S. schrieb:
> Meinst du damit RS umschalten?
> Ist es nicht einfacher nochmal einen Enablepuls drauf zu hauen?

Ja,da sollte RW stehen.
Einfacher, nein. BF lesen -> schreiben. Warum da noch irgend wo 
rumrütteln.
Gast #5308872
Lesenswert?

Teo D. schrieb:
> Teo D. schrieb:
>> Das Bussy auszulesen ist ja auch nich wirklich der Bringer.
>
> Tja, is halt nur Spielzeug, will ich haben, selber gemacht.
> Bei mir kommt außer Pommes auch kein TK Misst auf den Tisch.

Grundsätzlich jeder nach seinem Gusto. Das Busy-Flag ist schon ne nette 
Sache, damit kann man ganz gut die Unterschiede von Display zu Display 
auffangen. Sofern die Möglichkeit besteht (bi-direktionale Anbindung des 
LCD-Datenbus) sollte man es schon nutzen. Wenn nicht muss man halt die 
Timings mächtig aufweiten um allen möglicherweise verwendeten LCDs (bei 
den möglichen Einsatztemperaturen) gerecht zu werden.
(Insbesondere da die Lebensdauer der LCD Hintergrundbeleuchtung bei den 
transmissiven Ausführungen erfahrungsgemäß stark schwankt... und für 
einen Euro wird man wohl eher das Display tauschen anstatt da dran 
rumzumachen)

Gruß Dominik
OP #5308881
Lesenswert?

Peter D. schrieb:
> Ich benutze allerdings immer nur 6 IO-Pins zum LCD, d.h. RW liegt fest
> auf GND. Oder 3 IO-Pins und einen 74HC164.

Dito, wollt das aber halt mal machen.
Dito, so habe ich mein allererstes LCD auf einem 16f84 programmiert.
Schien mir als Übung sonst zu einfach und viel zu viele Pins. :)

Das Busy-Flag lesen heißt ja auch dieses zu beherrschen. Nur fällt mir 
nich wirklich was zu ein. Die Cursor Adresse auslesen, könnte manchen 
Situationen praktisch sein?

Peter D. schrieb:
> Bei manchem Clone mag das gehen, bei einem original HD44780 aber nicht.

Angeblich arbeite ich mit einem Original?
Funst aber auch mit einem L1652.
Das Dabla unterscheidet sich in diesem Punkt auch nicht.
Ich denke bei so vielen Derivaten ist einfach Erfahrung nötig.

Volker S. schrieb:
> Na ja, wenn das Busy-Flag "Busy" zeigt, dann ließt man ja normalerweise
> wieder und wieder, ohne vorher zu schreiben. (Also ich mach das so)
>
> Beim nächsten Lesen, will ich ja wieder das BF (bit7) und nicht bit3.

Ja klar!
Warum meinst du ist dieser verfik.... Thread entstanden? :D
Natürlich muss man vor dem ZWEITEN auslesen des BFs, erstmal das untere 
Nibble beseitigen. Das war echt peinlich Man.
Nur wenn das BF nicht gesetzt ist, muss man auch nicht das untere Nibble 
lesen. Es folgt ja ein Schreibbefehl, der den Nibble-Counter resetten 
(sollte er zumindest).
OP #5308906
Lesenswert?

Volker S. schrieb:
> Ah ok, die Unterscheidung wäre mir dann schon zu viel,
> bzw. habe ich gar nicht darüber nachgedacht...

Ditio :D

Muss ja auch nich sein, einfach den Stiefel durchziehen, vereinfacht 
das auch. :)
Spart bei mir auch nur ~5µs.

War da ja grad am popeln und wollte wissen ob ich das Dabla richtig 
interpretiere.
Man sollte immer etwas mehr wissen als man braucht, um nicht in 
scheinbar unlösbare Situationen zu geraten.
Und hier ist eh nur der Weg das Ziel....
(Firma: matzetronics) #5308914
Lesenswert?

Teo D. schrieb:
> Die Cursor Adresse auslesen, könnte manchen
> Situationen praktisch sein?

Naja, die meisten LCD mit dem Hitachi sind ja so klein, das man da nicht 
gross durcheinander kommt.
Wenn man dann doch mal ein 4*40 hat, dann kann man sich das vermutlich 
leichter mit 2 Variablen im MC merken, als das Zeug zurück aus dem 
langsamen Display zu lesen. Bei den DOGM132 mit SPI mache ich das immer 
so, das sind aber auch reine Grafik LCD.
OP #5308954
Lesenswert?

Matthias S. schrieb:
> Wenn man dann doch mal ein 4*40 hat, dann kann man sich das vermutlich
> leichter mit 2 Variablen im MC merken, als das Zeug zurück aus dem
> langsamen Display zu lesen.

Das teil stammt halt aus Zeiten, in denen Ram noch rar war. :)

Und hör auf mir meine super tolle Erkenntnis, wie ich das Ding auslese, 
madig zu machen!
Das hat viele Stunden und noch mehr Selbstzweifel gekostet. :D
(letzteres scheinbar berechtigt:()
(Firma: matzetronics) #5309011
Lesenswert?

Teo D. schrieb:
> Das teil stammt halt aus Zeiten, in denen Ram noch rar war. :)

Naja, ehrlich gesagt, selbst beim 8048 wäre noch genügend RAM für X und 
Y dagewesen und bei meinem Favoriten 8051 damals wars ein Klacks. Selbst 
das Busy Flag wurde von mir ignoriert, weils einfach schneller ging, 
wenn man einfach die Timings aus dem Datenblatt beachtete und schrieb, 
so schnell es erlaubt war.

Teo D. schrieb:
> Und hör auf mir meine super tolle Erkenntnis, wie ich das Ding auslese,
> madig zu machen!

Mir tut es ja auch leid um die Zeit, die du da reingesteckt hast, aber 
das hier ist nun mal keine Sonntagsschule, sondern die MC.net 
Folterkammer, die immer noch Salz reinstreut, wo es weh tut :-P
OP #5309091
Lesenswert?

Matthias S. schrieb:
> Mir tut es ja auch leid um die Zeit, die du da reingesteckt hast, aber
> das hier ist nun mal keine Sonntagsschule, sondern die MC.net
> Folterkammer, die immer noch Salz reinstreut, wo es weh tut :-P

Warum tut Dir das leid  tuts ja noch nich mal mir. ;)

Ne was nur immer wieder ärgerlich ist, das ich immer an so simplen 
Dingen hänge, wie ein blinder Fleck, den ich einfach nicht sehen will. 
Und das geht garnich, selbst wenn ich mich in aller Öffentlichkeit, 
einer solchen Demütigung aussetzen muss.

> das hier ist nun mal keine Sonntagsschule, sondern die MC.net
> Folterkammer, die immer noch Salz reinstreut, wo es weh tut :-P

Jo, da braucht man nich meckern, wenn man mal selber was abbekommt. ;P

skorpionx schrieb:
> Teo D. schrieb:
>> ?
>
> Das funktioniert...

Meins auch!
Zu spät gepostet!?
#5310873
Lesenswert?

Hi,
wollte es auch einmal probieren:
Also:
Portbit freimachen für R/Wquer
Die Routine Busyflagabfrage direkt hinter die Routine Zeichenausgabe an 
LCD, bzw. Befehl an LCD.

Busyflagabfrage:
Erst Port zum Eingang konfigurieren
Enable high
Daten auslesen (oberes Nibble mit B7)
Enable low
ein paar nops zur Stabilisierung des Ports
Enable high
Enable low
ohne Daten auszulesen (unteres Nibble einfach ignorieren)
Sprung in Schleife, so lange B7 gesetzt ist.
(oder mit "rol" B7 in Carry schieben und Carry abfragen, was im 
Endeffekt auf dasselbe herauskäme)
Und Port wieder zumn Ausgang machen etc.

So sieht der code dann aus:
busyflag:
push temp
ldi temp, 0x0F
out ddrb, temp
out daten, temp
cbi daten, rs
sbi daten, rw
;
busyflag1:
sbi daten, ena
nop
nop
nop
nop
nop
in temp, daten
nop
nop
cbi daten, ena
nop
nop
nop
nop
nop
sbi daten, ena
nop
nop
nop
nop
cbi daten, ena
nop
nop
sbrc temp, 7
rjmp busyflag1
nop
nop
nop
ldi temp, 0xFF
out ddrb, temp
cbi daten, rw
nop
nop
sbi daten, rs
pop temp
ret

Wieso die ganzen nops?
Weil ich meine, dass die Umschalterei von Ausgang zu Eingang etc.
Reflexionen auf dem Draht produziert. Also auch das Übersprechen der 
Steuerbits (ohne Busabschluss). Eben die Verdrahtung! ("Nur" 20 cm)

Also, es wird mir zumindest das erste Zeichen verschluckt. (Siehe 
Bildchen)
Habe jetzt das Label Busyflag wieder durch die passende Warteschleife 
ersetzt, und es läuft wieder so wie ich das gewöhnt bin.

ciao
gustav

P.S.:
Da ich der Meinung bin, dass das Enable-Bit ein Transition state Bit 
ist,
also der Wechsel von High nach Low hier das Entscheidende ist,
habe ich auch die Routine 'mal entsprechend ausprobiert, es geht dann 
noch schlechter.
Es ist dann - zumindest in diesem Zusammenhang - also doch ein "Current 
State" Bit. (Steht aber nirgends in der Doku.)
Angehängte Dateien:
#5311029
Lesenswert?

Edit:
Hi, nur zur Vervollständigung:
es muss so richtig heißen:
wait3:      ;Verzoegerungsschleife 3
push xl
push xh
push temp      ;Register sichern auf Stapel
push temp1      ;Sicherung von Temporaerregistern
in temp1, SREG    ;und Statusregister auf Stapel
push temp1      ;bei Interrupts notwendig
ldi xl, low(zeit1)  ;laedt Zaehlregisterpaar mit
ldi xh, high(zeit1)  ;oben deklariertem Wert "Zeit1"
;ldi zl, low(zeit1)  ;laedt Zaehlregisterpaar mit *falsches Register!*
;ldi zh, high(zeit1)  ;oben deklariertem Wert "Zeit1"
rjmp repeatx


Aber ändert nichts am Problem.

ciao
gustav
OP #5311185
Lesenswert?

Karl B. schrieb:
> also der Wechsel von High nach Low hier das Entscheidende ist,

Genau so ist das, sieht man auch im Zeitdiagramm.
Daten werden mit der fallenden Flanke übernommen, ausgegeben bei der 
steigenden.

Karl B. schrieb:
> cbi daten, ena
> nop
> nop
> sbrc temp, 7
> rjmp busyflag1


Wie lang dauert ein nop?...  tADD nicht eingehalten?
tADD = Die Zeit die der Adrescounter zum weit erzählen braucht, nachdem 
das Busy-Flag auf Low geht (~5-10µs).




PS: Deine Prosa und Bild bring ich grad nicht in Einklang!?
Der Rest iat leider auch nich viel klarer.
#5311357
Lesenswert?

Teo D. schrieb:
> Daten werden mit der fallenden Flanke übernommen, ausgegeben bei der
> steigenden.

Hi @Th,
genau das ist mein Denkfehler.
(Ich steh' soo kurz davor, das zu lösen...das ist immer soo blamabel.)

Danke nochmals für den Tip mit dem Adresscounter.

Dann hatte ich noch nen dicken Bug drin, wie gesagt, das Doppelregister 
bei der einen Zeitschleife falsch. Die wird bei der Init Routine 
glücklicherweise nicht am Anfang gebraucht.
Ich merkte das daran, dass die Hintergrundbeleuchtung am Ende nicht 
blinkt.
Also musste das irgendwo hängen geblieben sein. Bei der Zeitschleife. 
Und nicht etwa bei der Busy-Flag-Abfrage.


Teo D. schrieb:
> Deine Prosa und Bild bring ich grad nicht in Einklang!?

Das "T" fehlt im Bild. Der Erste Buchstabe des Tabellen-Strings wurde 
"geschlabbert".

Teo D. schrieb:
> Der Rest iat leider auch nich viel klarer.

Die Sache mit den "unsauberen" Impulsen auf dem Port.
Müsste echt noch einmal mit dem Oszi dran, und mir die Sache anschauen.
Ursachen: Irgendwelche Kontaktfehler, am selben Port Ausgänge und 
Eingänge die sich vielleicht gegenseitig verkoppeln. Weiß nicht.
Die Flachbandleitung ist mit ca. 20 cm vielleicht schon zu lang.
(Stichwort Busabschluss.)

ciao
gustav
OP #5311376
Lesenswert?

Karl B. schrieb:
> Die Flachbandleitung ist mit ca. 20 cm vielleicht schon zu lang.
> (Stichwort Busabschluss.)

Kann da nur was ohne BF Abfrage zu sagen sagen. Da gibst kaum Probleme.
Steckbrett, Display, ~40cm Flachband, 2. Display, keine Problem.
Wenn du da rumspielst, gib bitte laut wie's mit BF aussieht. Dann muss 
ich vielleicht irgend wann, mein Oszi nicht bemühen. :)
#5311736
Lesenswert?

Teo D. schrieb:
> Wenn du da rumspielst, gib bitte laut wie's mit BF aussieht.

Hi,
das ist mir jetzt noch aufgefallen:
Es kann nur an der Verdrahtung liegen, bzw. an der MCU-Portbeschaltung.
Beim Flashen kommt bei gestecktem Portstecker:
"An Error has occured."
Ziehe ich den Portstecker, ist die Fehlermeldung weg und es wird wie 
gewohnt geflasht.
Dann hab' noch einen Tip gelesen: Man kann das Watchdog-Timout in die 
BF-Abfrage einbauen. Damit ist sichergestellt, dass das Programm nicht 
in der BF-Routine hängenbleibt. Zumindest resettet sich die MCU dann und 
durchläuft die Initialisierung erneut. Dazu ist aber zu beachten, dass 
aufgrund Bestehenbleibens der Versorgungsspannung der POSR vom LCD nicht 
durchlaufen wird. Mit Portreset und dreimal hex 30 bzw. 03 und 
Warteschleifen fängt es dann wieder an. Aber das war ja schon klar.

ciao
gustav
#5314513
Lesenswert?

Hi,
da ich den Port in Verdacht hatte, schaute einmal eine alternative 
Initialisierungsroutine an.
(Die fand ich in der Literatur.)

Teo D. schrieb:
> Ne was nur immer wieder ärgerlich ist, das ich immer an so simplen
> Dingen hänge...

Und interessant, obwohl es im Buch vor Programmbeispielen nur so 
wimmelt, finde ich kein einziges für eine Busyflagabfrage.
Da stehen wir also gar nicht einmal so "dumm" da.
Scheint so, als ob sich sogar ein renommierter Fachbuchautor um diese 
Sache herummogelt.

Noch ein Fallstrick:
Der durch Port-Bit-Setzen auf "Eins" gesetzte "rs" wird durch die 
nachfolgenden Ausgabe wieder mit der "Null" des ausmaskierten "oberen" 
Ports-Nibbles überschrieben, so dass das Display ständig im 
Befehls-Modus steht.
Das bedeutet, dass im Charakter-Übergabemodus dass Rs-Impuls-Setzen 
hinter der Datenausgabe aber vor dem Enable-Impuls stehen muss.
Und da könnte es mit dem Timing evtl. eng werden. Daher wurde in die 
Enableimpuls-Routine vorher und hinterher noch "nop" gesetzt.
Die Code-Schnipsel sind im Anhang.
(Und man braucht kein zweites "swap"... entgegen der Feststellung im 
Buch.)



ciao
gustav
Angehängte Dateien:
#5314541
Lesenswert?

Karl B. schrieb:
> Noch ein Fallstrick:
> Der durch Port-Bit-Setzen auf "Eins" gesetzte "rs" wird durch die
> nachfolgenden Ausgabe wieder mit der "Null" des ausmaskierten "oberen"
> Ports-Nibbles überschrieben, so dass das Display ständig im
> Befehls-Modus steht.

Daher habe ich meine LCD-Lib so geschrieben, daß sie nur Bitbefehle 
benutzt. Viele MCs können einzelne Bits atomar setzen, d.h. ohne 
Seitenefekte auf andere Bits des selben Ports.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren