mikrocontroller.net

Forum: Compiler & IDEs Einzelne Bits vom Wert eines Array-Elem. auf Port-Pins ?


Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich muss eine Laufschrift für eine 8x15 LED-Matrix machen.

Bei einem Interrupt sollen auf einer Matrixspalte versch. Leds leuchten, 
damit  nach 6 Interrupts ein vollständiges Zeichen dargestellt werden 
kann. Die benötigte Segment-Belegung ist in einem Array gespeichert.

Bei jedem neuen Interrupt steht also ein 8 Bit Wert zur Verfügung,

z.B. 0b01100010

Entsprechend müssen dann in der aktuellen Spalte die Zeilen 2,6 und 7 
leuchten.

Die Zeilen, d.h. die zuständigen Pins in den Ports müssen anhand dieses 
Arrays entweder auf '0' oder '1' gesetzt werden.

Wie mach ich das? Bitte helft mir, Danke.

Mfg.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du willst also die LED-Matrix multiplexen?
16 SPalten zu je 8 Zeilen?

Wie findet die Spaltenaktivierung statt?

Das Programm muss etwa so aussehen:
global:
uint8_t   anzeige[16];   // hier müssen die anzuzeigenden Werte hin

ISR ( SPalteninterrupt )         // zB Timer overflow
{
     static   uint8_t    spalte;
     //-- neue Spalte errechnen--------
     spalte++;
     //-- Spalte auf 0..15 begrenzen---
     spalte   &=  0x0F;                      // 2*)
     //-- Ausgabe aktive Spalte--------
     PORT_wasweißich_1  = spalte;            // 1*)
     //-- Ausgabe LED-Anzeige----------
     PORT_wasweißich_2  = anzeige [ spalte ];
}


1*) Das muss evtl angepasst werden, abhängig von der Hardwareseitigen 
ansteuerung der Spalten.

2*) Falls du nur 15Spalten hast (also 0..14), dann muss das so aussehen:
if ( spalte == 15 ) spalte = 0x00;

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Matthias,

die Matrix hat [0..14] Spalten. Ich habe das Programm für 
Spaltenaktivierung schon geschrieben und es sieht bei mir so aus:
ISR(TIMER2_COMP_vect)              //Interrupt ausgelöst
 {
  Interrupt_Zaehler++;
  
  if (Interrupt_Zaehler < 15)
   {
    //---> HIER SOLL aktuelle Array-Bit-Belegung auf Zeilenports übertragen werden, aber WIE?
    //
    PORTB=Spalte_RAM [Spalten_Nr][0];   //Spalte
    PORTC=Spalte_RAM [Spalten_Nr][1];   //aktivieren
    Spalten_Nr++;
   }
    
  else if (Interrupt_Zaehler == 15)         //letzte Spalte
   {
    // HIER SOLL aktuelle Array-Bit-Belegung auf Zeilenports übertragen werden, aber WIE?
    //
    PORTB=Spalte_RAM [Spalten_Nr][0];    //Spalte 
    PORTC=Spalte_RAM [Spalten_Nr][1];    //aktivieren
    Spalten_Nr = 0;
    Interrupt_Zaehler = 0;
   }
 }


ich habe um Funktionalität zu prüfen alle Zeilenports in main() 
aktiviert, und auf der LED-Matrix laufen also volle Spalten. Das macht 
den Effekt,dass alle LEDS an sind, Spalten leuchten aber alle 
nacheinander mit ca. 130 Hz
http://rapidshare.com/files/30595793/video.rar
Aber es sollen eben nicht alle Zeilenbits aktiviert werden, sondern nur 
die, die benötigt werden um ein Zeichen darzustellen.

Diese Bits sind im Array [128][6] definiert (128 Zeichen, 6 Spalten pro 
Zeichen) Ein Element in [20][3] liefert z.B. 0b00001111  Das bedeutet 
dass nur die oberen 4 zeilen aktiviert werden müssen. Wie teile ich 
diese Bits den Ports mit ??

Ich muss für Zeile 0 in dem PORTD PD5 auf 0 setzten
         für Zeile 1        PORTD PD6 auf 0 setzten
...      für Zeile 7        PORTC PC4 auf 0 setzten ... usw.

Wenn ich weiß, wie sich das realisieren lässt, dann kann ich das 
Programm zu Ende machen (hoffe ich)

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Sieht auf den ersten Blick etwas konfus aus.
Poste doch mal bitte die KOMPLETTE Schaltung, dann kann ich dir sagen, 
wie du das machen musst.

PS: was ist das für ein komischer Link??
Hänge doch einfach Dateien hier an...

Nochmal zum Verständnis:
Das Display soll so angesteuert werden, dass alle LEDS (8*15=120Stück) 
für das Auge zugleich leuchten?

Gruß

Autor: Martin (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

das Display soll so angesteuert werden, dass ein lesbarer laufender Text 
auf den Leds erscheint.

(zu meinem Problem:)
Es ist mir mttlerweile gelungen auf jeder Spalte immer nur die richtigen 
LEDS zu schalten:
        PORTC |= _BV(PC3);           // zuerst alle PORTs  
  PORTC |= _BV(PC4);       // für Zeilen        
  PORTD = 0b11111100;          // auf "1", d.h. "AUS"
  
  if (Array_ & 0b00000001) PORTD &= ~_BV(PD5);   // "Array_" entspricht dem Wert
  if (Array_ & 0b00000010) PORTD &= ~_BV(PD6);   // für PORT-Belegung, für irgendein Zeichen
  if (Array_ & 0b00000100) PORTD &= ~_BV(PD7);
  if (Array_ & 0b00001000) PORTD &= ~_BV(PD2);
  if (Array_ & 0b00010000) PORTD &= ~_BV(PD3);
  if (Array_ & 0b00100000) PORTD &= ~_BV(PD4);
  if (Array_ & 0b01000000) PORTC &= ~_BV(PC3);
  if (Array_ & 0b10000000) PORTC &= ~_BV(PC4);

Bei jeder Spalte schaltet dieser Code verschiede Leds und schon nach den 
ersten 6 Spalten erscheint das erste Zeichen des Textes.

Jetzt muss ich noch irgendwie hinkriegen, dass die Zeichen langsam 
wandern.
z.B. die ersten 5 Durchläufe durch die 15 Spalten bleibt der Text 
stehen, zum Anfang des 6. Durchlaufes verschiebt sich der Text um 1/6 
eines Zeichens nah links oder so ähnlich.

Ich bin für alle Tipps dankbar ;)
Mfg.

Autor: Matthias (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Habe zwar den Schaltplan immer noch nicht gesehen, aber ich glaube du 
hast gegen einen wichtigen Grundsatz verstoßen:
Beim Entwickeln der Schaltung an die Software(seitige Ansteuerung) 
denken..

Wie auch immer.
Ich würde folgendes raten:
Ein Interruptprogramm (zB Timer Overflow)
Das tut nur ein
uint8_t Array[15];
ausgeben, etwa so, wie ich im ersten Post dargelegt habe.
Somit ist garantiert, dass immer die Information im array[0] auf Spalte 
Null,
array[1] auf Spalte Eins... ausgegeben wird.
Dies geschieht unabhängig von weiteren Programmteilen.

Das Hauptprogramm (main) tut jetzt in regelmäßigen Abständen den Inhalt 
von Array[15] nach rechts/links verschieben, neue Inhalte in dieses 
Array rein kopieren,....

SO ist das eine sehr saubere Lösung...

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.