Guten Morgen zusammen.
Ich bin momentan etwas am Ausprobieren aber ich komme gerade nicht ganz
weiter.
Ich habe eine Tastatur Matrix 5x5 und eine LED Matrix 5x7.
einzeln bekomme ich beide angesteuert.
Die LED Matrix ist an PORTD und PORTC angeschlossen an PORTD die Reihen
und an PORTC die Spalten, welche gemultiplext sind.
Nun wollte ich aber jetzt die mit es leicht machen um bequem die LEDs
durch ein Array schalten.
Mein Array sieht zum Beispiel so aus
1
uint8_tLED_Array[5]={0b00011100,
2
0b00110110,
3
0b01100011,
4
0b00110110,
5
0b00011100
6
};
Wie könnte ich nun bequem sagen wir mal im LED_Array[1] Bit 0 ändern ?
ich hatte mit das so vergestellt das ich meinem Code
LED_1(an);
bzw LED_1(aus);
Schreiben kann und das in dem Array die jeweilige LED an und
ausgeschaltet wird.
Nur der Zugriff auf das Array ist mir noch ein rätsel.
könnte mir da vieleicht jemand helfen?
Schönes Gruß
Frank
Frank schrieb:> ich hatte mit das so vergestellt das ich meinem Code> LED_1(an);> bzw LED_1(aus);> Schreiben kann
Einfacher wirds, wenn Du statt einer im Funktionsnamen codierten Nummer
die Koordinaten der LED angibst:
LedAn(int x, int y);
LedAus(int x, int y);
(x € [0..7], y € [0 .. 4])
Mit y wählst Du das Arrayelement aus, mit x das Bit im Arrayelement.
Damit kommt sowas dabei raus:
LedAn(int x, int y)
{
LED_Array[y] |= 1 << x;
}
und
LedAus(int x, int y)
{
LED_Array[y] &= ~ (1 << x);
}
... jeweils ohne Bereichsüberprüfung für x und y, was Du natürlich
nachpflegen solltest.
Stimmt soweit hatte ich noch gar nicht gedacht. Ich muss jetzt nur mal
überlegen ob das Praktisch ist bzw. wie und ob ich das umändern könnte.
Die LEDs werden nämlich später auf eine Frontplatte montiert aber nicht
alle zusammenhängend. Ich nutze hier nur ein gemultiplextes Array um IO
Pins zu sparen.
Zum Beispiel wird es eine LED geben die Anzeigen soll ob ein Heizdraht
bestromt wird. Könnte ich mit Defines Festlegen das die Heizdraht LED im
Array auf x5 y2 liegt ?
Also das man die Funktion mit:
LedAn(Heizdraht_LED);
LedAus(Heizdraht_LED);
oder wäre so was eine total unüblich Programmierung ?
Frank schrieb:> Zum Beispiel wird es eine LED geben die Anzeigen soll ob ein Heizdraht> bestromt wird. Könnte ich mit Defines Festlegen das die Heizdraht LED im> Array auf x5 y2 liegt ?>> Also das man die Funktion mit:>> LedAn(Heizdraht_LED);>> LedAus(Heizdraht_LED);>> oder wäre so was eine total unüblich Programmierung ?
Man könnte zwar schon sowas wie
1
#define Heizdraht_LED 5,2
machen, aber elegant finde ich das nicht. Wenn deine Matrix aber
sowieiso nichts mit der mechaninschen Anordnung der LEDs zu tun hat,
kannst auch alles mit einem einzigen Index machen:
Mechanisch sind sie komplett auf der Frontplatte verstreut. Ich benutze
die wirklich nur in einer Matrix/Multiplex um IO Pins zu sparen
Das mit dem Index schaue ich mir mal an das sind ganz interessant aus
Frank schrieb:> Also das man die Funktion mit:>> LedAn(Heizdraht_LED);>> LedAus(Heizdraht_LED);
Da Du bei Deiner Hardware die Hardwareadresse der LED kennen musst, also
wissen musst, in welcher Spalte und Zeile diese angeordnet sind, auch
genau diese Information in zwei #defines unterbringen:
#define SPALTE_HEIZDRAHT_LED 1
#define ZEILE_HEIZDRAHT_LED 3
LedAn(SPALTE_HEIZDRAHT_LED, ZEILE_HEIZDRAHT_LED);
Wenn Dir das zu viel Tipperei ist, lässt sich das wiederum mit einem
Macro erledigen:
#define LedAnMacro(a) LedAn(SPALTE_##a##_LED, ZEILE_##a##_LED)
so daß Du
LedAnMacro(HEIZDRAHT);
aufrufen musst.
Natürlich kannst Du auch mit einer indexbasierten Lösung arbeiten, aber
dann musst Du entweder den Index von Hand berechnen ... oder wieder ein
Macro verwenden, das den aus den "Koordinaten" der Led bestimmt.
Da kannst du aber dann auch gleich für jede LED einfach seine
Indexnummer und seine Bitnummer innerhalb des Bytes angeben lassen. Das
ist dann auch schon egal.
1
#define HEIZDRAHT_INDEX 0 // Index 0 im Array
2
#define HEIZDRAHT_BIT 0 // und dort das 0-te Bit
3
4
#define KUEHLUNG_INDEX 0 // Index 0
5
#define KUEHLUNG_BIT 1 // und dort das 1-te Bit
Noch ein bischen Makro Magie rundherum, wie du das angedeutet hast und
fertig.
Karl Heinz Buchegger schrieb:> Da kannst du aber dann auch gleich für jede LED einfach seine> Indexnummer und seine Bitnummer innerhalb des Bytes angeben lassen.
Und worin besteht da jetzt der Unterschied? Das ist, von den Namen
"Spalte" und "Zeile" abgesehen exakt dasselbe.
Die Index-Variante, die hier
Beitrag "Re: einzelne bits ändern in einem Array oder komplett anders ?" erwähnt wurde, hat
nicht Bitnummern in Indexwerten, sondern numeriert alle LEDs durch.
Rufus Τ. Firefly schrieb:> Karl Heinz Buchegger schrieb:>> Da kannst du aber dann auch gleich für jede LED einfach seine>> Indexnummer und seine Bitnummer innerhalb des Bytes angeben lassen.>> Und worin besteht da jetzt der Unterschied?
Dass sich der TO nicht mit der Umsetzung von Spalten und Zeilen in
Arrayindizes und Bitnummern gedanklich quälen muss :-)
> Das ist, von den Namen> "Spalte" und "Zeile" abgesehen exakt dasselbe.
Ja. Sollte auch für den TO nur ein Denkanstoss sein, dass er seine
Matrix in diesem Sinne nicht wortwörtlich als Matrix ansehen muss,
sondern einfach für eine LED die Ansteuerinformation so festlegen und
damit arbeiten kann, wie es ihm am leichtesten fällt.
Ob er eine LED als 'sitzt im Schnittpunkt von Zeile z und Spalte s'
ansieht, oder ob er sie als 'das zuständige Bit ist das Bit Nr b im
i-ten Eintrag des Arrays' ansieht ist gehupft wie gesprungen. Mir schien
nur, dass er die 2-te Sichtweise überhaupt nie in Betracht gezogen hätte
sondern durch den Begriff der 'Matrix' sich selbst unnötigerweise auf
Zeilen und Spalten festgenagelt sah.
sooo ich habe mal ein bisschen rumgewerkelt und wollte alles einmal
ausprobieren aber ich hänge da an einem Haken fest und zwar sieht es
momentan so aus
1
LedAn(intx,inty)
2
{
3
LED_Array[y]|=(1<<x);
4
}
5
6
7
LedAus(intx,inty)
8
{
9
LED_Array[y]&=~(1<<x);
10
}
11
12
13
14
15
intmain(void){
16
intindex;
17
18
inta,b;
19
20
DDRD=0xFF;
21
DDRC=0xFF;
22
DDRB=0xFF;
23
PORTB=0xFF;
24
25
TCCR1A=0x00;// Timer 1 Initialisieren
26
TCCR1B|=((1<<CS11)|(1<<CS10));// Prescaler auf "64"
Wenn ich das LedAn vor der Whileschleife aufrufe dann geht die richtige
LED an und wenn ich das in der Whileschleife aufrufe dann geht sie nicht
an ?!
Woran liegt das denn ?
Danach werde ich das mit dem einzelindex und den makros mal
ausprobieren.
also falls du keine lust hast das rad neu zu erfinden ...
ich habe eine einfachte LED Matrix lib gebastelt
https://github.com/benwilliam/AVR/tree/master/LED
in der LEDMatrix.c findest du funktionen um genau ein bit in einem array
zu setzen
Frank schrieb:> Wenn ich das LedAn vor der Whileschleife aufrufe dann geht die richtige> LED an und wenn ich das in der Whileschleife aufrufe dann geht sie nicht> an ?!
Die Funktionen LedAn und LedAus schalten nicht die LEDs selbst, sondern
setzen nur im Array die korrespondierenden Bits.
Wo ist Dein Code, der den Array-Inhalt per Multiplex an die LEDs
ausgibt?
Ich habe einen Timer Interruppt der alle 1ms ausgelöst wird und dann
nach unt nach die spalten ausgibt: Momentan ist es auf sehr langsam
eingestellt so das ich quasi sehe welche spalten immer an sind.
> TIMSK |= 1<<TOIE0; // Time 0 Initialisieren
Und für den Timer 0 hast du auch eine ISR?
Zeig bitte den ganzen Code. Wenn du denkst, dass das zuviel Code ist,
dann specke ihn auf das Notwendige ab, probier nochmal ob sich auch
wirklich derselbe Fehler zeigt, und poste das dann.
Für uns Helfer gibt es nichts lästigeres, als wie wenn wir uns aus
Codeschnipseln die möglichen Fehlerursachen zusammensuchen müssen und
dann ständig irgendwelche Nachfragen stellen müssen, die sich ganz
leicht dadurch verhindern lassen, indem du einfach alles zeigst.
Die meisten 'Dauerhelfer' hier sind ziemlich gut darin, auch etwas
umfangreicheren Code in kurzer Zeit zu verstehen und auf versteckte
Fehler abzuklopfen. Dazu gehören zb vergessene volatile oder auch
freigegebene Interrupts, für die es keine ISR gibt. Beides ist mit
deinen Codeschnipseln nicht beantwortbar.