Forum: Mikrocontroller und Digitale Elektronik Soft-PWM Version 3: Probleme beim Anpassen des Programms


von Andi M. (rootsquash)


Angehängte Dateien:

Lesenswert?

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.

von Andi M. (rootsquash)


Angehängte Dateien:

Lesenswert?

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.

von Andi M. (rootsquash)


Angehängte Dateien:

Lesenswert?

Da man ja nicht editieren kann, hier ein weiterer Post mit einem Update.
Keine Compiler-Warnings mehr, gleiches Problem.

von Andi M. (rootsquash)


Lesenswert?

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.

von Andi M. (rootsquash)


Angehängte Dateien:

Lesenswert?

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

von Andi M. (rootsquash)


Angehängte Dateien:

Lesenswert?

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

von Andi M. (rootsquash)


Lesenswert?

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.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.