Eine schöne Tageszeit liebe Gemeinde, da mein Wissen in Programmierung von Mikrocontrollern noch locker unter den Tisch wandert, bitte ich um eine Erklärung und etwaige Tipps von Fortgeschrittenen und Experten. Es geht lediglich um ein Lauflicht: LED-Board, welches an den STRL-Stecker vom RN-MiniControl angeschlossen ist. Der Haken dabei ist, dass der Stecker nicht jeweils eine Portbezeichnung beinhaltet, sondern von PB0 über PC3 bis hin zu PD7 geht. Wie stelle ich das an, unter Verwendung verschiedener Ports ein Lauflicht zu bekommen?
Archangel schrieb: > Wie stelle ich das an, unter Verwendung verschiedener Ports ein > Lauflicht zu bekommen? In dem Du einfach jeden einzelnen Pin nacheinander toggelst, dazu brauchst Du noch die Zeit die die einzelen LED an sein soll.
Archangel schrieb: > Wie stelle ich das an, unter Verwendung verschiedener Ports ein > Lauflicht zu bekommen? Indem du dir zb selber sowas wie einen 'virtuellen Port' bastelst (ein hochgestochenes Wort für einfach nur eine entsprechende Variable) und dann ausgehend von diesem "virtuellen Port" die Verteilung auf die einzelnen µC-Pins programmierst. So zb würd ich das machen, wenn das Lauflicht komplexere Muster machen soll. Wenn es nur eine einzige helle LED ist, die im Kreis läuft, dann allerdings würde ich die Pins direkt einfach toggeln.
Ich fürchte, dass ich immer noch nicht ganz weiterkomme... Folgender Quelltext ist schonmal entstanden:
1 | #include <avr/io.h> |
2 | #include <util/delay.h> |
3 | |
4 | int main(void); |
5 | |
6 | const int8_t numbers[8] = |
7 | {
|
8 | // LED: 0-7
|
9 | |
10 | 0b01000000, // PD6 |
11 | 0b10000000, // PD7 |
12 | 0b00000001, // PB0 |
13 | 0b00100000, // PB5 |
14 | 0b00001000, // PC3 |
15 | 0b00001000, // PB3 |
16 | 0b00001000, // PD3 |
17 | 0b00000100, // PC2 |
18 | |
19 | };
|
20 | |
21 | // wartet ms Millisekunden
|
22 | |
23 | void delay_ms(uint16_t ms) |
24 | {
|
25 | for(uint16_t t=0; t<=ms; t++) |
26 | _delay_ms(1); |
27 | }
|
28 | |
29 | int main(void) |
30 | {
|
31 | int i=1; |
32 | |
33 | DDRB |= ( 1 << DDB0) | (1<<DDB3) | ( 1<<DDB5); // PORTB als Ausgang |
34 | DDRC |= ( 1 << DDC2) |1<<DDC3); // PORTC als Ausgang |
35 | DDRD |= ( 1 << DDD3) | (1<<DDD6) | ( 1 <<DDD7); // PORTD als Ausgang |
36 | |
37 | |
38 | while(1) |
39 | {
|
40 | |
41 | /*PORTD = numbers[i];
|
42 | delay_ms(70);
|
43 | PORTB = numbers[i];
|
44 | delay_ms(70);
|
45 | PORTC = numbers[i];
|
46 | delay_ms(70);*/
|
47 | |
48 | |
49 | }
|
50 | |
51 | return 0; |
52 | }
|
Nur müsste jetzt in die while-Schleife eine ähnliche Form wie die hier kommen:
1 | PORTB ^= (1<<PB0) | (1<<PB5); |
Ich komme aber nicht auf die Syntax für mehrere LEDs drauf :( Bedanke mich im Voraus
Archangel schrieb: > Ich komme aber nicht auf die Syntax für mehrere LEDs drauf :( > > Bedanke mich im Voraus Wo liegt das Problem, Du schaltest zuerst alle PINs von PortB nacheinander durch, dann PortB komplett aus und fängst dann bei PortC bzw. PortD von vorne an. Dein Array benötigst Du nicht, da PB0 nichts anderes als 0 ist wie im header vom GCC zu erkennen:
1 | /* PORTB */
|
2 | #define PB7 7
|
3 | #define PB6 6
|
4 | #define PB5 5
|
5 | #define PB4 4
|
6 | #define PB3 3
|
7 | #define PB2 2
|
8 | #define PB1 1
|
9 | #define PB0 0
|
Du kannst also statt PORTB ^= (1<<PB0) auch PORTB ^= (1<<0) schreiben. Ergo nun einfach zwei verschachtelte for schleifen programmieren, eine für die drei Ports und eine für die jeweiligen 8 Pins derselben und das war's.
Das Problem ist, dass die Reihenfolge genau so zu sein hat, wie im Array geschrieben. Das wäre die benötigte Reihenfolge der geschalteten LEDs.
Archangel schrieb: > Das Problem ist, dass die Reihenfolge genau so zu sein hat, wie im Array > geschrieben. Das wäre die benötigte Reihenfolge der geschalteten LEDs. Dann mach's in Deiner main zu Fuß also z.B. sowas:
1 | PORTD ^= (1<<PD6); |
2 | delay_ms(70); |
3 | PORTD ^= (1<<PD6); |
Halt für alle nacheinander ;-)
Und wie immer ist die richtige Lösung die einfachste.. Ich hab' schon über Interrupts, Timer etc gelesen ;) Entschuldige, dass es solange dauerte, 1ll, und vielen Dank für deine Hilfe. Wie war das eigentlich mit dem "virtuellen Port" gemeint? MfG Nik
Archangel schrieb: > Wie war das eigentlich mit dem "virtuellen Port" gemeint?
1 | #define SWITCH_LED(on,port,pin) if(on) port |= (1<<pin); else port &= ~(1<<pin);
|
2 | |
3 | int main(void) |
4 | {
|
5 | uint8_t Licht = 0; |
6 | |
7 | ...
|
8 | |
9 | while(1) |
10 | {
|
11 | // realisiere ein umlaufendes 'Lauflicht'
|
12 | // indem ein Lichtmuster in der Variablen Licht umläuft
|
13 | if( Licht == 0 ) |
14 | Licht = 0x05; |
15 | else
|
16 | Licht = Licht << 1; |
17 | |
18 | // die Bits entsprechend verteilen
|
19 | SWITCH_LED( Licht & 0x01, PORTD, PD6 ); |
20 | SWITCH_LED( Licht & 0x02, PORTD, PD7 ); |
21 | SWITCH_LED( Licht & 0x04, PORTB, PB0 ); |
22 | SWITCH_LED( Licht & 0x08, PORTB, PB5 ); |
23 | SWITCH_LED( Licht & 0x10, PORTC, PC3 ); |
24 | SWITCH_LED( Licht & 0x20, PORTB, PB3 ); |
25 | SWITCH_LED( Licht & 0x40, PORTD, PD3 ); |
26 | SWITCH_LED( Licht & 0x80, PORTC, PC2 ); |
27 | |
28 | delay_ms(70); |
29 | }
|
30 | |
31 | return 0; |
32 | }
|
Die 'Musterarbeit' selbst findet in der Variablen 'Licht' statt. Dort hast du 8 Bits in der natürlichen Reihenfolge und programmierst diese Bits so, dass sie das als Lauflicht realisieren, was du haben willst. Du tust einfach so, als ob du einen 'Port' hättest, an dem die Led in der richtigen Reihenfolge bitweise angeordnet sind. Und dann verteilst du diese sauber angeordneten Bits mit einem 'Treiber' an die entsprechenden physikalischen Pins, wobei die abweichende Reihenfolge berücksichtigt wird und die Pins entsprechend umsortiert angesteuert werden. Voila: Wenn es darum geht komplizierte Lauflichtmuster zu realisieren, hast du einen 'virtuellen' Port, der sich genau so verhält wie man es haben möchte - die gedachten Led sind exakt in der richtigen Bitreihenfolge angeordnet. Die Anpassung an die reale Hardware geschieht in der 'Treiber'-Schicht.
Vielen Dank für Eure Hilfe, wirklich ausgiebige Antworten :) MfG Nik
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.