Forum: Compiler & IDEs LEDs ansteuern via Multiplexing


von Jens H. (Firma: FH-Köln) (holzi)


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
               ..........................................

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Dir fehlen zumindest Block-Klammerungen nach den if-Anweisungen
sowie break-Anweisungen am Ende der case-Zweige.

von Jens H. (Firma: FH-Köln) (holzi)


Lesenswert?

jetzt schon =)

von Matthias L. (Gast)


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.

von Gast (Gast)


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);
}

von Jens H. (Firma: FH-Köln) (holzi)


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?!

von Matthias L. (Gast)


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...

von Jens H. (Firma: FH-Köln) (holzi)


Lesenswert?

wo siehst du denn jetzt an der delay Funktion ein Problem?

Zyklisch hatte ich das eh vor in der main zu machen. Nur sah ich das 
Problem, dass evtl alles zu langsam umgeschaltet wird!

von Matthias L. (Gast)


Lesenswert?

Wahrend du dort mit delay die µC anhälst, kannst du  nichts anderes 
machen.

Nimm nen Timerinterrupt dafür. So würde die while-Schleife im main leer 
sein können.

von Jens H. (Firma: FH-Köln) (holzi)


Lesenswert?

ich hab grad mal nach Timer Interrupt gegoogelt..

wie muss ich mir das denn vorstellen?
1
void main(void){
2
3
sei()
4
5
while(1){
6
7
/*Interrupt Aufruf*/
8
9
 }
10
}

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Jens Holzi wrote:

> wie muss ich mir das denn vorstellen?

Ungefähr so:

http://www.nongnu.org/avr-libc/user-manual/group__demo__project.html

von Matthias L. (Gast)


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
}

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.