Forum: Mikrocontroller und Digitale Elektronik LCD + SD-Karte an SPI- Pins ?


von Henning (Gast)


Lesenswert?

Hallo Leute,

ich muss eine SD-Karte, ein LC-Display und 2 Tasten an 10 Pins eines 
Atmega anschließen.

Nun meine Frage -> kann ich das Display (4bit-mode ohne Busy) und die 
SD-Karte an die SPI-Pins zusammenschalten und dann so tun, als ob das 
Display auch ein SPI-Device wäre und es nur eben nur per ENABLE- Leitung 
zum entsprechenden Zeitpunkt ansprechen?

mfg - Henning

von fubu1000 (Gast)


Lesenswert?

Hallo,
na klar geht das, musst halt SPI an und aus machen, je nachdem ob du SD 
oder LCD ansprichst.
Nur den Pin für ChipSelect der SD und Enable des Lcd's nicht mehrfach 
beschalten.

Gruss

von ich (Gast)


Lesenswert?

4-Bit Mode ist aber kein SPI Mode, dann sollte die LCD schon auch im SPI 
Mode betrieben werden.

von Hannes L. (hannes)


Lesenswert?

ich wrote:
> 4-Bit Mode ist aber kein SPI Mode, dann sollte die LCD schon auch im SPI
> Mode betrieben werden.

Warum?

Das LCD braucht 5 Pins plus Enable, solange Enable nicht bedient wird, 
kümmert es sich nicht um das Gezappel an Daten und Register-Select.

SPI braucht 3 Pins plus Enable, solange Enable nicht bedient wird, wird 
der SPI-Bus ignoriert, also kann an den SPI-Pins auch ohne SPI-Protokoll 
mit Daten für das LCD geklappert werden.

Das macht also:
- 5 Pins für LCD-Data + RS, auf denen auch SPI ist
- 1 Pin LCD-Enable
- 1 Pin SPI-Chip-Enable
- 2 Pins Taster

Von den 10 Portpins bleibt also unter Umständen noch einer übrig.

Natürlich wird die Software dadurch etwas komplexer, Kartenzugriffe und 
LCD-Ausgaben müssen aufeinander abgestimmt werden, aber danach wurde ja 
nicht gefragt.

...

von Andreas K. (a-k)


Lesenswert?

Taster lassen sich mit Widerstand auch problemlos an den LCD-Datenpins 
unterbringen.

von Pete K. (pete77)


Lesenswert?

Bau das LCD mit einem PCF8574A auf I2C um, dann hast Du 3 Pins gespart 
:-)

von Henning (Gast)


Lesenswert?

@Andreas Kaiser:
Wenn ich die Taster aber dort anbringe, dann könnte mir das den LCD- 
Datenverkehr durcheinander bringen?! Und eigentlich hatte ich vor die 
Taster auf Interrupt-PINS zu verschalten.

@all die anderen:
ich wusste halt nicht, ob das so einfach klappt ein ja eigentliches 
nicht-spi gerät an den spi-bus zu packen.
das problem ist ja auch, dass die sd-karte kein "echtes" spi-gerät 
darstellt, und nach dem SS noch ein weiteres signal sendet, aber damit 
muss ich dann halt klarkommen.


das gute in meiner anwendung ist, dass das lcd-display nur einmal pro 
sekunde aktualisiert wird und auf die sd-karte je nach datenaufkommen 
auch nur etwa alle 15 bis 60minuten.


noch eine kurze frage zu den write/erase cycles solch einer karte. wenn 
ich nun immer einen 512byte-Block beschreibe, und mache dies bis eine 
16mb-Karte gefüllt ist (also runde 9millionen mal?!?!), dann sind doch 
diese write/erase cycles erst dann interessant, wenn ich erneut auf den 
selben speicherblock zugreife, richtig?
oder muss ich jeden schreibzugriff mitzählen?

von Andreas K. (a-k)


Lesenswert?

Henning wrote:

> Wenn ich die Taster aber dort anbringe, dann könnte mir das den LCD-
> Datenverkehr durcheinander bringen?!

Nicht wenn das LCD ohne Lesefunktion betrieben wird (RW=0).

Technik: GND - Taster - Widerstand 3K3 - Datenleitung.

Wenn ins LCD geschrieben wird ist egal ob der Taster aktiv ist oder 
nicht, weil sich der AVR am Widerstand nicht stört.

Für die Tasterabfrage stellt man die Datenleitungen auf Eingang ohne 
Pullup. Für die nötigen Pullups sorgt der Display-Controller 
(HD44780&Co). Diese zieht der Taster aber trotz Serienwiderstand 
problemlos auf low Pegel.

Konflikt zwischen LCD-Aktivität und Tasterabfrage im Interrupt entsteht 
nicht, wenn man bei der Abfrage temporär die Pins auf Eingang 
programmiert, abfragt, und wieder auf den vorherigen Stand bringt.

Will man vom LCD unbedingt auch lesen (was einen Pin kostet), dann wird 
die Auslegung des Taster-Widerstands etwas kniffliger, weil der 
Display-Controller weit schwächer treibt als der AVR. Nötig ist das aber 
nicht, weil die LCDs prima auch ohne RW arbeiten, indem man feste 
Wartezeiten statt Busy-Abfrage einbaut.

> Und eigentlich hatte ich vor die
> Taster auf Interrupt-PINS zu verschalten.

Wenn du die zum Aufwecken brauchst, wär's ein Grund, aber der Pin Change 
Interrupt moderner AVRs tut es auch.

Ansonsten ist eine Anfrage im Timer-Interrupt für's Entprellen viel 
praktischer als ein direkter Interrupt.

von Henning (Gast)


Lesenswert?

irgendwie hört sich das mit den taster am LCD besser an finde ich... 
muss das ganze wohl mals ausprobieren.

von Simon K. (simon) Benutzerseite


Lesenswert?

Pete K. wrote:
> Bau das LCD mit einem PCF8574A auf I2C um, dann hast Du 3 Pins gespart
> :-)

Besser ist es, das LCD an einen 4094 zu hängen, weil es nämlich dann 
auch am SPI-Bus hängen kann. Außerdem ist ein 4094 um einiges billiger 
als der I2C Schrott. ;) ;)

von Andreas K. (a-k)


Lesenswert?


von Hannes L. (hannes)


Lesenswert?

Naja, bis zu 4 Tasten über Widerstände sind schon die optimale Lösung. 
Das macht dann 6 Pins für das LCD und 4 Pins für SPI (müsste auch mit 3 
gehen). Die Dannegger-Bulletproof-Entprellung lässt sich auch 
(zumindest in ASM) gut in die LCD-Ausgabe integrieren.

Jeder zusätzliche Baustein (egal ob I²C oder Schieberegister) 
verkompliziert nur unnötig Schaltung und Platine.

...

von Andreas K. (a-k)


Lesenswert?

Hannes Lux wrote:

> Naja, bis zu 4 Tasten über Widerstände sind schon die optimale Lösung.

5 Tasten. Mit der RS Leitung geht das genauso.

von Henning (Gast)


Lesenswert?

Also schreibe ich mein Programm so, als hätte ich gar kein LCD und nur 
dann wenn ich den LCD-Inhalt unmittelbar ändern möchte schreibe ich die 
Register um, initialisiere das LCD, schreibe drauf und schreibe die 
Register wieder auf EINGANG um?

Das "ständige" umschreiben der Register hat auch im Mikrocontroller 
(mega16) keinen "Verschleiß" zur Folge?

von Simon K. (simon) Benutzerseite


Lesenswert?

Henning wrote:
> Das "ständige" umschreiben der Register hat auch im Mikrocontroller
> (mega16) keinen "Verschleiß" zur Folge?

Hehe! Also sowas habe ich auch noch nie gelesen. Natürlich nicht ;)

von Henning (Gast)


Lesenswert?

stimmt, war irgendwie ziemlich blöd von mir. die i/o´s sind erstmal ja 
auch nur register :P

von Andreas K. (a-k)


Lesenswert?

Henning wrote:

> Also schreibe ich mein Programm so, als hätte ich gar kein LCD und nur
> dann wenn ich den LCD-Inhalt unmittelbar ändern möchte schreibe ich die
> Register um, initialisiere das LCD, schreibe drauf und schreibe die
> Register wieder auf EINGANG um?

Dann musst du aufpassen, dass nicht genau die LCD-Routine von der 
Abfrage im Timer-Interrupt unterbrochen wird. Geht auch, aber einfacher 
ist es andersrum, also bei der Tasterabfrage:
- DDRx der Pins sichern.
- Pins als Input programmieren.
- 2 CPU-Takte warten!
- PINx auslesen.
- DDRx wieder auf gesicherten Stand zurücksetzen.

Wenn du die Taster wirklich als Interrupt-Quelle benötigst, dann wird es 
ein kleines bischen komplizierter.

von Henning (Gast)


Lesenswert?

Da hast Du auch wieder Recht. Aber dann müsste ich das Umschreiben der 
Register und das Auslesen noch mit in meine Timerroutine reinbringen, 
stehe immer nicht so auf das Aufpumpen von Interrupt. :-(

von Andreas K. (a-k)


Lesenswert?

Also nu - wenn du nicht Tanja heisst und 122880 Interrupts pro Sekunde 
durchpfeifst, dann kommt es auf die 8 Takte ja wohl auch nicht an.

Interrupts für PeDa's Debouncing macht man alle 10ms oder so.

von Henning (Gast)


Lesenswert?

Ich brauche gar nicht mal solch ein krasses Debouncing. Ich würde 
einfach in meinem Sekunden-Interrupt die Taster abfragen und 
entsprechend Flag setzen. Sind nur zur Steuerung einer kleinen 
Menüstruktur, die aber vermutlich nur alle paar Tage überhaupt mal in 
Benutzung sein wird.

von Hannes L. (hannes)


Lesenswert?

Henning wrote:
> Ich brauche gar nicht mal solch ein krasses Debouncing.

Sooo krass ist das nun auch wieder nicht. PeDas 
Bulletproof-Entprellung braucht nur ein rundes Dutzend Takte alle 10 
bis 20 ms. Sie muss auch nicht im Interrupt laufen, sondern kann auch 
per Semaphore (Flag) vom Timer synchronisiert werden.

> Ich würde
> einfach in meinem Sekunden-Interrupt die Taster abfragen und
> entsprechend Flag setzen.

Dann bietet es sich doch an, einen 10ms-Interrupt zu nutzen, in dessen 
ISR die 100stel Sekunden für die Sekundenzählung zählen und ein Flag für 
die Entprellung (als Job der Mainloop) zu setzen. Und damit bei 
LCD-Ausgaben keine Tastenaussetzer entstehen, kann man auch im LCD-Wait 
das Prellflag prüfen und den Entprelljob aufrufen.

> Sind nur zur Steuerung einer kleinen
> Menüstruktur, die aber vermutlich nur alle paar Tage überhaupt mal in
> Benutzung sein wird.

Naja, auch nur gelegentlich benutzte Menüs sollten ordentlich 
funktionieren. Besonders dann, wenn es kein zusätzlicher Aufwand ist. 
Das Verschmähen dieser Tastenentprellung ist Sparen am falschen Fleck. 
Sowas rächt sich mit Sicherheit irgendwann.

...

von Andreas K. (a-k)


Lesenswert?

Hannes Lux wrote:

> Und damit bei
> LCD-Ausgaben keine Tastenaussetzer entstehen, kann man auch im LCD-Wait
> das Prellflag prüfen und den Entprelljob aufrufen.

Welche Aussetzer? Der längste LCD-Wait beträgt 2ms.

von Hannes L. (hannes)


Lesenswert?

Andreas Kaiser wrote:
> Hannes Lux wrote:
>
>> Und damit bei
>> LCD-Ausgaben keine Tastenaussetzer entstehen, kann man auch im LCD-Wait
>> das Prellflag prüfen und den Entprelljob aufrufen.
>
> Welche Aussetzer? Der längste LCD-Wait beträgt 2ms.

Du wirst doch aber auch ganze Zeichenketten ausgeben, oder kehrst Du 
nach jedem ausgegebenen Byte zur Mainloop zurück?

Ich synchronisiere LCD-Wait übrigens auch über einen Timer. Und wenn es 
die SRAM-Auslasung zulässt, dann lege ich im SRAM auch noch einen 
Bildschirmspeicher an, das macht LCD-Wait total überflüssig. Ein Job der 
Mainloop schaufelt dann alle 1ms ein Byte aus dem Bildschirmspeicher an 
das LCD und entwirrt dabei nebenbei noch die verschachtelte 
Zeilenzuordnung.

Ist kein SRAM für den Bildschirmspeicher übrig, dann prüfe ich im 
LCD-Wait (Warten auf ein vom Timer gesetztes Flag) die Jobflags und 
arbeite darin die Jobs der Mainloop ab. Das ist effizienter als 
Warteschleifen.

...

von Andreas K. (a-k)


Lesenswert?

Hannes Lux wrote:

> Du wirst doch aber auch ganze Zeichenketten ausgeben, oder kehrst Du
> nach jedem ausgegebenen Byte zur Mainloop zurück?

Nö. Aber normalerweise muss ich mittendrin in der Textausgabe auch keine 
Taste abfragen.

Aber was ist denn dabei das Maximum:
- 2ms für Tabula Rasa,
- 50µs pro Zeichen.
Ergibt bei 4x20 also eine Gesamtzeit von 6ms bis das LCD voll ist und 
nix mehr draufpasst. Damit kann ich leben.

von Henning (Gast)


Lesenswert?

Ich denke sowas ist ganz einfach von der Anwendung abhängig und 
Stolpersteine im zeitlichen Programmablauf zu vermeiden ist nie 
verkehrt. In meiner Anwendung ist das jedoch überhaupt nicht schlimm, 
der Mega läuft auf 8Mhz und wird sich wohl eher langweilen als vor 
Arbeit sterben.

von Hannes L. (hannes)


Lesenswert?

Andreas Kaiser wrote:

> Aber was ist denn dabei das Maximum:
> - 2ms für Tabula Rasa,
> - 50µs pro Zeichen.
> Ergibt bei 4x20 also eine Gesamtzeit von 6ms bis das LCD voll ist und
> nix mehr draufpasst. Damit kann ich leben.

Ja, ok, wobei ich den LCDs etwas mehr Zeit gönne, denn ich hatte schon 
welche, die mehr Zeit brauchten. Außerdem kann ich nicht so schnell 
lesen... ;-)

...

von Henning (Gast)


Lesenswert?

Wie ist denn das mit der Leitungslänge bei den SD-Karten? Sind etwa 30cm 
Flachbandkabel in Ordnung oder ist das "unmöglich"?

von Henning (Gast)


Lesenswert?

Nachtrag: erste Tests mit der SD-karte liefen bisher absolut erfolglos. 
Muss morgen nochmal alles mit vernünftigem Spannungsregler usw. 
aufbauen, so mit eben schnell Dioden und WIderstände hinfummeln wird 
nix.

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.