Soft-PWM Version 3: Probleme beim Anpassen des Programms

#2383538
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.
Angehängte Dateien:
#2393436
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
Angehängte Dateien:
#2393804
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...
Angehängte Dateien:
#2396288
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?

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren