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


von Martin (Gast)


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.

von Matthias (Gast)


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:
1
global:
2
uint8_t   anzeige[16];   // hier müssen die anzuzeigenden Werte hin
3
4
ISR ( SPalteninterrupt )         // zB Timer overflow
5
{
6
     static   uint8_t    spalte;
7
     //-- neue Spalte errechnen--------
8
     spalte++;
9
     //-- Spalte auf 0..15 begrenzen---
10
     spalte   &=  0x0F;                      // 2*)
11
     //-- Ausgabe aktive Spalte--------
12
     PORT_wasweißich_1  = spalte;            // 1*)
13
     //-- Ausgabe LED-Anzeige----------
14
     PORT_wasweißich_2  = anzeige [ spalte ];
15
}


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;

von Martin (Gast)


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:
1
ISR(TIMER2_COMP_vect)              //Interrupt ausgelöst
2
 {
3
  Interrupt_Zaehler++;
4
  
5
  if (Interrupt_Zaehler < 15)
6
   {
7
    //---> HIER SOLL aktuelle Array-Bit-Belegung auf Zeilenports übertragen werden, aber WIE?
8
    //
9
    PORTB=Spalte_RAM [Spalten_Nr][0];   //Spalte
10
    PORTC=Spalte_RAM [Spalten_Nr][1];   //aktivieren
11
    Spalten_Nr++;
12
   }
13
    
14
  else if (Interrupt_Zaehler == 15)         //letzte Spalte
15
   {
16
    // HIER SOLL aktuelle Array-Bit-Belegung auf Zeilenports übertragen werden, aber WIE?
17
    //
18
    PORTB=Spalte_RAM [Spalten_Nr][0];    //Spalte 
19
    PORTC=Spalte_RAM [Spalten_Nr][1];    //aktivieren
20
    Spalten_Nr = 0;
21
    Interrupt_Zaehler = 0;
22
   }
23
 }


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)

von Matthias (Gast)


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ß

von Martin (Gast)


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:
1
        PORTC |= _BV(PC3);           // zuerst alle PORTs  
2
  PORTC |= _BV(PC4);       // für Zeilen        
3
  PORTD = 0b11111100;          // auf "1", d.h. "AUS"
4
  
5
  if (Array_ & 0b00000001) PORTD &= ~_BV(PD5);   // "Array_" entspricht dem Wert
6
  if (Array_ & 0b00000010) PORTD &= ~_BV(PD6);   // für PORT-Belegung, für irgendein Zeichen
7
  if (Array_ & 0b00000100) PORTD &= ~_BV(PD7);
8
  if (Array_ & 0b00001000) PORTD &= ~_BV(PD2);
9
  if (Array_ & 0b00010000) PORTD &= ~_BV(PD3);
10
  if (Array_ & 0b00100000) PORTD &= ~_BV(PD4);
11
  if (Array_ & 0b01000000) PORTC &= ~_BV(PC3);
12
  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.

von Matthias (Gast)


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

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.