Hallo.
Ich versuche mich gerade am Soft-PWM-Beispiel (Version 3).
1 | /******************************************************************/
| 2 | // nur zum testen, in der Anwendung entfernen
| 3 | /*
| 4 | // Test values
| 5 | volatile uint8_t tmp;
| 6 | const uint8_t t1[8]={255, 40, 3, 17, 150, 99, 5, 9};
| 7 | const uint8_t t2[8]={27, 40, 3, 0, 150, 99, 5, 9};
| 8 | const uint8_t t3[8]={27, 40, 3, 17, 3, 99, 3, 0};
| 9 | const uint8_t t4[8]={0, 0, 0, 0, 0, 0, 0, 0};
| 10 | const uint8_t t5[8]={9, 1, 1, 1, 1, 1, 1, 1};
| 11 | const uint8_t t6[8]={33, 33, 33, 33, 33, 33, 33, 33};
| 12 | const uint8_t t7[8]={0, 0, 0, 0, 0, 0, 0, 88};
| 13 |
| 14 |
| 15 | // Messung der Interruptdauer
| 16 | tmp =1;
| 17 | tmp =2;
| 18 | tmp =3;
| 19 |
| 20 | // Debug
| 21 |
| 22 | memcpy(pwm_setting, t1, 8);
| 23 | pwm_update();
| 24 |
| 25 | memcpy(pwm_setting, t2, 8);
| 26 | pwm_update();
| 27 |
| 28 | memcpy(pwm_setting, t3, 8);
| 29 | pwm_update();
| 30 |
| 31 | memcpy(pwm_setting, t4, 8);
| 32 | pwm_update();
| 33 |
| 34 | memcpy(pwm_setting, t5, 8);
| 35 | pwm_update();
| 36 |
| 37 | memcpy(pwm_setting, t6, 8);
| 38 | pwm_update();
| 39 |
| 40 | memcpy(pwm_setting, t7, 8);
| 41 | pwm_update();
| 42 | */
| 43 | /******************************************************************/
|
setzt doch nur einmal zu Beginn die Ausgänge nacheinander auf die
eingetragenen Werte.
Wenn ich jetzt irgendwelche zeitlichen Verläufe einprogrammieren will,
z.B. einen einfachen Wechsel nach 2 Sekunden, sollte doch sowas helfen:
1 | // globale Variablen
| 2 |
| 3 | volatile uint8_t foo; pwm_durchlaeufe; // ----Neue Variablen
|
1 | void countpwm(void) { // ----Neue Funktion
| 2 | if (pwm_durchlaeufe == 200) {
| 3 | pwm_durchlaeufe = 0;
| 4 | if (foo == 1) {
| 5 | memcpy(pwm_setting, t6, 8);
| 6 | foo=0;
| 7 | pwm_update();
| 8 | }
| 9 | else {
| 10 | memcpy(pwm_setting, t5, 8);
| 11 | foo=1;
| 12 | pwm_update();
| 13 | }
| 14 | }
| 15 | else {
| 16 | pwm_durchlaeufe++;
| 17 | }
| 18 | }
|
1 | int main(viod) {
| 2 | .
| 3 | .
| 4 | .
| 5 | const uint8_t t5[8]={0, 0, 0, 0, 0, 12, 200, 0};
| 6 | const uint8_t t6[8]={0, 0, 0, 0, 0, 200, 12, 0};
| 7 | memcpy(pwm_setting, t5, 8); // Neue Startbedingungen
| 8 | pwm_update();
| 9 | foo = 0; pwm_durchlaeufe = 0;
|
Aber nach 2 Sekunden wirds einfach dunkel.
Sieht jemand woran das liegt?
Komplette main.c ist im Anhang.
Falls relevant:
Wenn ich die Werte für die PWM in den Startbedingungen ändere passiert
genau was ich erwarte.
µC ist ein ATMega8 auf dem Pollin Eva-Board 2.0.1, Takt ist per Fuses
auf 8 MHz gestellt.
Vielen Dank schomal.
Ich vermute dass ich pwm_update(); nicht in der ISR aufrufen sollte,
aber auch wenn ich einfach ein Flag setze und dann in der while-Schleife
das Flag zurücksetze und pwm_update aufrufe klappt es nicht.
Vorsichtshalber habe ich mal den/die/das(?) Makefile angehangen.
Da man ja nicht editieren kann, hier ein weiterer Post mit einem Update.
Keine Compiler-Warnings mehr, gleiches Problem.
Schon wieder zu spät zum Editieren :-/
Habs hinbekommen. Ich habe keine Ahnung was noch falsch war, aber jetzt
gehts.
Jetzt muss ich das noch auf mehr Kanälen machen und schnellere und
kompliziertere Abläufe hinkriegen, mal gucken ob ich die Ideen aus
http://www.mikrocontroller.net/articles/LED-Fading umsetzen kann.
Hallo.
Ich habe mal weiter an dem Programm gestrickt und wieder ein Problem
gefunden, diesmal beim Anpassen des Beispielprogramms:
http://www.mikrocontroller.net/articles/Soft-PWM für mehr Kanäle (16
statt 8).
main.c ist im Anhang.
Das Problem ist, dass die beiden LEDs an PD5 und PD6 (Atmel EVA Board
2.0.1 von Pollin) jetzt zwar augenscheinlich ein Blinkmuster
wiederholen, dieses aber nicht den vorgegebenen Werten entspricht. Es
sieht eher nach wildem Blinken aus.
Mit 8 Kanälen funktioniert es
Ich würde mich wirklich über Hilfe freuen.
Grüße, Andi
Aktueller Quelltext im Anhang.
1 | #define PWM_PORT PORTB // Port für PWM
| 2 | #define PWM_PORT2 PORTD // Port für PWM
| 3 | #define PWM_DDR DDRB // Datenrichtungsregister für PWM
| 4 | #define PWM_DDR2 DDRD // Datenrichtungsregister für PWM
|
funktioniert augenscheinlich,
1 | #define PWM_PORT2 PORTB // Port für PWM
| 2 | #define PWM_PORT PORTD // Port für PWM
| 3 | #define PWM_DDR2 DDRB // Datenrichtungsregister für PWM
| 4 | #define PWM_DDR DDRD // Datenrichtungsregister für PWM
|
blinkt wild.
Vorkommen im Quelltext: 1 | PWM_PORT = (uint8_t)(tmp & 0x00FF); // Ports setzen zu Begin der PWM
| 2 | PWM_PORT2 = (uint8_t)((tmp >> 8) & 0x00FF); // zusätzliche PWM-Ports hier setzen
|
1 | PWM_PORT &= (uint8_t)(tmp & 0x00FF); // Ports löschen
| 2 | PWM_PORT2 &= (uint8_t)((tmp >> 8) & 0x00FF); // zusätzliche PWM-Ports hier setzen
|
1 | PWM_DDR = 0xFF;
| 2 | PWM_DDR2 = 0xFF;
|
Liegt es am Bit-Shift? Wenn ich das rausnehme blinkt er (oh Wunder) auch
mit den sonst funktionierenden Definitionen.
Oder schreibt er irgendeinen Mist in die Variablen?
Ist der Code den ich da gestrickt habe so langsam dass er sich
verheddert? (mit 30 FPS geht es auch nicht)
Passiert irgenwas komisches beim Sortieren wenn mehrere der Werte gleich
sind? Eigentlich ist dafür ja Aufräum-Code vorhanden...
1 | uint16_t pwm_setting[PWM_CHANNELS]; // Einstellungen für die einzelnen PWM-Kanäle
| 2 | uint16_t pwm_setting_tmp[PWM_CHANNELS+1]; // Einstellungen der PWM Werte, sortiert
| 3 | // ändern auf uint16_t für mehr als 8 Bit Auflösung
|
das sollten uint8_t sein, macht aber auch keinen Unterschied.
Ich verstehe jetzt einfach nicht, warum es nicht klappt:
- mit 8 Kanälen klappt es
- die Variablen deren Breite man ändern muss sind entsprechend
beschriftet
- die Breite der betroffenen Variablen ist geändert
- die Stellen an denen man die weiteren Ports/Kanäle definieren/setzen
muss sind beschriftet.
- der weitere Port/die weiteren Kanäle wurden hinzugefügt:
Andi M. schrieb:
> 1 | #define PWM_PORT PORTB // Port für PWM
| 2 | > #define PWM_PORT2 PORTD // Port für PWM
| 3 | > #define PWM_DDR DDRB // Datenrichtungsregister für
| 4 | > PWM
| 5 | > #define PWM_DDR2 DDRD // Datenrichtungsregister für
| 6 | > PWM
|
>
> 1 | > PWM_PORT = (uint8_t)(tmp & 0x00FF); //
| 2 | > Ports setzen zu Begin der PWM
| 3 | > PWM_PORT2 = (uint8_t)((tmp >> 8) & 0x00FF); //
| 4 | > zusätzliche PWM-Ports hier setzen
| 5 | >
|
> 1 | > PWM_PORT &= (uint8_t)(tmp & 0x00FF); //
| 2 | > Ports löschen
| 3 | > PWM_PORT2 &= (uint8_t)((tmp >> 8) & 0x00FF);
| 4 | > // zusätzliche PWM-Ports hier setzen
| 5 | >
|
> 1 | > PWM_DDR = 0xFF;
| 2 | > PWM_DDR2 = 0xFF;
| 3 | >
|
Wenn ich PWM_PORT2 auf die LEDs ausgebe siehts OK aus, wenn ich PWM_PORT
auf die LEDs ausgeben lasse blinken sie in einem Muster das dem
Erwartungswert nicht ganz unähnlich ist.
Was kann denn da kaputt sein?
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
|