Forum: Mikrocontroller und Digitale Elektronik Schiebe Register Kaskade , Ausgang ansteuern


von Rudi_T (Gast)


Lesenswert?

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

von Rudi_T (Gast)


Lesenswert?

Achso, ich verwende einen ATmega 8L was ich samt Eval-Board von Pollin 
gekauft habe

von Karl H. (kbuchegg)


Lesenswert?

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.

von Dietrich L. (dietrichl)


Lesenswert?

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

von Rudi_T (Gast)


Lesenswert?

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

von Malte S. (maltest)


Lesenswert?

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.

von Rudi_T (Gast)


Lesenswert?

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

von Malte S. (maltest)


Lesenswert?

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.

von Karl H. (kbuchegg)


Lesenswert?

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. :-)

von Ersi (cell85)


Lesenswert?

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.

von spontan (Gast)


Lesenswert?

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?

von Karl H. (kbuchegg)


Lesenswert?

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