LEDs ansteuern via Multiplexing

OP (Firma: FH-Köln) #1049989
Lesenswert?

habe vor eine 3x3 RGB Matrix aufzubauen. Ich will je nachdem 
unterschiedlich verschiedene Felder(zb. Feld 1 und 3) zum leuchten 
bringen und in der main das Feld und die Farbe übergeben! Hatte zuerst 
die 2 Zeilen zum Auschalten ( &= ~.... ) in jeder if Anweisung nicht 
drinnen, jedoch wäre dann für immer die Zeile bzw Spalte aktiviert. Geht 
das mit dem Quelltext, dass ich Feld 1 und Feld 3 gleihczeitig leuchten 
lasse? Ich schalte ja ansich die Felder durch, aber schalte sie ja auch 
wiederrum sofort danach wieder aus!!


1
void set_field(int field, int color)
2
{
3
  switch(field)
4
  {
5
    case 1:
6
      if(color==0)
7
        {PORTC |= (1 << PC3); //Zeile 1
8
        PORTB |= (1 << PB0); // Spalte 1
9
        //_delay_ms(1);
10
        PORTC &= ~(1 << PC3);
11
        PORTB &= ~(1 << PB0);}
12
      if(color==1)
13
        {PORTC |= (1 << PC3); //Zeile 1
14
        PORTB |= (1 << PB2); // Spalte 3
15
        //_delay_ms(1);
16
        PORTC &= ~(1 << PC3);
17
        PORTB &= ~(1 << PB2);}
18
     break;
19
    case 2:
20
      if(color==0)
21
        {PORTC |= (1 << PC3); //Zeile 1
22
        PORTB |= (1 << PB3); // Spalte 4
23
        //_delay_ms(1);
24
        PORTC &= ~(1 << PC3);
25
        PORTB &= ~(1 << PB3);}
26
      if(color==1)
27
        {PORTC |= (1 << PC3); //Zeile 1
28
        PORTB |= (1 << PB5); // Spalte 6
29
        //_delay_ms(1);
30
        PORTC &= ~(1 << PC3);
31
        PORTB &= ~(1 << PB5);}
32
     break;
33
    case 3:
34
      if(color==0)
35
        {PORTC |= (1 << PC3); //Zeile 1
36
        PORTC |= (1 << PC0); // Spalte 7
37
        //_delay_ms(1);
38
        PORTC &= ~(1 << PC3);
39
        PORTC &= ~(1 << PC0);}
40
      if(color==1)
41
        {PORTC |= (1 << PC3); //Zeile 1
42
        PORTC |= (1 << PC2); // Spalte 9
43
        //_delay_ms(1);
44
        PORTC &= ~(1 << PC3);
45
        PORTC &= ~(1 << PC2);}
46
     break;
47
               ..........................................
Gast #1050017
Lesenswert?

Das hat doch nichts mit Matrix ansteuerung zutun!

Du müsstest ja zB in der Main permanent deine funktion set_field mit 
verschiedenen Parametern aufrufen, damit das alles funzt.

Du brauchst einen Zwischenspeischer, der zyklisch per TImerinterrupt 
ausgegeben wird.

Wenn du leds zu/abschalten willst, musst du das anshcließend nur in 
besagtem Zwischenspeicher tun. Den nenne ich Videospeicher.


Poste doch mal einen Schaltplan dazu.
Gast #1050558
Lesenswert?

1. Du musst die Pausen auch aktivieren, sonst leuchten sie so kurz, dass 
du es nicht siehst. Versuchs mit 5-10 ms. Je nachdem wieviele Elemente 
du durchschaltest, die Zeiten verkürzen.
2. Du kannst dir die ganze switch() Anweisung komplett sparen. Du 
übergibst ja der Funktion sowieso schon welches Feld du ansteuern 
willst.

Änder die Feldansteuerung einfach so:
PORTC |= (1 << field); //Zeile 1
Natürlich muss die Zahl des Feldes, am entsprechenden Pin sein, sonst 
musst du davor noch einen verschobenen Wert hinzufügen oder abziehen.
Bsp: Zeile 1 an Pin 3: immer field +2

3. Für if Anweisungen gibt es auch die else Anweisung.
if (prüfwert)
// WIRD AUSGEFÜHRT WENN WAHR
else
// WENN AUSGEFÜHRT WENN UNWAHR


void set_field(int field, int color)
{
   PORTC |= (1 << field); //Zeile 1
      if(color==0) {
        PORTB |= (1 << PB0); // Spalte 1
        _delay_ms(10);
        PORTB &= ~(1 << PB0);}
     } else {
        PORTB |= (1 << PB2); // Spalte 3
        _delay_ms(10);
        PORTB &= ~(1 << PB2);}
    }
   PORTC &= ~(1 << field);
}
OP (Firma: FH-Köln) #1050875
Lesenswert?

ja danke die Idee ist gut!
Aber ich sehe jetzt auch wieder das Problem, dass ich in der main immer 
wieder die Werte übergeben muss die gesetzt sind!! Einfacher wäre es 
wohl wie "lippy" schrieb, dass ich eine Art von Videospeicher 
programmiere?! Einmal setzen und dann weiss er bescheid?!
Gast #1050883
Lesenswert?

>Aber ich sehe jetzt auch wieder das Problem, dass ich in der main immer
>wieder die Werte übergeben muss die gesetzt sind!

Da gibt es noch ein Problem:
1
  _delay_ms(10);


>Einfacher wäre es wohl wie "lippy" schrieb, dass ich eine Art von >Videospeicher 
programmiere?!

Ja die Idee scheint gut zu sein..
das fenster aufmach
;-)


>Einmal setzen und dann weiss er bescheid?!
Noch besser: Es wird sogar zyklisch von allein ausgegeben...
Gast #1050914
Lesenswert?

>wie muss ich mir das denn vorstellen?

Eher so:
1
ISR(timer_überlauf) // das wird bei jedem Timerüberlauf angesprungen
2
{
3
 ...
4
 // hier wird immer nur eine Spalte/Zeile ausggegeben.
5
 // beim nächsten mal somit die nächste...
6
}
7

8
void Timer_init ( void)
9
{
10
...
11
}
12

13
void main(void){
14

15
Timer_init(); // zB so dass er alle 1ms überläuft
16
sei()
17

18
while(1)
19
 {
20
   ... mach irgendwas anderes
21
 }
22
}

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren