Hallo, ich habe ein (recyceltes) LCD (das standardgemäß funktionieren könnte, aber ohne Datenblatt) an 2 Schieberegister angeschlossen. Das eine ist für den 8bit Datenbus zuständig, das andere für die Steuerungsleitungen. Die Schieberegister bekommen die Bits von einer Tina23 via SPI rein gedrückt. Die Initialisierung scheint zu klappen, denn nach dem Einschalten ist nur eine Zeile dunkel, nach der Initialisierungssequenz habe ich 2 dunkle Zeilen. Die Textübertragung klappt noch nicht. Bislang mache ich es so, dass ich jeweils 2 Byte (Daten und Steuerung) zweimal übertrage. Bei der ersten Übertragung ist das enable-bit gesetzt, beim zweiten Mal wird es gelöscht (bei sonst identischen Daten). Ist das vom Ansatz her richtig, oder müsste ich die Daten 3mal übertragen (und dann beim 2ten Mal enable einschalten)? Ich habe es versuchsweise auch mal umgekehrt übertragen. Ach ja, die Schieberegister bekommen den RCK-Puls nach dem Schieben von 2 Bytes. Die Befehle habe ich mit einem "seriellen Debugger" (2 Schieberegister mit LEDs an den Ausgängen) überprüft. Falls die Frage schon mal gestellt wurde, bitte ich um Nachsicht, dass ich nicht alle Freds, die zu LCDs gefunden werden, gelesen habe.
Hallo Peter, danke für den Tip. Ich hatte eher gehofft, etwas über das Zeitverhalten von LCDs zu erfahren, bzw. darüber, wann denn die Daten verarbeitet werden. Nun gut. Habe mir also einen Treiber mit dem 74HC164 aufgebaut, alles angeschlossen und das Proggy für die Tina umgeschrieben, aber es will noch net. Könnte bitte jemand das Programm mal kontrollieren und mir Viehtbäck geben, ob mein Fehler Programm ist, oder ich mich von meinem LCD verabschieden muss?!?
Hallo, haste den Kontrast auch richtig eingestellt ??? gruß BerndB
Hallo, > haste den Kontrast auch richtig eingestellt ??? Habe mir extra noch eine Huckepack-Platine mit einem Spannungsinverter gemacht, um beide Fälle der Kontrastspannung durchprobieren zu können. Ob er richtig ist, kann ich nicht beurteilen. Bin Neuling in Sachen HW. Ich sehe auf jeden Fall schwarze Balken und eine Veränderung nach der Initialisierung - insofern scheint die Kommunikation zumindest grundsätzlich zu klappen. Ich habe es inzwischen auch mit diesem LCD probiert: http://www.pollin.de/shop/detail.php?pg=NQ==&a=NzY3OTc4OTk= Muss dazu sagen, dass ich das Folienkabel entfernt und ein Flachband angelötet habe. Das Flachband habe ich so beschaltet, dass das Enable des 2. Controllers nach DB7 kommt, sodass ich in den ersten Leitungen identische Belegung mit einem 2zeiligen Display habe. Nach dem Umlöten habe ich mit einem Durchgangsprüfer alle Pins getestet, um einen evtl. Kurzschluss zu entdecken (Das 1.27 Raster war ziemlich heftig für mich - aber mit Löthonig habbichs schließlich hinbekommen). Das WD-C2704 (nur ein Controller angeschlossen) verhält sich noch seltsamer, wie mein recyceltes Optrex. Anfangs hatte ich es frei auf dem Tisch liegen und da rasten die Buchstaben/Zeichen wild über mehrere Zeilen (eine blieb ganz schwarz). Dann habe ich es richtig angeschraubt und die Steuerplatine anders verkabelt - jetzt ist Ruhe. So sehr Ruhe, dass nach den schwarzen Balken sich nix mehr ändert. Da ich Neuling bin, bin ich recht verunsichert und weiß nicht, ob ich bei dem Umschreiben des Programmes, oder in der HW, oder beidem einen Fehler gemacht habe.
Santiago wrote: > danke für den Tip. Ich hatte eher gehofft, etwas über das Zeitverhalten > von LCDs zu erfahren, bzw. darüber, wann denn die Daten verarbeitet > werden. So kritisch ist das Timing nicht. Die Initsequenz lt. Datenblatt sollte eingehalten werden. Der Enable-Puls sollte ~1µs lang sein. Nach einem Byte ~40µs warten, nach Clear ~1,5ms. > Könnte bitte jemand das Programm mal kontrollieren und mir Viehtbäck > geben, ob mein Fehler Programm ist, oder ich mich von meinem LCD > verabschieden muss?!? Ginge es vielleicht als ZIP und mit Zeilenende (CR+LF)? Peter
> So kritisch ist das Timing nicht. > Die Initsequenz lt. Datenblatt sollte eingehalten werden. > Der Enable-Puls sollte ~1µs lang sein. > Nach einem Byte ~40µs warten, nach Clear ~1,5ms. Ja, DIE timings konnte ich auch dem Datenblatt entnehmen. Was mir fehlt, ist wann die LCD-Controller üblicherweise die Daten verarbeiten. Wird von Enable der Pegel ausgewertet, oder die steigende oder fallende Flanke getriggert ... ... auch wenn es vielleicht umständlich sein sollte - ich denke, es sollte auch mit den beiden 595ern von meinem ersten Treiber auch funzen. Wenn ich wüßte, worauf es ankommt, könnte ich das Proggy ja entsprechend umbauen. Ich habe ein Baureihen-Handbuch von Optrex, weiß allerdings nicht, ob meines sich entsprechend verhält. Unter der Annahme dass dem so wäre, würde ich das Diagramm so interpretieren, dass die Busdaten bei jedem Flankenwexel von Enable verarbeitet werden. Das würde meinem ursprünglichen Ansatz entgegen kommen, denn dann bräuchte ich dieselben Daten nicht mehrfach senden?!? >> Könnte bitte jemand das Programm mal kontrollieren und mir Viehtbäck >> geben, ob mein Fehler Programm ist, oder ich mich von meinem LCD >> verabschieden muss?!? > > Ginge es vielleicht als ZIP und mit Zeilenende (CR+LF)? OK, sorry - da ich GVim (zusammen mit TC) auch unter Windows nutze, spüre ich von derlei Ärgernissen nix. Hoffe das Format passt jetzt. Habe einfach in vim den Dateityp auf "DOS" geändert und neu gespeichert.
Hallo, habe gerade nochmal nachgerechnet. Hat jetzt zwar nix mit der LCD Funktionalität zu tun, trotzdem sollte die Zeile 43 von clock.h wie folgt lauten:
1 | #define TIMER_IPS ((uint16_t)(((uint16_t)((F_CPU / 0xFFFF) + 0.999) + 1 / 2) * 2))
|
Santiago wrote:
> ... und hier die Sauce als ZIP.
Sieht fast o.k. aus.
Die Bittabelle im Progmem kann meines Wissens aber nicht als BITNO[i]
gelesen werden. Schau mal ins Listing, ob da LD oder LPM verwendet wird.
Es tut aber auch nicht so weh, 8 Konstanten im SRAM zu belassen.
Peter
Hallo Peter, danke für Deine Unterstützung! > Sieht fast o.k. aus. ;) > Die Bittabelle im Progmem kann meines Wissens aber nicht als BITNO[i] > gelesen werden. Schau mal ins Listing, ob da LD oder LPM verwendet wird. > Es tut aber auch nicht so weh, 8 Konstanten im SRAM zu belassen. Hm, ja ... leuchtet ein. Habe die beiden Arrays (das Gleiche gilt ja auch für das Array der Monate?!?) aus dem Progmem entfernt, jetzt blinkt die 2. Zeile in unregelmäßigen Abständen. Allerdings komplett als schwarze Blöcke. Zeichen sind keine erkennbar. Meine Assemblerkenntnisse lassen doch sehr zu wünschen übrig, jedoch wenn ich die richtige Stelle gefunden habe, wird dort LD verwendet. Wollte erst ein diff posten, allerdings sind alle Adressen verschoben, sodass ein diff nicht wirklich Sinn macht. Deshalb also beide Listings.
Hallo, möchte an dieser Stelle nochmals nachhaken, denn geschoben (mit dem 74HC164) läuft bei mir noch immer nix. Folgender Testaufbau: Ein ATtiny2313 steuert (gleichzeitig) ein LCD parallel und eines seriell an. Beide sollen das gleiche ausgeben - aber nur bei dem mit paralleler Ansteuerung funktioniert es auch. Im beigefügten Archiv ist, neben dem Schaltplan der Schiebung, jeweils eine Aufnahme mit einem LCD parallel und dem anderen seriell angesteuert. Damit es nicht heißt, es liegt an Kontrast, Anschluss oder LCD selber, habe ich die Displays auch vertauscht angeschlossen (bei dem großen ist Enable des zweiten Controllers nicht angeschlossen, deshalb bringt dessen erste Zeile Müll). Die Platine mit dem Schieberegister habe ich mehrfach durchgemessen und auch nach Kurzschluss gesucht. Hardwäre-mäßig fällt mir an der Stelle nix mehr ein, was ich noch prüfen könnte. Vielleicht liegt es ja doch an der Software (um die Richtigkeit der Bit-Definitionen überprüfen zu können, liegt der Schaltplan im Archiv, den ich per Durchgangsprüfer auch verifiziert habe). Die betreffenden Funktionen sehen so aus:
1 | #include <inttypes.h> |
2 | #include <avr/io.h> |
3 | #include <avr/pgmspace.h> |
4 | #include <util/delay.h> |
5 | #include "Config.h" |
6 | #define USE_SINGLE_PINS 1
|
7 | |
8 | static void lcdSample(void); |
9 | PROGMEM char defLine0[] = "LCD Module SRD-20 HP"; |
10 | PROGMEM char defLine1[] = "20 Digits x 2 Lines."; |
11 | PROGMEM char clrLine[] = " "; |
12 | //static uint8_t Bits[] = { 0x02, 0x04, 0x08, 0x01, 0x40, 0x20, 0x10, 0x80 };
|
13 | static uint8_t Bits[] = { 0x80, 0x10, 0x20, 0x40, 0x01, 0x08, 0x04, 0x02 }; |
14 | |
15 | |
16 | static void lcdWriteByte(uint8_t d, uint8_t isData) { |
17 | uint8_t i=0; |
18 | |
19 | /*
|
20 | * first the serial data ...
|
21 | */
|
22 | for (i=0; i < 8; i++) { |
23 | PORT_LCD_SER_CLOCK &= (uint8_t) ~(1 << PIN_LCD_SER_CLOCK); |
24 | |
25 | if (d & Bits[i]) PORT_LCD_SER_DATA |= 1 << PIN_LCD_SER_DATA; |
26 | else PORT_LCD_SER_DATA &= (uint8_t) ~(1 << PIN_LCD_SER_DATA); |
27 | |
28 | PORT_LCD_SER_CLOCK |= 1 << PIN_LCD_SER_CLOCK; |
29 | }
|
30 | |
31 | if (isData) { |
32 | PORT_LCD_SER_DATA |= 1 << PIN_LCD_SER_DATA; |
33 | PORT_LCD_RS |= 1 << PIN_LCD_RS; |
34 | } else { |
35 | PORT_LCD_SER_DATA &= (uint8_t) ~(1 << PIN_LCD_SER_DATA); |
36 | PORT_LCD_RS &= (uint8_t) ~(1 << PIN_LCD_RS); |
37 | }
|
38 | |
39 | PORT_LCD_ENABLE |= 1 << PIN_LCD_ENABLE; |
40 | PORT_LCD_SER_SYNC |= 1 << PIN_LCD_SER_SYNC; |
41 | |
42 | /*
|
43 | * and now the parallel data ...
|
44 | */
|
45 | #if(USE_SINGLE_PINS)
|
46 | if (d & 0x01) PORT_LCD_D0 |= 1 << PIN_LCD_D0; |
47 | else PORT_LCD_D0 &= (uint8_t) ~(1 << PIN_LCD_D0); |
48 | if (d & 0x02) PORT_LCD_D1 |= 1 << PIN_LCD_D1; |
49 | else PORT_LCD_D1 &= (uint8_t) ~(1 << PIN_LCD_D1); |
50 | if (d & 0x04) PORT_LCD_D2 |= 1 << PIN_LCD_D2; |
51 | else PORT_LCD_D2 &= (uint8_t) ~(1 << PIN_LCD_D2); |
52 | if (d & 0x08) PORT_LCD_D3 |= 1 << PIN_LCD_D3; |
53 | else PORT_LCD_D3 &= (uint8_t) ~(1 << PIN_LCD_D3); |
54 | if (d & 0x10) PORT_LCD_D4 |= 1 << PIN_LCD_D4; |
55 | else PORT_LCD_D4 &= (uint8_t) ~(1 << PIN_LCD_D4); |
56 | if (d & 0x20) PORT_LCD_D5 |= 1 << PIN_LCD_D5; |
57 | else PORT_LCD_D5 &= (uint8_t) ~(1 << PIN_LCD_D5); |
58 | if (d & 0x40) PORT_LCD_D6 |= 1 << PIN_LCD_D6; |
59 | else PORT_LCD_D6 &= (uint8_t) ~(1 << PIN_LCD_D6); |
60 | if (d & 0x80) PORT_LCD_D7 |= 1 << PIN_LCD_D7; |
61 | else PORT_LCD_D7 &= (uint8_t) ~(1 << PIN_LCD_D7); |
62 | #else
|
63 | PORT_LCD_DATA = d; |
64 | #endif
|
65 | PORT_LCD_SER_SYNC &= (uint8_t) ~(1 << PIN_LCD_SER_SYNC); |
66 | PORT_LCD_ENABLE &= (uint8_t) ~(1 << PIN_LCD_ENABLE); |
67 | |
68 | _delay_us(45); |
69 | }
|
70 | |
71 | void lcdInit(void) { |
72 | /*
|
73 | * serial connection
|
74 | */
|
75 | DDR_LCD_SER_DATA |= 1 << PIN_LCD_SER_DATA; |
76 | DDR_LCD_SER_SYNC |= 1 << PIN_LCD_SER_SYNC; |
77 | DDR_LCD_SER_CLOCK |= 1 << PIN_LCD_SER_CLOCK; |
78 | |
79 | /*
|
80 | * parallel connection
|
81 | */
|
82 | DDR_LCD_ENABLE |= 1 << PIN_LCD_ENABLE; |
83 | DDR_LCD_RS |= 1 << PIN_LCD_RS; |
84 | #if(USE_SINGLE_PINS)
|
85 | DDR_LCD_D0 |= 1 << PIN_LCD_D0; |
86 | DDR_LCD_D1 |= 1 << PIN_LCD_D1; |
87 | DDR_LCD_D2 |= 1 << PIN_LCD_D2; |
88 | DDR_LCD_D3 |= 1 << PIN_LCD_D3; |
89 | DDR_LCD_D4 |= 1 << PIN_LCD_D4; |
90 | DDR_LCD_D5 |= 1 << PIN_LCD_D5; |
91 | DDR_LCD_D6 |= 1 << PIN_LCD_D6; |
92 | DDR_LCD_D7 |= 1 << PIN_LCD_D7; |
93 | #else
|
94 | DDR_LCD_DATA = 0xFF; |
95 | #endif
|
96 | |
97 | _delay_ms(16); |
98 | lcdCommand(0x38); |
99 | _delay_ms(5); |
100 | lcdCommand(0x38); |
101 | _delay_us(110); |
102 | lcdCommand(0x38); |
103 | lcdCommand(0x38); |
104 | lcdCommand(0x08); |
105 | lcdCommand(0x01); |
106 | lcdCommand(0x06); |
107 | lcdEnable(1); |
108 | |
109 | lcdSample(); |
110 | |
111 | _delay_ms(5000); |
112 | }
|
Deine Bitzuordnung stimmt nicht mit dem Schaltplan überein. Zuerst gibst Du Bit7 aus (0x80), QH ist aber mit DB0 verbunden. Also müßte es richtig heißen:
1 | static uint8_t Bits[] = { 0x01, ... |
Peter
Hallo Peter,
danke für Deine Aufmerksamkeit.
> Deine Bitzuordnung stimmt nicht mit dem Schaltplan überein.
QH ist mit DB0 verbunden - Ja.
Also das ist jetzt so eine Situation, die ich garnicht mag :(
Es funktioniert - und ich versteh nicht warum.
Habe mir nach Deinem Einwand nochmal den Plan angeschaut und dachte mir,
ok, dann habe ich die Richtung für die Bitmuster falsch gewählt und bin
auf die auskommentierte Zeile gekommen.
1 | //static uint8_t Bits[] = { 0x10, 0x80, 0x40, 0x20, 0x02, 0x04, 0x08, 0x01 };
|
2 | static uint8_t Bits[] = { 0x01, 0x08, 0x04, 0x02, 0x20, 0x40, 0x80, 0x10 }; |
Wollte schon posten, dass es immer noch nicht tut - da viel mir auf, dass Du geschrieben hattest - mit 0x01 anfangen. Meine Liste angeschaut - diese umgedreht und jetzt funzt es. Nur versteh ich net, warum ich von hinten anfangen muss? Entspricht nicht QA dem LSB? Ich glaube, jetzt bin ich völlig durcheinander. Für etwas mehr Licht im Dunkel wäre ich sehr dankbar.
Das Schieberegister schiebt von vorn nach hinten. Ehe das Eingangsbit an QH erscheint, muß es also 8-mal geschoben werden. Es muß das höchstwertigste zuerst eingeschoben werden (MSB first). Peter P.S.: Oftmals läßt sich ein Fehler nur finden, wenn man auch den Schaltplan postet.
Hallo Peter, herzlichen Dank für Deine Geduld. > Ehe das Eingangsbit an QH erscheint, muß es also 8-mal geschoben werden. Wenn ich das Datenblatt in Ruhe nochmal anschaue, dann kann man es "eigentlich" garnicht anderst interpretieren. Schätze an der Ecke bin ich noch lange nicht sattelfest. MSB, LSB, steigende oder fallende Flanke ... puh! Bißchen viel auf einmal. Jedenfalls kann ich jetzt mein Proggy wieder aufräumen. Das ist ja auch was :) > Oftmals läßt sich ein Fehler nur finden, wenn man auch den Schaltplan > postet. Ich versuche auch in diesen Punkten dazu zu lernen.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.