Forum: Mikrocontroller und Digitale Elektronik Schieberegistersachen


von Simon K. (simon) Benutzerseite


Lesenswert?

Hallo,

Ich habe mal eine kleine Frage.
Ich schließe ein HD44780 Display per Schieberegister an.
Schieberegister läuft an einem Mega16 mit SPI eingeschaltet. Wenn ich
nun den SPI Takt auf Fsys/128 stelle bei 16Mhz. dann hätte ich doch
quasi 16000000/128=125000 Clocktakt. Bei 8Bits entspräche das
125000/8=15625 Hz Strobetakt.

1/15625Hz = 64uS. Heißt es jetzt, dass wenn das Display 40uS für einen
Befehl braucht (Die langen INIT Befehle mal ausgelassen) dass ich hier
keine warteschleifen brauch?

von Mueschel (Gast)


Lesenswert?

Im Prinzip ja.
Du musst aber natürlich vor dem Senden der nächsten Daten immer so
lange warten, bis die SPI alles ins Schieberegister geschaufelt hat.
Insofern brauchst du doch Warteschleifen, bzw. musst auf den
entsprechenden Interrupt warten.

von Simon K. (simon) Benutzerseite


Lesenswert?

Jo, ok.

von Hannes L. (hannes)


Lesenswert?

"Warteschleifen" braucht man eigentlich garnicht, wenn man es
dementsprechend programmiert. Denn Warteschleifen vernichten nur
wertvolle Rechenleistung. Sie sollten daher nur bei kurzen
zeitkritischen Wartezeiten (im µs-Bereich) angewendet werden.

Ich habe ein Display (8 Zeilen, 24 Zeichen) mit einem Timer-Int
synchronisiert (Mega8535).
Der Timer-Int setzt nur ein Flag, dass die "Wartezeit" abgelaufen
ist. Im Hauptprogramm wird dieses Flag abgefragt und dann das nächste
Zeichen ausgegeben. Wenn andere Arbeiten anliegen, können auch mal
einige "Ausgabetermine" ausfallen, das merkt aber keiner.
Da in gewissen Programmsituationen der ganze Bildschirm (192 Zeichen)
auf einmal aktualisiert wird, habe ich der Ausgaberoutine einen
Ringbuffer von 256 Bytes spendiert (es war noch ausreichend SRAM
vorhanden, der Einfachheit des Pointerhandlings im Bereich von $100 bis
$1ff). Die LCD_Data-Routine schreibt nun nur in den Ringbuffer (geht
wahnsinnig schnell), die Zeichen werden dann so ausgegeben, wie der
Controller Zeit dazu findet, bis der Lesepointer den Schreibpointer
erreicht hat. Dann wird ein "Jobflag" gelöscht, welches in der
LCD_DATA-Routine gesetzt wurde, worauf die Zeichenausgabe eingestellt
wird.
Auch die Cursor-Positionierung erfolgt über den Ringbuffer. Dazu wurden
Steuerzeichen im unteren ASCII-Bereich vereinbart. Jede Positionierung
benötigt zwei Bytes im Ringbuffer.

Wenn deine SPI-Ausgabe dementsprechend langsam ist, dann kann die
Ausgabe des nächsten Zeichens natürlich über den SPI-Interrupt
synchronisiert werden. Einen Ringbuffer wirst du aber trotzdem
brauchen.

...

von Peter D. (peda)


Lesenswert?

Ja, geht super.

Habe ich beim ATTiny12 auch gemacht.

Die Daten müssen ja nur die 1µs stabil anliegen, während E = 1 ist.

Du kannst also ruhig die nächsten Daten reinschieben, während das LCD
noch den alten Befehl abarbeitet.

Ich habe ein 74HC164 genommen, dann reichen 3 Leitungen zum LCD.


Peter

von Simon K. (simon) Benutzerseite


Angehängte Dateien:

Lesenswert?

Ok klingt gut. So sieht meine Schaltung aus.

Wollte mir eine kleine lib basteln, die man dann immer mal wieder
verwenden kann.

C-Code habe ich schon, allerdings ist das Display hier sehr
eigenwillig. Hat irgndwie ne Macke!

von Peter Dannegger (Gast)


Lesenswert?

Achso, Du benutzt den 4Bit-Modus, dann hast Du ja jede Menge Wartezeit.

Ich habe den 8Bit-Modus benutzt und steuere den E-Pin nach dem Schieben
direkt an, das ist von der Software her einfacher:

http://www.mikrocontroller.net/forum/read-4-22246.html#new

Die Wartezeit (46µs) hatte ich damals noch dringelassen (unnötig).


Bei Displays mit 2 E-Pins braucht man dann insgesamt 4 Portpins (CLK,
DIN, E1, E2).


Peter

von Hannes L. (hannes)


Lesenswert?

Also das WD-C2704M von Pollin (4x27) läuft bei mir im 4-Bit-Mode in ASM
sehr stabil. Allerdings direkt angeschlossen, also ohne
Schieberegister.

Dafür hatte ich mal eine Ansteuerung geschrieben, bei der die Pins frei
verteilt werden dürfen, also jeder Pin auf einem anderen Port sein darf.
Einschränkung sind die Datenpins, die müssen in einem Nibble eines Ports
liegen, oberes oder unteres Nibble kann ausgewählt werden. Dies schafft
die Möglichkeit, die für LCD genutzten Pins (des Mega8) so zu
verteilen, dass man die Spezialfunktionspins frei halten kann.
Ich habe aber bisher noch keine Zeit und Muße gefunden, diese Routinen
so abzuändern, dass die Ausgabe über Ringbuffer und
Timer-Synchronisation erfolgt. Dort, wo ich das LCD einsetze, werden
immer nur wenige Zeichen aktualisiert, da ist Ausgabecache nicht
unbedingt erforderlich.

...

von Simon K. (simon) Benutzerseite


Lesenswert?

<<Achso, Du benutzt den 4Bit-Modus, dann hast Du ja jede Menge
Wartezeit.

Ich habe den 8Bit-Modus benutzt und steuere den E-Pin nach dem
Schieben
direkt an, das ist von der Software her einfacher:



Hm.Hatte ich mir auch erst gedacht, aber effektiver ist es doch, wenn
man die Schiebezeit vom Schieberegister als Waitstate sozusagen benutzt
um das LCD nicht zu schnell anzusteuern.

Ich muss dann zwar auf den höchsten Teiler beim SPI gehen, aber was
solls. Hängt eh nur das eine Schieberegister dranne.

PS: Irgndwie habe ich das Gefühl die MOS 4094 (meistens CD4094) von
Reichelt sind irgndwie sehr langsam im gegensatz zu dem HC/HCT Typ. Und
das obwohl der HC/HCT Typ kaum mehr kostet.

von ,,,, (Gast)


Lesenswert?

Die CD-Familie ist in der Tat grottenlahm. Aber warum wunderst du dich,
steht doch alles im Datenblatt drin!

von Simon K. (simon) Benutzerseite


Lesenswert?

nene, ist mir ja nachher erst aufgefallen im Datenblatt.. Ist nicht so,
als hätte ich das DB nicht gelesen!


PS: Kleine Frage zu C.

ich hab eine Funktion die einen Parameter erwartet. Nennen wir sie
void func(unsigned char param)
Ist erstmal egal was diese Funktion macht.

Nun habe ich ein Byte (0b00000000) in der Variable
unsigned char var = 0b00000000

Wenn ich jetzt folgenden Funktionsaufruf mache
func(var & (~(1<<4)) );

Wird dann der Wert in var verändert?
Ich schätze nein oder?
Es wird doch erst var in ein temporäres Register gelegt, geOR't und
dann der Funktion übergeben oder?

von The Daz (Gast)


Lesenswert?

var wird nicht veraendert. Du benutzt ja & und nicht &=.

von Simon K. (simon) Benutzerseite


Angehängte Dateien:

Lesenswert?

Hier wäre mein bis jetziger Code. Falls es jemand interessiert oder
vielleicht sogar jemand mal drüberlesen möchte :-). Bin ja noch nicht
so der Profi in gcc für AVR.

von Simon K. (simon) Benutzerseite


Angehängte Dateien:

Lesenswert?

Ok Danke Daz.

Das sieht ja grausam aus. Hier mal besser lesbar.

PS: Ist natürlich keine Spur von Ringbuffer etc.. Werde erstmal die
ganzen Pausen rausnehmen und probieren mit einem WINTEK von Pollin.

von Hannes L. (hannes)


Lesenswert?

@Simon:

Bist du sicher, dass du das Timing korrekt einhältst?
Enable sollte meines Erachtens nach erst aktiviert werden, nachdem die
Data-Pegel sicher anliegen. Ein gleichzeitiges Anlegen der Data-Pegel
und des Enable-Impulses halte ich für zu störanfällig. Ich kann mich da
aber auch irren, ich habe noch kein LCD mit Schieberegister angesteuert.
Mir wäre es aber zu heikel...

...

von Hannes L. (hannes)


Lesenswert?

Achja... Bist du sicher, dass die Pausen auch ausgeführt werden? Nicht,
dass dir die beim Compilieren bzw. Linken wegoptimiert werden...

...

von Simon K. (simon) Benutzerseite


Lesenswert?

Also ich glaube zumindest dass dies keine Probleme macht. War erst auch
zweifelhaft, hat aber wohl zuerst funktioniert. Leider steht im
Datenblatt nix ob es Rising Edge oder Falling Edge strobed. Jetzt bin
ich unsicher.

Die Pausen sind da.
1
 228                 .L26:
2
 229                 .LM31:
3
 230                 /* #APP */
4
 231 00ea 0000          nop
5
 232                 /* #NOAPP */
6
 233 00ec 2196          adiw r28,1
7
 234 00ee 8FEF          ldi r24,hi8(-1)
8
 235 00f0 CF3F          cpi r28,lo8(-1)
9
 236 00f2 D807          cpc r29,r24
10
 237 00f4 D1F7          brne .L26

von Jan (Gast)


Lesenswert?

Laut Datenblatt zu meinem Displaytech 204A mit HD44780 müssen die Daten
mindestens 60 ns vor bis mindestens 10ns nach dem falling edge von E
anliegen.
Das sicherste wäre somit, die Daten am Schieberegister auszugeben, dann
über einen separaten Pin an und wieder auszuschalten und dann erst das
Schieberegister zu überschreiben.

von Peter Dannegger (Gast)


Lesenswert?

Laut HD44780 Datenblatt muß RS vor E = 1 anliegen, dann die Daten mit E
= 1 anlegen und dann E = 0 setzen. Dann das nächste Nibble, macht
insgesamt 5 * Schieben und Latchen.


Ich schiebe einmal 8 Bit, dann setze ich RS auf DIN des
Schieberegisters und dann E = 1, nen bischen warten, E = 0, fertig.


Peter

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
Noch kein Account? Hier anmelden.