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
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
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.
...
@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?
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.
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. ;) ;)
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.
...
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?
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 ;)
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.
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. :-(
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.
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.
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.
...
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.
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.
...
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.
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.
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... ;-)
...
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.