Hallo, ich habe mir eine LED-Matrix gebaut. 6*8 LED. An Port B0-7 (Mega8)hängen über einen Widerstand von 330 Ohm die Anoden der LED's. Die Kathodenstränge werden über 6 BC547B nach Minus geschaltet. Die Transistoren werden über einen 4,7kOhm Widerstand über Port D0-5 angesteuert. Die Schaltung funktioniert soweit. Das Multiplexen passiert in einer timergesteuerten Interruptroutine. Allerding habe ich Übersprechen dh. es leuchten LED's ganz schwach mit. Und zwar im Muster der am Port B ausgegeben Daten. Da es sich um sehr empfindliche, helle, weisse LED's handelt, fällt es doch etwas auf (Trotz des hohen Widerstandes von 330 Ohm). Ein Kondensator (100nF) direkt an die betreffenden LED's gelötet, schafft Abhilfe. Aber das kann doch nicht die Lösung sein ? Gruß Günter
Das ist Programmgesteuert. überlege mal wie und wann Du die Ausgänge schaltest.
Ich denke nicht. ISR { Ich schalte zuerst Port B auf 0. x Wechsele dann auf den nächsten Strang (Inhalt von Port D*2)und x gebe dann das nächste Bitmuster auf Port B aus. Beim nächsten Aufruf ist das nächste Muster dran. } Ich habe an den Stellen mit "x" auch schon ein Delay eingebaut. Die Leiterbahnzwischenräume saubergekratzt (Streifenraster). Und den Transistoren einen Widerstand von 2,2 kOhm nach Masse verpasst. Es ist ja auch nicht bei allen LED gleich stark.
Hier die ISR: Hatte übrigens in meinem Anfangsposting Port B und Port D vertauscht.
1 | ISR (TIMER0_OVF_vect) |
2 | {
|
3 | PORTD= 0; |
4 | //_delay_us(100);
|
5 | PORTB= SegCount; //1.Reihe an |
6 | //_delay_us(100);
|
7 | PORTD= a[ByteCount]; //1.Byte Laden |
8 | if (SegCount<32) |
9 | {SegCount=SegCount*2;} |
10 | else
|
11 | {SegCount=1;} |
12 | if (ByteCount<5) |
13 | {ByteCount=ByteCount+1;} |
14 | else
|
15 | {ByteCount=0;} |
16 | }
|
Die jeweiligen 6 auszugebenen ByteWerte befinden sich in der Feldvariablen a[0-5]. Takt: 8Mhz ISR-Takt 8Mhz/256 Den Variablen a[0-5] werden im Laufe des Programms verschiedene Werte zugeordnet. zB main { a[0]++; oder ähnlich loop; } Oder sollte man die Schaltung besser umgekehrt mit PNP-Transistoren aufbauen und Port D nicht 1 für "LED an" sondern 0 für "LED an" schalten ?
Guenter B. schrieb: > Allerding habe ich Übersprechen dh. es leuchten LED's ganz schwach mit. Das ist in 99,99% aller Fälle ein Programmierfehler.
Guenter B. schrieb: > Hier die ISR: > Hatte übrigens in meinem Anfangsposting Port B und Port D vertauscht. > >
1 | > ISR (TIMER0_OVF_vect) |
2 | > { |
3 | > PORTD= 0; |
4 | > //_delay_us(100); |
5 | > PORTB= SegCount; //1.Reihe an |
6 | > //_delay_us(100); |
7 | > PORTD= a[ByteCount]; //1.Byte Laden |
8 | > if (SegCount<32) |
9 | > {SegCount=SegCount*2;} |
10 | > else |
11 | > {SegCount=1;} |
12 | > if (ByteCount<5) |
13 | > {ByteCount=ByteCount+1;} |
14 | > else |
15 | > {ByteCount=0;} |
16 | > } |
17 | >
|
>
Was unschön ist:
Du erhöhst im selben Durchlauf ByteCount und SegCount. Hier hast Du
Glück, dass beide Variablen verschiedene Wertebereiche haben.
Wenn der Wertebereich aber gleichgroß wird überspringt deine ISR den
Großteil der 'Pixel'.
Stell es am Besten so um, dass du nur dann die Zeile änderst, wenn du
alle Spalten einmal durchlaufen hast.
Guenter B. schrieb: > ISR-Takt 8Mhz/256 > _delay_us(100); Negative Zeitachse oder? Ich hätte auch immer gern 200us Zeit wenn nur 32us zur Verfügung stehen. Ich würde die Multiplex-Frequenz auf ca 100 Hz für einen Durchlauf setzen (also ca 600 Hz für die Interrupt-Routine). Dann klappts auch mit 100us delay. Brauchen wirst Du ca 5us für die Transistoren. Gruß Anja
Ich wüds so umbauen
1 | ISR (TIMER0_OVF_vect) |
2 | {
|
3 | PORTD = 0; |
4 | PORTB = 0; |
5 | |
6 | SegCount = SegCount << 1; |
7 | if (SegCount == 0b01000000) |
8 | SegCount = 1; |
9 | |
10 | ByteCount++; |
11 | if (ByteCount > 5) |
12 | ByteCount = 0; |
13 | |
14 | PORTB = SegCount; |
15 | PORTD = a[ByteCount]; |
16 | }
|
Das verschafft dir nach dem Ausschalten der LED und vor dem Einschalten der nächsten Spalte etwas Zeit, so dass sich eventuelle externe Kapazitäten entladen können und die Transistoren sicher abgeschaltet haben. PORTB und PORTD sind sicher auf Ausgang geschaltet?
Vergiss bitte, was ich geschrieben habe, ich hab' zwei große Denkfehler gehabt. Wenn es so dagestanden hätte, hätte ich es etwas besser verstanden:
1 | ISR (TIMER0_OVF_vect) |
2 | {
|
3 | PORTD= 0; |
4 | //_delay_us(100);
|
5 | PORTB= SegCount; //1.Reihe an |
6 | //_delay_us(100);
|
7 | PORTD= a[ByteCount]; //1.Byte Laden |
8 | if (ByteCount<5) { |
9 | ByteCount=ByteCount+1; |
10 | SegCount=SegCount*2; |
11 | } else { |
12 | ByteCount=0; |
13 | SegCount=1; |
14 | }
|
15 | }
|
;-)
@captain subtext Ich muss doch das entsprechende Bitmuster (Bytecount)ausgeben und die entsprechende Spalte (Segcount) auswaehlen. Im Prinzip arbeiten hier zwei Zaehler fuer dieselbe Sache: 1,2,4,8,16,32 fuer die Spalte und O,1,2,3,4,5 als Index fuer Feldvariable mit dem entsprechenden Bitmuster. @Anja Die 100us waren nur testweise drin. Ausserdem bin ich bei meinem Halbwissen davon ausgegangen, dass innerhalb einer ISR Interrupts gesperrt sind und ich somit mehr Zeit habe. Gruß Gbl
gbl schrieb: > Ich muss doch das entsprechende Bitmuster (Bytecount)ausgeben und die > entsprechende Spalte (Segcount) auswaehlen. Im Prinzip arbeiten hier > zwei Zaehler fuer dieselbe Sache: > 1,2,4,8,16,32 fuer die Spalte und > O,1,2,3,4,5 als Index fuer Feldvariable mit dem entsprechenden > Bitmuster. Das habe ich im zweiten Anlauf ja auch begriffen. ;-) Es wäre für Andere übersichtlicher, derart abhängige Variablen gemeinsam zu bearbeiten. Siehe dazu meinen zweiten Post.
@captain subtext Da hatten sich wohl unsere Postings überschnitten. Ich hatte deinen Beitrag erst gesehen, als ich meinen abgesandt hatte. Aber du hast recht: Man könnte das Ganze etwas übersichtlicher lösen. @Karl Heinz Buchegger D=0 B=0 Werde ich heute Abend ausprobieren. Zu den Ports: Ich meine schon die Ports auf Ausgang geschaltet zu haben. Ansonsten würde es doch gar nicht funktionieren oder ? Werde es aber auch jeden Fall kontrollieren. Gruß gbl
Guenter B. schrieb: > Zu den Ports: > Ich meine schon die Ports auf Ausgang geschaltet zu haben. > Ansonsten würde es doch gar nicht funktionieren oder ? Doch, eventuell schon. Wenn die Ports auf Eingang geschaltet sind, dann schaltest Du nur die internen Pull-Ups ein (was ein HIGH über den Pull-Up am Ausgang ergibt) oder aus (was die Ausgänge hochohmig macht). Mit einem npn-Transistor am Ausgang kann das funktionieren, der Transistor ist dann aber langsamer.
Was noch interessant ist: Wenn du die Transistoren in Emitterschaltung betreibst, haben die nach Sättigung eine ziemlich lange Speicherzeit. Poste doch mal die Schaltung. Wie gross ist der Basisstrom, die Stromverstärung und der Kollektorstrom? Abhilfe würde hier ein Verkleinern des Basisstromes, oder das Umstellen auf Kollektorschaltung helfen.
@ Karl Heinz Buchegger Habe die Routine mal eingbaut: Keine Veränderung. Auch nicht wenn ich nach B=0 D=0 ein _delay_us(5) oder (20) ausgebe. @edi DDRB = 0xFF; DDRD = 0xFF; hatte ich gesetzt @Matthias Lipinsky Die Transistoren werden über 4,7 kOhm angesteuert. IB=(5-0,7)/4700=0,91mA IC=(5-2-0,1)/330=8,8 mA Verstärkung ca 250 (laut HFE-Messbuchse am DMM) I gesamt (Alle LED's an) -> ca 90mA Gruß gbl
Jetzt mal Butter bei den Fischen. Exakten Schaltplan Exaktes Programm Wie sieh der Aufbau aus? Steckplatine, Lochraster, geätzte Schaltung? Wenn geht: Photo
Matthias Lipinsky schrieb: > Poste doch mal die Schaltung. Wie gross ist der Basisstrom, die > Stromverstärung und der Kollektorstrom? Und gleich noch ein Oszillogramm vom Strom zweier benachbarter Reihen beim Umschalten der Transistoren...
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.