Endlosschleife

#3282431
Lesenswert?

Hallo,

ich versuche gerade, einen PWM zu programmieren. Nur zu Testzwecken habe 
ich folgenden Codeabschnitt programmiert:
1
int main(void) {
2
  double X, Xold, Xp, Xd, P, D;
3

4
  P = 0.1;
5
  D = 60;
6

7
  DDRB = 0xff;
8
  PORTB = 0x00;
9
  
10
  ADMUX = (1<<REFS0);
11
  ADCSRA = (1<<ADEN)|(1<<ADPS2);
12

13
  TCCR0 = (1<<CS00);
14
  TIMSK = (1<<TOIE0);
15

16
  sei();
17

18

19
  while(1) {    
20
    pwm = 128;
21
...

Setze ich die lezte Zeile "pwm = 128" vor die while-Schleife, so 
funktioniert meine Regelung. In der while-Schleife aber nicht mehr.

Ich habe leider überhaupt keine Idee an was das liegen könnte.

Vielen Dank für eure Unterstützung! :)
Persönliche Seite #3282439
Lesenswert?

Kilian Herbst schrieb:
>   while(1) {
>     pwm = 128;
> ...
>
> Setze ich die lezte Zeile "pwm = 128" vor die while-Schleife, so
> funktioniert meine Regelung. In der while-Schleife aber nicht mehr.

Der Rest der while() wäre interessanter.

Dadurch dass die Zuweisung innerhalb der while() steht, wird der 
Variable "pwm" zu Beginn jedes Durchlaufes erneut der Wert 128 
zugewiesen. Vermutlich willst du aber eben diese Variable stetig ändern.
#3282448
Lesenswert?

Der Rest der while-Schleife:
1
    for(int i=0; i< 8;i++) {
2
      X =  X + ADC_Read();
3
    }
4
    X = X/8;
5
    if(X < 512) X = 512;
6
    Xp = X - 512;
7
    Xp = Xp * P;
8
    
9
    Xd = X - Xold;
10
    Xold = X;
11
    Xd = Xd * D;
12
  
13
    Y = Xp + Xd;
14
    Y = Y/2;
15
    
16
    if(Y > 255) Y = 255;
17
    if(Y < 0) Y = 0;

Den habe ich nicht mit gepostet, weil der an der Variable pwm nichts 
ändert. (soll er natürlich in der Endversion dann schon machen)

Wenn ich in die Main-Methode einfach nur pwm=128; schreibe, funktioniert 
es - die Leuchtdioden blinken also. Schreibe ich aber:
1
while(1) { pwm = 128;}

Dann geht gar nichts, die LEDs bleiben aus.
Gast #3282453
Lesenswert?

Kilian Herbst schrieb:
> Wenn ich in die Main-Methode einfach nur pwm=128; schreibe, funktioniert
> es - die Leuchtdioden blinken also. Schreibe ich aber:while(1) { pwm =
> 128;}
>
> Dann geht gar nichts, die LEDs bleiben aus.

wie wissen nicht wo PWM überhaupt verwendet wird. Wenn wir das nicht 
sehen das können wir nicht helfen.
Persönliche Seite #3282458
Lesenswert?

> while(1) { pwm = 128;}

Wenn du das so schreibst kein wunder, die Schleife wird
ja nie verlassen.

die PWN var taucht in deinem Codefragmentauch nicht wieder auf
und ist auch nirgentwo definiert/declariert.
Also auch unötig und kann wegbleiben.


Kilian Herbst schrieb:
> Der Rest der while-Schleife:

BITTE, den ganzen code, mit allen drum und dran. Keine Fragmente
oder einzelne Zeilen Stück für Stück preisgeben.
#3282486
Lesenswert?

Ok, hier der ganze Quelltext ;): Teilweise habe ich den aus dem 
avr-Tutorial genommen. Das mit dem int(main) habe ich hieraus:
http://www.kreatives-chaos.com/artikel/codeschnipsel-avr-gcc

Ich weiß, dass ADC_init() nicht aufgerufen wird, das sollte aber mein 
Problem nicht beeinträchtigen.
1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <stdlib.h>
4
#include <stdint.h>
5
#include <avr/interrupt.h>
6

7

8
uint8_t pwm = 0, cnt = 0;
9
uint16_t Y = 0;
10

11
void ADC_Init(void) {
12
 
13
  uint16_t result;
14
 
15
  // die Versorgungsspannung AVcc als Refernz wählen:
16
  ADMUX = (1<<REFS0);    
17
  // oder interne Referenzspannung als Referenz für den ADC wählen:
18
  // ADMUX = (1<<REFS1) | (1<<REFS0);
19
 
20
  // Bit ADFR ("free running") in ADCSRA steht beim Einschalten
21
  // schon auf 0, also single conversion
22
  ADCSRA = (1<<ADPS1) | (1<<ADPS0);     // Frequenzvorteiler
23
  ADCSRA |= (1<<ADEN);                  // ADC aktivieren
24
 
25
  /* nach Aktivieren des ADC wird ein "Dummy-Readout" empfohlen, man liest
26
     also einen Wert und verwirft diesen, um den ADC "warmlaufen zu lassen" */
27
 
28
  ADCSRA |= (1<<ADSC);                  // eine ADC-Wandlung 
29
  while (ADCSRA & (1<<ADSC) ) {         // auf Abschluss der Konvertierung 
30

31
warten
32
  }
33
  /* ADCW muss einmal gelesen werden, sonst wird Ergebnis der nächsten
34
     Wandlung nicht übernommen. */
35
  result = ADCW;
36
}
37

38
uint16_t ADC_Read()
39
{
40
  ADCSRA |= (1<<ADSC);            // eine Wandlung "single conversion"
41
  while (ADCSRA & (1<<ADSC) ) {   // auf Abschluss der Konvertierung warten
42
  }
43
  return ADCW;                    // ADC auslesen und zurückgeben
44
}
45

46
int main(void) {
47
  double X, Xold, Xp, Xd, P, D;
48

49
  P = 0.1;
50
  D = 60;
51

52
  DDRB = 0xff;
53
  PORTB = 0x00;
54
  
55
  ADMUX = (1<<REFS0);
56
  ADCSRA = (1<<ADEN)|(1<<ADPS2);
57

58
  TCCR0 = (1<<CS00);
59
  TIMSK = (1<<TOIE0);
60

61
  sei();
62

63
  while(1) {
64
                pwm = 128;
65
    for(int i=0; i< 8;i++) {
66
      X =  X + ADC_Read();
67
    }
68
    X = X/8;
69
    if(X < 512) X = 512;
70
    Xp = X - 512;
71
    Xp = Xp * P;
72
    
73
    Xd = X - Xold;
74
    Xold = X;
75
    Xd = Xd * D;
76
  
77
    Y = Xp + Xd;
78
    Y = Y/2;
79
    
80
    if(Y > 255) Y = 255;
81
    if(Y < 0) Y = 0;
82
  }
83

84
  return 0;
85
}
86

87
ISR (TIMER0_OVF_vect) {
88
  uint8_t temp = 0x00;
89
  cnt++;
90
  if(cnt == 0xff)
91
    cnt = 0;
92
  if(cnt < pwm)
93
    temp = 0xff;
94
  PORTB = temp;
95
}

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