LED Matrix Ansteuerung - Denkanstoß

Gast #2006566
Lesenswert?
• ▲
▼
Hallo,

ich habe eine 10x11 LED Matrix aufgebaut. Über einen Timer wird in jeder 
Millisekunde eine Zeile aktiv geschaltet. GLeichzeitig habe ich ein 11 
Felder großes Array für das "Spaltenmuster" welches ich für die grade 
aktive Zeile auf den Port des uC lege.
1
void schreibe_matrix() {
2
  maske = (1 << aktive_zeile); //wird in der Timer ISR hochgezählt
3
  PORTA = maske;
4
  if(aktive_zeile > 7) {
5
    PORTF = maske >> 8;
6
  }
7
  PORTC = ~spaltenmuster[aktive_zeile];
8
  PORTD = ~spaltenmuster[aktive_zeile] >> 8;
9
}

Diese Lösung ist leider sehr unflexibel in der Ansteuerung der Spalten.

Jemand einen Tipp wie ich ein 2-dimensionales Array LED[11][10] nun in 
meine Funktion für die Ansteuerung übersetzen könnte?
#2006580
Lesenswert?
• ▲
▼
matrix schrieb:

> Diese Lösung ist leider sehr unflexibel in der Ansteuerung der Spalten.

Warum?

> Jemand einen Tipp wie ich ein 2-dimensionales Array LED[11][10] nun in
> meine Funktion für die Ansteuerung übersetzen könnte?

Keine gute Idee.

Abgesehen davon, dass man

   (1 << aktive_zeile)

nicht macht, weil man nicht mit einer variablen Bitzahl schieben will, 
ist der Rest so schon in Ordnung. (Fast: Erst die LED abschalten, so 
dass nichts leuchtet, dann die neue Zeile setzen und erst dann die LED 
in der neuen Spalte einschalten. Ansonsten hast du Geisterleuchten)

Die Daten werden so zurecht gelegt, dass man in der ISR möglichst 
einfach, effizient und schnell darauf zugreifen kann. Die ISR soll so 
schnell wie möglich laufen, damit sie den restlichen Programmfluss 
möglichst wenig beeinflusst.

Was versprichst du dir von einem 2D Array, was du von 2 Funktionen
1
void SetPixel( uint8_t x, uint8_t y )
2
{
3
  ...
4
}
5

6
void ClearPixel( uint8_t x, uint8_t y )
7
{
8
  ...
9
}
nicht kriegst?
Gast #2006595
Lesenswert?
• ▲
▼
Mhh eigentlich hast du recht. Aber müsste ich bei den Funktionen nicht 
auch mit einer variablen Bitzahl schieben? (Warum sollte man das 
überhaupt vermeiden?)
1
void setPixel(uint8_t x, uint8_t y) {
2
      spaltenmuster[y] = (1 << x); //wobei hier das Problem wäre das 0,0 nicht links oben ist?
3
}

Ich glaub ich steh auf dem Schlauch!
#2006604
Lesenswert?
• ▲
▼
matrix schrieb:
> Mhh eigentlich hast du recht. Aber müsste ich bei den Funktionen nicht
> auch mit einer variablen Bitzahl schieben? (Warum sollte man das
> überhaupt vermeiden?)

Weil dein AVR auf Assembler Ebene dafür keine Instruktion hat, sondern 
der Compiler das mit einer Schleife umsetzen muss.

>
>
1
void setPixel(uint8_t x, uint8_t y) {
2
>       spaltenmuster[y] = (1 << x); //wobei hier das Problem wäre das 0,0
3
> nicht links oben ist?
4
> }

* Das Problem lässt sich aber lösen.
  Du bist der Programmierer, du kannst das zurechtbiegen

* Ja, du musst auch hier variabel schieben. Klar.
  In der Programmierung gibt es aber eine schöne 'Faustregel', die da
  "Time for Space" lautet.
  Man meint damit: Durch den Einsatz von Speicherplatz kann man oft
  Laufzeit sparen und umgekehrt.
1
uint8_t Shift[] = ( 1 << 0, 1 << 1, 1 << 2, 1 << 3,
2
                    1 << 4, 1 << 5, 1 << 6, 1 << 7 };

das sind zb alle Bitmuster, die mit Verschiebungen on 0 bis 7 Bit 
möglich sind.

   Anstelle von

   1 << x

kann man daher auch schreiben

   Shift[x];

und kriegt dasselbe. Nur eben schneller.

Allerdings muss das in deiner ISR nicht so aufwändig gemacht werden. Du 
weißt ja, dass active_zeile nicht wild hin und her springt, sondern 
geordnet immer um 1 höher wird. WEnn du dir daher die Maske aufhebst und 
die Maske immer nur um 1 Stelle nach links verschiebst, hast du dasselbe 
Ergebnis, als wie wenn du 1 << active_zeile jedesmal neu berechnest.
1
ISR( .... )
2
{
3

4
  PORTC = 0xFF;
5
  PORTD = 0xFF;
6

7
  aktive_zeile++;
8
  maske <<= 1;
9

10
  if( aktive_zeile == 11 ) {
11
    aktive_zeile = 0;
12
    maske = 0x01;
13
  }
14
  
15
  PORTA = maske;
16
  PORTF = maske >> 8;
17

18
  PORTC = ~spaltenmuster[aktive_zeile];
19
  PORTD = ~spaltenmuster[aktive_zeile] >> 8;
20
}

Antwort schreiben

Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt. Bitte hier nur auf die ursprüngliche Frage antworten, für neue Fragen einen neuen Beitrag erstellen.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.