Hallo! Ich steh ein wenig auf dem Schlauch. Ich habe eine Funktion gebastelt die eine LED auf und abblendet. Die Geschwindigkeit des auf und abblendens ist jedesmal zufällig. Nun möchte ich mehrere LEDs ansteuern und könnte dies durch kopieren,umbenennen und ändern des Ports in der Funktion erreichen. Das scheint mir nicht elegant zu sein. Andererseits bereitet es mir Kopfzerbrechen das einiges an Parametern pro Aufruf der Funktion geändert wird. Wie macht man sowas richtig?
Hallo, du kannst einfach einen PORT und einen PIN übergeben, z.b. blink(PORTA, PA0) bzw. in deinem Fall PORTA |= blink(PA0); gruß
Hallo Mat, ich glaube das wird der Sache nicht gerecht da ja alle LEDs unterschiedlich schnell auf und abblenden sollen. Ich übergebe am Ende die Sache so: blink[0]=blink0() blink[1]=blink1() ..... blink[7] und danach: Ausgabe=(blink0|blink1|blink2|.........|blink7)
sowas in der art ?
1 | #define PWM_MAX 34 |
2 | #define PWM_CHANNEL 8 |
3 | #define PWM_DIR (led_val[i]&128) |
4 | #define PWM_VAL (led_val[i]&127) |
5 | |
6 | char led_val[PWM_CHANNEL]; |
7 | char led_dly[PWM_CHANNEL] |
8 | |
9 | char blink0 (void) |
10 | { |
11 | char i; // temp general purpose variable |
12 | static char pwm; |
13 | int var; |
14 | |
15 | for(i=PWM_CHANNEL;i--;) { |
16 | if(!led_dly[i]--) //Bei Ablauf: |
17 | { |
18 | if (PWM_VAL==PWM_MAX) //Zählrichtung bestimmen |
19 | led_val[i]=PWM_MAX; |
20 | else if (PWM_VAL==0) |
21 | led_val[i]=128; |
22 | |
23 | PWM_DIR?led_dly[i]++:led_dly[i]--; //Abhängig von der Richtung zählen |
24 | led_dly[i]=rand()%200+1; //Neue zufällige Länge für die Warteschleife |
25 | } |
26 | } |
27 | |
28 | if (pwm==44) //Hier wird PWM generiert |
29 | pwm=0; |
30 | |
31 | pwm=pwm+1; |
32 | |
33 | var=0; |
34 | for(i=PWM_CHANNEL;i--;) |
35 | if(pwm>PWM_VAL) var|=1<<i; |
36 | |
37 | return var; |
38 | } |
Hallo Chris, ich glaube nicht das es "sowas in der Art" ist. Meine Funktion generiert ja eine PWM. Da Du "for" Schleifen in deinem Vorschlag hast gehe ich davon aus das keine PWM generieren kannst. Ist das so richtig?
Das ist so falsch. Deine Funktion generiert ein Bitpattern welches für ein PWM gebraucht werden kann, pwm wird damit selbst nicht generiert. Der Forschlag ist im Prinzip dein Code, welcher einfach auf 8 leds erweitert wurde. Derzeit max 8 leds, wenn du das char blink0 in ein unsigned int blink0 änderst sind es dann max 16 leds. Wenn du mehr brauchst, auf long ändern sowie auch die Definition von var und du hast max 32 leds. Weniger ist auch möglich, einfach die Konstante ändern.
Es hat sich jedoch beim Editieren ein Fehler eingeschlichen, PWM_DIR?led_dly[i]++:led_dly[i]--; muss PWM_DIR?led_val[i]++:led_val[i]--; heissen, da ja x (val) gezählt wurde.
Hallo Chris, also ich versuche mal nachzuvollziehen was Du da Vorgeschlagen hast. Es werden da sicher noch Fragen auftauchen aber schonmal vielen Dank: Ist ja genug Stoff für einige Stunden ;-)
Ich hatte übrigens auch einen Fehler drinne und zwar bei der Neubestimmung der Auf und Abblendzeit.Nur der Vollständigkeit halber anbei der korrigierte Code.
Ich denke, es wäre einfacher einfach in HW auszutesten mit ein paar Leds mehr am Port, dann versetehst du es sicher einfacher. Ansonsten was ich nicht verstanden habe, wieso du bis 34 zählst und den pwm bis 44, also ein fixed on-pwm von ca 22.7% immer an hast, aber ich kenne auch nicht den zeitintervall von einem PWM zum anderen, vielleicht entspricht eine Einheit auch ca 1/2 Stunde. Sollte aber 44 nur ein Tippfehler sein, dann ändere bitte den Wert auf PWM_MAX. So kannst du auch ev. später auf z.B. 100 ändern.
Hallo Chris, ich denke um deinen Code zu verstehen muss ich noch einige Kapitel in meinen C Büchern weiterarbeiten. Im Moment versuche ich nur nachzuvollziehen was Du im PWM Teil machst dabei stolpere ich im Moment über: #define PWM_VAL (led_val[i]&127) Mir scheint aber das Kapitel "Makros" das Richtige zu sein. Ich habe das Ganze hier bereits mit 8 LEDs aufgebaut. Die hängen an einem 74HC595 (über SPI von einem ATmega8 gesteuert) und die erste LED macht was sie soll und , wie gesagt, wenn ich den ganzen Kram 8 mal kopieren würde, würden die anderen auch das tun was sie sollen. Aber das soll ja nicht Ziel der "Übung" sein ;-) Die 44 sind kein Fehler. Wenn man noch mehr dimmt sieht man die einzelnen Helligkeitstufen und das ist nicht "schön" Wie man das löst ist sicherlich auch "Spass" für einige Nachmittage. Tipps nehme ich gerne an :-)
Also ich rate jetzt mal ein wenig: #define PWM_VAL (led_val[i]&127) Bedeutet das PWM_VAL "i" mal die Zeichenkette "led_val" denen wiederum jeweils der Wert "127" zugewiesen wird? Und wie geht denn "i--" in einer for Schleife als Bedingung die dann auch noch keine Reinitialisierung enthält??? Was passiert denn da dann eigentlich?
Schreib rein was dir nicht klar ist und wieso, werde es dann erklären. Ein define ist ein substitute, in der einfachsten Form ohne parameter wie hier dient er hauptsächlich der Lesbarkeit des Quellcodes. #define PWM_VAL (led_val[i]&127) Ich habe die variable direction sowie x in eine einzige variable zusammengesteckt, nähmlich led_val. Bit 7 ist direction und der Rest ist x (von 0-127). Man hätte das auch mit Strukturen und Bitfeldern machen können, bringt aber gewisse Probleme mit sich, welche man dann entsprechend kontrollieren und beseitigen muss. Deshalb hatte ich hier einen einfacheren Weg gewählt. Ist aber im Prinzip dasselbe wie struct led_val_s { int val :7; int direction :1; } led_val[8]; Dies nur am Rande. PWM_VAL wird verwendet, um val, oder x in deinem Beispiel rauszubekommen, wertebereich 0-127 . und PWM_DIR um die Direction rauszubekommen, wertebereich 128 oder 0 der einfachheit halber. Eigentlich sollte es heissen, es werden die 7 bits ausmaskiert #define PWM_VAL (led_val[i]&((1<<7)-1)) und #define PWM_DIR (led_val[i]&(1<<7)) val&mask heisst hier value and mask, ein binäres and. << heisst shift left. led_val[i] als Bit 0bDVVVVVVV , D=Dir V=val . Auf das reduziert sich das.
led_val ist ein Array aus PWM_CHANNEL Werten, also aus 8 in diesem Beispiel char led_var[PWM_CHANNEL]; // ist dasselbe als char led_var[8]; // ein Array welches von led_var[0] bis led_var[7] // zugegriffen wird, 8 variabeln insgesamt. die variable i ist ein Zähler, welcher auch mit char i ; // generic counter variable initialisiert wird. Das Makro oder die Define #define PWM_VAL (led_val[i]&127) wird im folgenden Code if (PWM_VAL==PWM_MAX) durch if ((led_val[i]&127)==34) ersetzt. Wenn du cpp bemühst, bekommst du das auch angezeigt. Das For, PWM_CHANNEL ist dasselbe wie 8 und ein code wie dieser: for(i=PWM_CHANNEL;i--;) printf("i=%d\n",i); -> for(i=8;i--;) printf("i=%d\n",i); = produziert: i=7 i=6 i=5 i=4 i=3 i=2 i=1 i=0 und wird insgesamt 8 mal durchlaufen. Beim Vergleich i-- != 0 wird i nachher automatisch decrementiert. Ansonsten könntest du auch schreiben, for(i=0;i<PWM_CHANNEL;i++) gäbe denselben Effekt, nur die Richtung ist umgekehrt, von 0->max
Chris, wow! Respekt! Ich melde mich hier wieder sobald ich alles wirklich verstanden und vielleicht sogar umgesetzt habe. Vielen vielen Dank!
Hier nochmal der Code mit deinem Fehler behoben (rauf+runter gezählt).
1 | #define PWM_CHANNEL 8 |
2 | #define PWM_MAX 35 |
3 | |
4 | char blink0 (void) |
5 | { |
6 | static char val[PWM_CHANNEL]; |
7 | static char dly[PWM_CHANNEL]; |
8 | static char rnd[PWM_CHANNEL]; |
9 | static char pwm; |
10 | |
11 | char i; // temp general purpose variable |
12 | int var; |
13 | |
14 | for(i=PWM_CHANNEL;i--;) |
15 | if(!dly[i]--) //Bei Ablauf: |
16 | { |
17 | if (val[i]==0) |
18 | dly[i]=rnd[i]=rand()%200+1; |
19 | else if (val[i]==PWM_MAX) //Zählrichtung bestimmen |
20 | dly[i]=rnd[i],rnd[i]=0; |
21 | |
22 | rnd[i]?val[i]++:val[i]--; //Abhängig von der Richtung zählen |
23 | } |
24 | |
25 | |
26 | if (pwm==44) //Hier wird PWM generiert |
27 | pwm=0; |
28 | |
29 | pwm=pwm+1; |
30 | |
31 | var=0; |
32 | for(i=PWM_CHANNEL;i--;) |
33 | if(pwm>PWM_VAL) var|=1<<i; |
34 | |
35 | return var; |
36 | } |
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.