Hallo, ich bin gerade an der Umsetzung einer 5x5 LED-Matrix. Dazu habe ich die Spalten per BC548 Transistor an 5V verbunden. Die Basen der 5 npn habe ich mit dem PORTD eines Atmega8 verbunden. Die Zeilen habe ich nun über je einen 82 Ohm Widerstand am PORTC des selbigen AVRs angeschlossen. Die LEDs (3,2V , 20mA) kann ich statisch alle samt ansteuern (einzeln), indem ich eben den jeweiligen Spaltentransistor durchschalte, und die Zeilen so maskiere, dass an den LEDs die leuchten sollen Masse liegt (logische 0). Sobald ich nun aber 2 LEDs abwechselnd leuchten lasse, also multiplexe, leuchten 2-3 LEDs ganz schwach mit. Ich habe die komplette Verschaltung noch mal überprüft und auch fremdkontrollieren lassen. Ich stehe nun vor dem Problem, dass ich warscheinlich eine tückische Sache übersehe. Auch hab ich die Leckströme der abgeschaltenen LEDs in betracht gezogen, aber kann das der Grund sein? Vielen Dank vorab für eure Hilfe Marcel P.
Erstmal ist dein Widerstand viel zu groß. In einer 5x5- Matrix leuchten von den 25 LEDs maximal 5 gleichzeitig, für 1/5 der Zeit. D.h. die LED muß mit dem fünffachen Strom geschaltet werden. Dafür dürfte der Atmega-Port aber ein wenig zu schlapp sein. Also auch Masse über einen Treiber. ULN2003 z.B. mfg.
Das kann an der Reihenfolge deiner Aktionen liegen. Bevor man ein neue Spalte einschaltet muss die zuletzt eingeschaltete Spalte erst mal ausgeschaltet werden. Dann erst die Zeilen ändern und die neue Spalte einschalten.
holger schrieb: > Das kann an der Reihenfolge deiner Aktionen liegen. > > Bevor man ein neue Spalte einschaltet muss die > > zuletzt eingeschaltete Spalte erst mal ausgeschaltet > > werden. Dann erst die Zeilen ändern und die neue > > Spalte einschalten. Genau! Hab ich noch vergessen. mfg.
Okay, das dachte ich mir schon, nur sind die LEDs sowieso zu grell für die meine Bedürftnisse. Aber daran sollte es eigentlich ja auch nicht liegen, dass andere LEDs mitleuchten, oder doch?!
Auch das mit der Reihenfolge habe ich bedacht. Ich setzte vor jeder Änderung der Zeilenmasken alle Spalten auf 0. Außerdem würden dann die falschen LEDs doch genauso hell leuchten oder nicht? Sind ja dann auch einen Taktzyklus lang an.
Marcel P. schrieb: > Auch das mit der Reihenfolge habe ich bedacht. Ich setzte vor jeder > > Änderung der Zeilenmasken alle Spalten auf 0. Außerdem würden dann die > > falschen LEDs doch genauso hell leuchten oder nicht? Sind ja dann auch > > einen Taktzyklus lang an. Da muß noch eine kleine "Schutzzeit" rein. Wenn Du PortD auf 0 setzt, wird das Portregister auf 0 gesetzt und dann schaltet der Port. Das dauert eben auch ein wenig. Setz' da ein paar NOPs zwischen und mache das Umschalten nicht mit vollem Takt, sondern wesentlich langsamer, z.B 1000x in der Sekunde. mfg.
Hallo nochmal, ich habe nun die Pausen eingefügt, dennoch zeigt die Matrix scheinbar zufällige Leuchtbilder. Dabei leuchtet bei folgender Einstellung eine LED am hellsten, 2 weitere leuchten schwach mit.
1 | PORTC = 0; |
2 | PORTD = 1; |
3 | _delay_loop_1(4); |
4 | PORTD = 0; |
5 | _delay_loop_1(4); |
6 | |
7 | PORTC = 0; |
8 | PORTD = 2; |
9 | _delay_loop_1(4); |
10 | PORTD = 0; |
11 | _delay_loop_1(4); |
12 | |
13 | PORTC = 0; |
14 | PORTD = 4; |
15 | _delay_loop_1(4); |
16 | PORTD = 0; |
17 | _delay_loop_1(4); |
18 | |
19 | PORTC = 0b00000001; |
20 | PORTD = 8; |
21 | _delay_loop_1(4); |
22 | PORTD = 0; |
23 | _delay_loop_1(4); |
24 | |
25 | PORTC = 0; |
26 | PORTD = 16; |
27 | _delay_loop_1(4); |
28 | PORTD = 0; |
29 | _delay_loop_1(4); |
Im Vergleich zu vorher habe ich nun lediglich in die Masseleitungen je einen BC548 eingefügt und zur "erhöhten" Lichtausbeute einen zusätzlichen Widerstand parallel zum alten mit ebenfalls 82 Ohm gelötet. Ist in diesem Abschnitt das Problem mit den Pausen soweit richtig umgesetzt? Vielen Dank soweit für die bisherige Hilfe =) Marcel P.
Was soll der Quatsch mit den Delayloops. Nimm _delay_ms(1), damit man auch weiß, wie groß die Delays sind. Ich vermute mal Deine Delays sind viel zu kurz, 1kHz reicht dicke. Beim Emitterfolger brauchst Du auch keine zusätzlichen Delays, der ist schnell genug.
1 | PORTD = 0; // aus |
2 | PORTC = BITMUSTER0; // neues Bitmuster |
3 | PORTD = 1<<0; // an |
4 | _delay_ms( 1 ); // 1kHz |
5 | |
6 | PORTD = 0; // aus |
7 | PORTC = BITMUSTER1; // neues Bitmuster |
8 | PORTD = 1<<1; // an |
9 | _delay_ms( 1 ); // 1kHz |
10 | |
11 | PORTD = 0; // aus |
12 | PORTC = BITMUSTER2; // neues Bitmuster |
13 | PORTD = 1<<2; // an |
14 | _delay_ms( 1 ); // 1kHz |
15 | |
16 | // usw.
|
Peter
PORTC = 0; PORTD = 1; //Spalte 1 an _delay_loop_1(40); PORTC = 0; PORTD = 0; _delay_loop_1(4); PORTC = 0; PORTD = 2; //Spalte 2 an _delay_loop_1(40); PORTC = 0; PORTD = 0; _delay_loop_1(4); PORTC = 0; PORTD = 4; //Spalte 3 an _delay_loop_1(40); PORTC = 0; PORTD = 0; _delay_loop_1(4); PORTC = 0b00000001; PORTD = 8; //Spalte 4 an _delay_loop_1(40); PORTC = 0; PORTD = 0; _delay_loop_1(4); PORTC = 0; PORTD = 16; //Spalte 5 an _delay_loop_1(40); PORTC = 0; PORTD = 0; _delay_loop_1(4);
...das Beispiel von Peter ist doch besser... und am besten in eine Funktion verpacken die immer eine Spalte nach der anderen macht, also bei jedem Aufruf die nächste SPalte bearbeitet... Ausführlich wäre das dann so ähnlich: //Variablen für die 5 Zeile global für den ersten Versuch void Matrix_Update (void) { static uint8_t zaehler=0; switch (zaehler) { case 0: { PORTD = 0; // aus PORTC = BITMUSTER0; // neues Bitmuster PORTD = 1<<0; // an break; } case 1: { PORTD = 0; // aus PORTC = BITMUSTER1; // neues Bitmuster PORTD = 1<<1; // an break; } ... } zaehler++; if (zaehler>4) { zaehler=0; } }
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.