Hallo, ich muss eine Laufschrift für eine 8x15 LED-Matrix machen. Bei einem Interrupt sollen auf einer Matrixspalte versch. Leds leuchten, damit nach 6 Interrupts ein vollständiges Zeichen dargestellt werden kann. Die benötigte Segment-Belegung ist in einem Array gespeichert. Bei jedem neuen Interrupt steht also ein 8 Bit Wert zur Verfügung, z.B. 0b01100010 Entsprechend müssen dann in der aktuellen Spalte die Zeilen 2,6 und 7 leuchten. Die Zeilen, d.h. die zuständigen Pins in den Ports müssen anhand dieses Arrays entweder auf '0' oder '1' gesetzt werden. Wie mach ich das? Bitte helft mir, Danke. Mfg.
Du willst also die LED-Matrix multiplexen? 16 SPalten zu je 8 Zeilen? Wie findet die Spaltenaktivierung statt? Das Programm muss etwa so aussehen:
1 | global:
|
2 | uint8_t anzeige[16]; // hier müssen die anzuzeigenden Werte hin |
3 | |
4 | ISR ( SPalteninterrupt ) // zB Timer overflow |
5 | {
|
6 | static uint8_t spalte; |
7 | //-- neue Spalte errechnen--------
|
8 | spalte++; |
9 | //-- Spalte auf 0..15 begrenzen---
|
10 | spalte &= 0x0F; // 2*) |
11 | //-- Ausgabe aktive Spalte--------
|
12 | PORT_wasweißich_1 = spalte; // 1*) |
13 | //-- Ausgabe LED-Anzeige----------
|
14 | PORT_wasweißich_2 = anzeige [ spalte ]; |
15 | }
|
1*) Das muss evtl angepasst werden, abhängig von der Hardwareseitigen ansteuerung der Spalten. 2*) Falls du nur 15Spalten hast (also 0..14), dann muss das so aussehen: if ( spalte == 15 ) spalte = 0x00;
Hallo Matthias, die Matrix hat [0..14] Spalten. Ich habe das Programm für Spaltenaktivierung schon geschrieben und es sieht bei mir so aus:
1 | ISR(TIMER2_COMP_vect) //Interrupt ausgelöst |
2 | {
|
3 | Interrupt_Zaehler++; |
4 | |
5 | if (Interrupt_Zaehler < 15) |
6 | {
|
7 | //---> HIER SOLL aktuelle Array-Bit-Belegung auf Zeilenports übertragen werden, aber WIE?
|
8 | //
|
9 | PORTB=Spalte_RAM [Spalten_Nr][0]; //Spalte |
10 | PORTC=Spalte_RAM [Spalten_Nr][1]; //aktivieren |
11 | Spalten_Nr++; |
12 | }
|
13 | |
14 | else if (Interrupt_Zaehler == 15) //letzte Spalte |
15 | {
|
16 | // HIER SOLL aktuelle Array-Bit-Belegung auf Zeilenports übertragen werden, aber WIE?
|
17 | //
|
18 | PORTB=Spalte_RAM [Spalten_Nr][0]; //Spalte |
19 | PORTC=Spalte_RAM [Spalten_Nr][1]; //aktivieren |
20 | Spalten_Nr = 0; |
21 | Interrupt_Zaehler = 0; |
22 | }
|
23 | }
|
ich habe um Funktionalität zu prüfen alle Zeilenports in main() aktiviert, und auf der LED-Matrix laufen also volle Spalten. Das macht den Effekt,dass alle LEDS an sind, Spalten leuchten aber alle nacheinander mit ca. 130 Hz http://rapidshare.com/files/30595793/video.rar Aber es sollen eben nicht alle Zeilenbits aktiviert werden, sondern nur die, die benötigt werden um ein Zeichen darzustellen. Diese Bits sind im Array [128][6] definiert (128 Zeichen, 6 Spalten pro Zeichen) Ein Element in [20][3] liefert z.B. 0b00001111 Das bedeutet dass nur die oberen 4 zeilen aktiviert werden müssen. Wie teile ich diese Bits den Ports mit ?? Ich muss für Zeile 0 in dem PORTD PD5 auf 0 setzten für Zeile 1 PORTD PD6 auf 0 setzten ... für Zeile 7 PORTC PC4 auf 0 setzten ... usw. Wenn ich weiß, wie sich das realisieren lässt, dann kann ich das Programm zu Ende machen (hoffe ich)
Sieht auf den ersten Blick etwas konfus aus. Poste doch mal bitte die KOMPLETTE Schaltung, dann kann ich dir sagen, wie du das machen musst. PS: was ist das für ein komischer Link?? Hänge doch einfach Dateien hier an... Nochmal zum Verständnis: Das Display soll so angesteuert werden, dass alle LEDS (8*15=120Stück) für das Auge zugleich leuchten? Gruß
Hallo, das Display soll so angesteuert werden, dass ein lesbarer laufender Text auf den Leds erscheint. (zu meinem Problem:) Es ist mir mttlerweile gelungen auf jeder Spalte immer nur die richtigen LEDS zu schalten:
1 | PORTC |= _BV(PC3); // zuerst alle PORTs |
2 | PORTC |= _BV(PC4); // für Zeilen |
3 | PORTD = 0b11111100; // auf "1", d.h. "AUS" |
4 | |
5 | if (Array_ & 0b00000001) PORTD &= ~_BV(PD5); // "Array_" entspricht dem Wert |
6 | if (Array_ & 0b00000010) PORTD &= ~_BV(PD6); // für PORT-Belegung, für irgendein Zeichen |
7 | if (Array_ & 0b00000100) PORTD &= ~_BV(PD7); |
8 | if (Array_ & 0b00001000) PORTD &= ~_BV(PD2); |
9 | if (Array_ & 0b00010000) PORTD &= ~_BV(PD3); |
10 | if (Array_ & 0b00100000) PORTD &= ~_BV(PD4); |
11 | if (Array_ & 0b01000000) PORTC &= ~_BV(PC3); |
12 | if (Array_ & 0b10000000) PORTC &= ~_BV(PC4); |
Bei jeder Spalte schaltet dieser Code verschiede Leds und schon nach den ersten 6 Spalten erscheint das erste Zeichen des Textes. Jetzt muss ich noch irgendwie hinkriegen, dass die Zeichen langsam wandern. z.B. die ersten 5 Durchläufe durch die 15 Spalten bleibt der Text stehen, zum Anfang des 6. Durchlaufes verschiebt sich der Text um 1/6 eines Zeichens nah links oder so ähnlich. Ich bin für alle Tipps dankbar ;) Mfg.
Habe zwar den Schaltplan immer noch nicht gesehen, aber ich glaube du hast gegen einen wichtigen Grundsatz verstoßen: Beim Entwickeln der Schaltung an die Software(seitige Ansteuerung) denken.. Wie auch immer. Ich würde folgendes raten: Ein Interruptprogramm (zB Timer Overflow) Das tut nur ein uint8_t Array[15]; ausgeben, etwa so, wie ich im ersten Post dargelegt habe. Somit ist garantiert, dass immer die Information im array[0] auf Spalte Null, array[1] auf Spalte Eins... ausgegeben wird. Dies geschieht unabhängig von weiteren Programmteilen. Das Hauptprogramm (main) tut jetzt in regelmäßigen Abständen den Inhalt von Array[15] nach rechts/links verschieben, neue Inhalte in dieses Array rein kopieren,.... SO ist das eine sehr saubere Lösung...
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.