mikrocontroller.net

Forum: Compiler & IDEs LEDs ansteuern via Multiplexing


Autor: Jens Holzi (Firma: FH-Köln) (holzi)
Datum:

Bewertung
0 lesenswert
nicht 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!!


void set_field(int field, int color)
{
  switch(field)
  {
    case 1:
      if(color==0)
        {PORTC |= (1 << PC3); //Zeile 1
        PORTB |= (1 << PB0); // Spalte 1
        //_delay_ms(1);
        PORTC &= ~(1 << PC3);
        PORTB &= ~(1 << PB0);}
      if(color==1)
        {PORTC |= (1 << PC3); //Zeile 1
        PORTB |= (1 << PB2); // Spalte 3
        //_delay_ms(1);
        PORTC &= ~(1 << PC3);
        PORTB &= ~(1 << PB2);}
     break;
    case 2:
      if(color==0)
        {PORTC |= (1 << PC3); //Zeile 1
        PORTB |= (1 << PB3); // Spalte 4
        //_delay_ms(1);
        PORTC &= ~(1 << PC3);
        PORTB &= ~(1 << PB3);}
      if(color==1)
        {PORTC |= (1 << PC3); //Zeile 1
        PORTB |= (1 << PB5); // Spalte 6
        //_delay_ms(1);
        PORTC &= ~(1 << PC3);
        PORTB &= ~(1 << PB5);}
     break;
    case 3:
      if(color==0)
        {PORTC |= (1 << PC3); //Zeile 1
        PORTC |= (1 << PC0); // Spalte 7
        //_delay_ms(1);
        PORTC &= ~(1 << PC3);
        PORTC &= ~(1 << PC0);}
      if(color==1)
        {PORTC |= (1 << PC3); //Zeile 1
        PORTC |= (1 << PC2); // Spalte 9
        //_delay_ms(1);
        PORTC &= ~(1 << PC3);
        PORTC &= ~(1 << PC2);}
     break;
               ..........................................


Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

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

Autor: Jens Holzi (Firma: FH-Köln) (holzi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
jetzt schon =)

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Gast (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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);
}

Autor: Jens Holzi (Firma: FH-Köln) (holzi)
Datum:

Bewertung
0 lesenswert
nicht 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?!

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht 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:
  _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...

Autor: Jens Holzi (Firma: FH-Köln) (holzi)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Jens Holzi (Firma: FH-Köln) (holzi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich hab grad mal nach Timer Interrupt gegoogelt..

wie muss ich mir das denn vorstellen?
void main(void){

sei()

while(1){

/*Interrupt Aufruf*/

 }
}

Autor: Jörg Wunsch (dl8dtl) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jens Holzi wrote:

> wie muss ich mir das denn vorstellen?

Ungefähr so:

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

Autor: Matthias Lipinsky (lippy)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>wie muss ich mir das denn vorstellen?

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

void Timer_init ( void)
{
...
}

void main(void){

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

while(1)
 {
   ... mach irgendwas anderes
 }
}

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
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.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.