Hi, ich baue für die Schule eine LED Wand. Dazu habe ich eine Schieberegisterschaltung wie hier: http://www.mikrocontroller.net/articles/AVR-Tutorial:_Schieberegister mit 3 Stück HC595 gesteckt und an den Ausgängen jeweils eine LED so das ich 24-LED's ansteuern könnte. Wie kann ich denn nun jetzt, angenommen die Pins wären von 1 bis 24 durchnummeriert Pin5 ansteuern , wenn bereits pin10 und Pin 20 angesteuert sind? Muss ich jedesmal die Pin10 und Pin20 erneut mit ansteuern? Entschuldigt meine blöde Frage, Schieberegister sind was einfaches aber ich weiß nicht ob es eventuell einen C-Code-Trick gibt um nicht jedesmal das komplette Bitmuster durchzusenden. Ich frage daher weil die LED's per Zufallgenerator eingeschaltet werden sollen. Viele Grüße Rudi
Achso, ich verwende einen ATmega 8L was ich samt Eval-Board von Pollin gekauft habe
Rudi_T schrieb: > Entschuldigt meine blöde Frage, Schieberegister sind was einfaches aber > ich weiß nicht ob es eventuell einen C-Code-Trick gibt um nicht jedesmal > das komplette Bitmuster durchzusenden. Mit Ausnahme der einen Sonderfalles, in dem man ein Muster durch das Schiebregister durchtaktet und nach jedem Schritt anzeigt (also ein Lauflicht macht), gibt es keinen Trick. Man taktet jedesmal alle Bits raus. Mach dir also im Speicher ein Array von Bytes, welches deine Ausgänge repräsentiert und in dem du deine Änderungen in Form von Bits setzen bzw. Bit löschen durchführst. Sind alle Änderungen gemacht, dann werden alle Bytes in einem Aufwasch erneut ans SR ausgegeben und angezeigt. Hört sich jetzt schlimmer an als es ist.
Rudi_T schrieb: > Entschuldigt meine blöde Frage, Schieberegister sind was einfaches aber > ich weiß nicht ob es eventuell einen C-Code-Trick gibt um nicht jedesmal > das komplette Bitmuster durchzusenden. Das hat nichts mit C zu tun - die Hardware erfordert das komplette durchschieben. Denn jeder Schiebetakt schiebt alle Bits eins weiter. Gruß Dietrich
Hi Karl, aber wie mach ich das mit der Zufallsschaltung. Die Funktion gibt jetzt LED5 aus. Gut dann gebe ich das Bitmuster für LED5 vor und schalte es. Im zweiten Durchlauf sagt die Funktion LED 11 -> Ich gebe das Bitmuster von LED11 vor und sende es ab aber LED5 ist dann aus. Ich muss also vorher irgendwie herausfinden welche LED's bereits gesetzt sind damit die bei der Zuschaltung einer LED nicht wieder ausgehen. oder? Viele Grüße Rudi
Rudi_T schrieb: > Ich muss also vorher irgendwie herausfinden welche LED's bereits gesetzt > sind damit die bei der Zuschaltung einer LED nicht wieder ausgehen. Genau. Deshalb sollst du: Karl Heinz Buchegger schrieb: > Mach dir also im Speicher ein Array von Bytes, welches deine Ausgänge > repräsentiert und in dem du deine Änderungen in Form von Bits setzen > bzw. Bit löschen durchführst. Sind alle Änderungen gemacht, dann werden > alle Bytes in einem Aufwasch erneut ans SR ausgegeben und angezeigt. Macht für 24 LEDs ein Array aus drei Bytes. darin setzt du zufällig ein Bit und taktest das Array raus. Setzt das nächste Bit ohne Löschen des bisherigen Inhalts und taktest raus etc. Ohne eine Repräsentation des Bildes im Speicher wird das nichts. Naja, du könntest den Ausgang des SR auf eine Eingang des Controllers zurückführen und dann beim Durchschleifen Bits verändern. Ist aber anfälliger, da sich Fehler akkumulieren können und bringt keinen Vorteil für drei Byte.
Bequemer wäre doch eigentlich ein I2C I/O Expander sehe ich gerade, der hat 16 Ausgänge und kostet 1€. Der hat auch einen Interrupt Ausgang. Texas TCA9539
hmm...
1 | static uint8_t image[3]; |
2 | |
3 | ...
|
4 | |
5 | |
6 | void update_leds(void) { |
7 | int i; |
8 | PORTx &= ~(1 << LATCH_PIN); |
9 | for (i = 0; i < 3; ++i) { |
10 | SPDR = image[i]; |
11 | loop_until_bit_is_set(SPSR, SPIF); |
12 | }
|
13 | PORTx |= 1 << LATCH_PIN; |
14 | }
|
15 | |
16 | void set_led(uint8_t led) { |
17 | image[led >> 3] |= 1 << (led & 0x7); |
18 | }
|
So ungefähr, ungetestet. Wo ist das kompliziert? Das mit dem variablen Left-Shift in set_led() ist für den AVR keine leichte Kost, also wenn du irgend eine Möglichkeit hast, das zu umgehen, nutze sie. Gibt es je nach Anwendungsfall zuhauf.
Malte S. schrieb: > Das mit dem variablen Left-Shift in set_led() ist für den AVR keine > leichte Kost, Im allgemeinen Fall: ja - sollte man umgehen. In diesem speziellen Fall wird das kaum eine Rolle spielen, es sei denn er will innerhalb 1 Sekunden 1000 Leds zufällig ein und ausschalten. :-)
Der GPIO Expander hat den Vorteil das du einen Interrupt bekommst wenn ein Ein/Ausgang sich ändern sollte, das hat man beim Schieberegister nicht. Sodurch könnte man CPU Zeit sparen.
IO-Expander sind bei der Fragestellung nach dem richtigem Schieben etwas fehl am Platz. Interrupts brauchts für solch eine Anwendung garantiert nicht. Zu was auch?
spontan schrieb: > IO-Expander sind bei der Fragestellung nach dem richtigem Schieben etwas > fehl am Platz. I/O Expander sind vom TO selber mit ins Spiel gekommen, weil er sich davor fürchtet, 24 Bits gezielt auf 3 Bytes aufzuteilen und er dazu ein bisschen rechnen muss. Das er dann erst mal eine I2C Lib braucht, schien ihn hingegen nicht zu stören :-)
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.