Hallo Zusammen. Ich wollte mich mal bei euch informieren, wie ihr das so machen würdet: Ich habe einen Attiny13 in Kombination mit einem CD4067BE Schieberegister. Die Datenleitungen entsprechen der Portbelegung, das heisst: PB0 (Attiny) auf Input A (Shift Register) PB1 (Attiny) auf Input B (Shift Register) PB2 (Attiny) auf Input C (Shift Register) PB3 (Attiny) auf Input D (Shift Register) Die Ausgänge des Shiftregisters (16) sind einfach nur LED's. Nun funktioniert das ganze ganz in Ordnung, wenn ich schreibe PORTB = 0x01; leuchtet LED 1, bei PORTB = 0x02; LED 2 und so weiter. Nun, wenn ich mehrere LED's leuchten lassen will, muss ich ja abwechselnd while (irgendwas) { PORTB = 0x01; //irgend ein Delay PORTB = 0x00; PORTB = 0x02; //irgend ein Delay PORTB = 0x00; } Leider habe ich nach längerem rumprobieren keine gescheite Routine hingekriegt, gibt es da evtl. Musterlösungen wo man ein wenig abkucken könnte? Gruss & Danke im Voraus
Hi >Ich habe einen Attiny13 in Kombination mit einem CD4067BE >Schieberegister. Der CD4067 ist ein Multiplexer/Demultiplexer, kein Schieberegister. MfG Spess
Electronics'nStuff schrieb: > Die Datenleitungen entsprechen der Portbelegung, das heisst: > > PB0 (Attiny) auf Input A (Shift Register) > PB1 (Attiny) auf Input B (Shift Register) > PB2 (Attiny) auf Input C (Shift Register) > PB3 (Attiny) auf Input D (Shift Register) > > Die Ausgänge des Shiftregisters (16) sind einfach nur LED's. Gibts diese Netzliste als auch Bild (aka. Schaltplan)?
Electronics'nStuff schrieb: > Leider habe ich nach längerem rumprobieren keine gescheite Routine > hingekriegt, Das Zauberwort heißt, wie eigentlich in über 70% aller Fälle: Timer Es ist im Grunde immer das gleiche Prinzip. Wenn irgendwo eine Zeitsteuerung im Spiel ist, dann erledigt das die ISR eines Timers.
spess53 schrieb: > Der CD4067 ist ein Multiplexer/Demultiplexer, kein Schieberegister. Oh, shit mein Fehler. Natürlich, war ja eig. auch die Idee hinter dem Bauteil :) Lothar Miller schrieb: > Gibts diese Netzliste als auch Bild (aka. Schaltplan)? Ja, klar. Befindet sich im Anhang. Gruss
Electronics'nStuff schrieb: > spess53 schrieb: >> Der CD4067 ist ein Multiplexer/Demultiplexer, kein Schieberegister. > > Oh, shit mein Fehler. Natürlich, war ja eig. auch die Idee hinter dem > Bauteil :) War eine schlechte Idee. Mit Schieberegistern wärst du besser gefahren.
Karl Heinz Buchegger schrieb: > Das Zauberwort heißt, wie eigentlich in über 70% aller Fälle: Timer Ja, aber in die ISR muss auch noch eine Routine, und die würde mich eben interessieren wie so was im Besten Fall aussieht. Klar, kriege ich irgendwas hin aber das ist bis jetzt immer ein bisschen vermurkst rausgekommen und ich hatte jedes Mal das Gefühl, das geht bestimmt einfacher. Gruss
Karl Heinz Buchegger schrieb: > Mit Schieberegistern wärst du besser gefahren. Hätte ich genommen, wenn ich ein 16-Kanal Schieberegister gefunden hätte. War aus Platz- und Layoutgründen (-> 1Lagig) die bessere Alternative für mich. Aber die Schaltung ist jetzt schon umgesetzt, geroutet und geätzt :) Also würde ich gerne mit den Bauteilen arbeiten, die jetzt auf meiner kleinen Platine werkeln. Gruss
Electronics'nStuff schrieb: > Karl Heinz Buchegger schrieb: >> Das Zauberwort heißt, wie eigentlich in über 70% aller Fälle: Timer > > Ja, aber in die ISR muss auch noch eine Routine In der ISR wird abwechselnd (um bei deinem Beispiel zu bleiben) 0x01 auf den Port ausgegeben und 0x02. Bei jedem ISR Aufruf die jeweils andere 'Stelle' (wenn du 2 Stellen hast. Bei zb 4 dann eben nacheinander alle 4 durchgehen. Bei jedem Aufruf kommt die jeweils nächste Stelle.) Das wirst du ja wohl noch hinkriegen :-)
1 | uint8_t welche; |
2 | |
3 | ISR( ... ) |
4 | {
|
5 | if( welche == 0 ) |
6 | PORTB = 0x01; |
7 | else
|
8 | PORTB = 0x02; |
9 | |
10 | welche = 1 - welche; |
11 | }
|
That's it. Das ist schon alles. So, und jetzt auf und sich mit Timern vertraut machen FAQ: Timer Bei dir ist das jetzt natürlich blöd, weil du 16 'Stellen' hast. D.h. jede LED (so sie eingeschaltet ist) leuchtet nur 1/16 der Zeit. D.h. das wird ziemlich dunkel werden.
Ok, ich sehe ich bin ein wenig zu unpräzise. Das ganze soll nachher unterschiedlich funktionieren. Am liebsten hätte ich eine Funktion wie z.b. light (3, 16) Wobei die 3 für die Anzahl LED's steht und die 16 für die Zeit (in ms z.B.) Weisst du wie ich es meine? Danke für den Hinweis mit dem aber ich habe dieses Tutorial schon durch sowie erfolgreich eine Uhr gebaut, mit PWM gearbeitet etc. Einen Interrupt alle 10ms (z.B.) zu erzeugen ist für mich kein Problem aber eine gescheite Routine habe ich nicht gefunden bis jetzt. Gruss
Karl Heinz Buchegger schrieb: > leuchtet nur 1/16 der Zeit. Ja, das ist schon ok :) Soll auch eine Low-Current Anwendung werden. Gruss
Electronics'nStuff schrieb: > Karl Heinz Buchegger schrieb: >> Mit Schieberegistern wärst du besser gefahren. > > Hätte ich genommen, wenn ich ein 16-Kanal Schieberegister gefunden > hätte. Das coole an Schieberegistern wie zb einem 595 ist, dass man sie trivial kaskadieren kann. Braucht man 16 Pins, dann schaltet man einfach 2 Stück 8 Bit Schieberegister hintereinander. Softwaremässig ist das immer noch ein 16-Bit Schieberegister. Die Software kriegt davon nichts mit, dass da eigentlich 2 IC an der Arbeit sind. AVR-Tutorial Im Abschnitt über Schieberegister. > Aber die Schaltung ist jetzt schon umgesetzt, geroutet und geätzt :) > Also würde ich gerne mit den Bauteilen arbeiten, die jetzt auf meiner > kleinen Platine werkeln. Tja. Das Problem wird werden, dass du mit deiner Lösung nicht viel Freude haben wirst. Ein 1:16 Multiplex ist schon hart an der Grenze, bzw. eigentlich drüber.
Electronics'nStuff schrieb: > Weisst du wie ich es meine? Nein. Was soll das ganze überhaupt werden.
Karl Heinz Buchegger schrieb: > Das coole an Schieberegistern wie zb einem 595 ist, dass man sie trivial > kaskadieren kann. Ach, das wusste ich nicht.. dachte da steckt mehr Aufwand dahinter. Danke für den Hinweis auf den Artikel, den werde ich mir als Lesezeichen speicher, wenn ich das nächste mal Schieberegister benutze. Aber trotzdem, das Problem mit dem Platz bleibt, ein 595 ist SO-16, zwei davon wären demnach 32 Pins, ich brauche so nur 24. Gruss
Karl Heinz Buchegger schrieb: > Was soll das ganze überhaupt werden. Ne kleine Unterbodenbeleuchtung für Gläser. Es sollen verschiedene Muster einprogrammiert werden, die danach in einer Endlosschlaufe vor sich hin leuchten. Also ich probier mich mal geschickter auszudrücken: Ich möchte eine Funktion, in die ich eingeben kann led(3) und dann leuchtet led 1-3. Wenn ich eingebe led(4) leuchtet led 1-4. Natürlich soll das Ganze immer gleich hell bleiben, d.h. eine led leuchtet immer mit 1/16 der leuchtkraft, unabhängig davon, ob andere LED's eigeschaltet wruden. Gruss
Electronics'nStuff schrieb: > Ich möchte eine Funktion, in die ich eingeben kann led(3) und dann > leuchtet led 1-3. Wenn ich eingebe led(4) leuchtet led 1-4. > > Natürlich soll das Ganze immer gleich hell bleiben, d.h. eine led > leuchtet immer mit 1/16 der leuchtkraft, unabhängig davon, ob andere > LED's eigeschaltet wruden. Wenn ich deine Schaltung studiere, dann geht das gar nicht. Und zwar deshalb nicht, weil du gar keine Möglichkeit hast, KEINE Led leuchten zu lassen. So wird das nichts mit einem Multiplex. Also: so wird das nichts. Sorry. Entweder du lebst damit, dass du immer nur 1 LED einschalten kannst, oder du baust deine Schaltung um. (Im einfachsten Fall: auf eine LED verzichten, die immer dann 'eingeschaltet' wird, wenn im Multiplex eine LED nicht leuchten soll)
Karl Heinz Buchegger schrieb: > oder du baust deine Schaltung um. Ich hänge X auf PB5 :) Der Fall in dem keine LED leuchtet, kommt sowieso nie bis fast nie vor. Oder ist zumindest nicht vorgesehen. Ich will auch nicht das 100ste Schieberegister an den 100ten Attiny mit dem 100-fach benutzten Code benutzen (auch wenn sich diese Lösung bewährt hat). Gruss
> Ich möchte eine Funktion, in die ich eingeben kann led(3) und > dann leuchtet led 1-3. Wenn ich eingebe led(4) leuchtet led 1-4. Ja, das kannst du dann ja immer noch drüber bauen. Aber erst mal muss der Multiplex laufen. Den brauchst du um mehrere LED gleichzeitig leuchten alssen zu können. Und zwar unabhängig davon, welche LED dann tatsächlich leuchten sollen > (Im einfachsten Fall: auf eine LED verzichten, die immer dann > 'eingeschaltet' wird, wenn im Multiplex eine LED nicht leuchten soll) Ich geh mal davon aus, dass du auf LED-16 verzichtest
1 | volatile uint8_t LedOn[15]; |
2 | uint8_t multiplexCnt; |
3 | |
4 | ISR( ... ) |
5 | {
|
6 | multiplexCnt++; |
7 | if( multiplexCnt == 15 ) |
8 | multiplexCnt = 0; |
9 | |
10 | if( LedOn[multiplexCnt] ) |
11 | PORTB = multiplexCnt; |
12 | else
|
13 | PORTB = 15; |
14 | }
|
Und darüber kannst du jetzt Funktionen legen, die dir im Array LedOn eine 0 oder eine 1 einschreiben, je nachdem welche LED leuchten sollen.
Electronics'nStuff schrieb: > Karl Heinz Buchegger schrieb: >> oder du baust deine Schaltung um. > > Ich hänge X auf PB5 :) Keine gute Idee. Nicht böse sein, aber bei deinen Programmierkünsten, solltest du dir Reset nicht wegfusen. Da kannst du 15 Prozessoren auch gleich so beim Fenster rauswerfen. > Der Fall in dem keine LED leuchtet, kommt sowieso nie bis fast nie vor. Du hast Multiplex nicht verstanden. Der kommt vor! Ungefähr 700 mal in der Sekunde! Bei jeder LED stellt sich die Frage: Leuchten oder nicht Leuchten. Leuchten ist einfach, du gibst ihr Muster an den Demux aus. Aber wie realisierst du 'nicht leuchten'? Im Zeitslot dieser LED muss irgendwas am Demux passieren, so dass dann diese LED (und zu diesem Zeitpunkt auch keine andere) eben nicht leuchtet.
Karl Heinz Buchegger schrieb: > volatile uint8_t LedOn[15]; > uint8_t multiplexCnt; > > ISR( ... ) > { > multiplexCnt++; > if( multiplexCnt == 15 ) > multiplexCnt = 0; > > if( LedOn[multiplexCnt] ) > PORTB = multiplexCnt; > else > PORTB = 15; > } Hm, verstehe ich das richtig, dass jetzt immer alle LEDs leuchten? Weil if (LedOn[multiplexCnt]) ist doch immer wahr (ausser wenn multiplexCNnt = 0)?
Karl Heinz Buchegger schrieb: > Du hast Multiplex nicht verstanden. > Der kommt vor! > Ungefähr 700 mal in der Sekunde! > > Bei jeder LED stellt sich die Frage: Leuchten oder nicht Leuchten. > Leuchten ist einfach, du gibst ihr Muster an den Demux aus. Aber wie > realisierst du 'nicht leuchten'? Im Zeitslot dieser LED muss irgendwas > am Demux passieren, so dass dann diese LED (und zu diesem Zeitpunkt auch > keine andere) eben nicht leuchtet. OH, jetzt habe ich verstanden. Ich war mir nicht ganz im Klaren, was PORTB = 0x00 in meiner Schaltung auslöst. Dann nehme ich die LED raus, das ist wirklch die einzige gescheite Alternative.
Electronics'nStuff schrieb: > Karl Heinz Buchegger schrieb: >> volatile uint8_t LedOn[15]; >> uint8_t multiplexCnt; >> >> ISR( ... ) >> { >> multiplexCnt++; >> if( multiplexCnt == 15 ) >> multiplexCnt = 0; >> >> if( LedOn[multiplexCnt] ) >> PORTB = multiplexCnt; >> else >> PORTB = 15; >> } > > Hm, verstehe ich das richtig, dass jetzt immer alle LEDs leuchten? Nein, das verstehst du falsch. > Weil if (LedOn[multiplexCnt]) ist doch immer wahr (ausser wenn > multiplexCNnt = 0)? Ähm. Da gibt es ein Array. Das nennt sich LedOn Hier ist es LedOn +---+---+---+---+---+---+---+---+-... | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | +---+---+---+---+---+---+---+---+-... Und dann gibt es einen Zähler multiplexCnt. Der nimmt nacheinander alle Werte von 0 bis 14 an. Wenn also multiplexCnt gerade den Wert 0 hat, was steht im Array an der Indexposition 0 (weil LedOn[multiplexCnt]). Da steht eine 0. Und 0 ist für das if ein logisches FALSE. d.h. in dem Fall wird dann auf den Demux eine 15 ausgegeben. D.h. Led-1 leuchtet nicht. (wohl aber würde LED-16 leuchten, da die aber physisch nicht vorhanden ist, leuchtet gar keine LED) Kurze Zeit später wird die ISR wieder aufgerufen. multiplexCnt hat dann den Wert 1. Was steht im Array an der Index-Position 1? Da steht eine 1 drinnen. 1 ist für das if ein logisches TRUE. Also wird der then Zweig genommen und die 1 an den Demux gegegeben. d.h. die LED-2 wird eingeschaltet und leuchtet. Wieder kurze Zeit später wird die ISR das nächste mal aufgerufen. multiplexCnt hat denn den Wert 2. Was steht im Array an der Index-Position 2? Da steht eine 0. 0 ist für das if ein logisches FALSE (soll also heissen: die zugehörige LED soll nicht leuchten). Ergo wird wieder das else genommen und der Demux auf 15 gestellt. 15 heisst, dass LED-3 (und auch keine andere LED) nicht leuchtet. usw. usw. und so geht das immer reihum, mindestens 100 komplette Zyklen in der Sekunde (ansonsten flackert die ganze Sache). Zu jedem beliebigen Zeitpunkt leuchtet genau und nur eine einzige Led oder eben gar keine. Aber: die Zeiten sind so kurz und dein Auge ist so träge, dass du nicht mitkriegst, das das so ist. Für dich leuchten die jeweils eingeschalteten LED alle gleichzeitig. Wie beim Kino. Du siehst in Wirklichkeit auch nur Standbilder. Da das aber viele in der Sekunde sind und du jedes Bild nur ganz kurz siehst, siehst du keine Einzelbilder mehr sondern einen bewegten Film.
Tja, komischer Ansatz. Ich verstehe auch nicht, warum so ein kleiner Controller und dann wieder ne I/O-Erweiterung dran (noch dazu ne ganz schlechte wie in diesem Fall)? Machs neu und nimm gleich nen Mega8 (oder 48/88), für jede LED nen Port. Man muss auch los lassen können :-)
Karl Heinz Buchegger schrieb: > LedOn > +---+---+---+---+---+---+---+---+-... > | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | > +---+---+---+---+---+---+---+---+-... Oh man, was steh ich auch auf dem Schlauch. Danke für deine schöne ausführliche Erklärung, aber diese Zeichnung hätte schon genügt um meine Verwirrung zu vernichten :) Danke für eure Bemühungen!
Der CD4067BE ist kein großer Stromtreiber, d.h. bei 1:16 Multiplex wirst du die LEDs kaum noch sehen. 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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.