Forum: Mikrocontroller und Digitale Elektronik LED Matrix Ansteuerung - Denkanstoß


von matrix (Gast)


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?

von Karl H. (kbuchegg)


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?

von matrix (Gast)


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!

von Karl H. (kbuchegg)


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
}

von matrix (Gast)


Lesenswert?

Alles klar, Danke!
Ich denke darauf kann sogar ich aufbauen ;)

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
Noch kein Account? Hier anmelden.