Forum: PC-Programmierung AVRStudio, simpelste Vergleiche funktionieren nicht


von Jens F. (insanitaeter)


Lesenswert?

Hi,

mittlerweile bin ich am verzweifeln da nicht einmal mehr das einfachste 
Funktioniert.

Was soll es werden ? Ansteuerung einer RGB Led mit ATTINY, 3 Taster zur 
Steuerung.
Es gibt sicher bessere Wege eine PWM zu bauen aber nach 5 Stunden 
kopfzerbrechen und Umbauen ist nun das untenstehende bei herausgekommen.

Das Problem:
nachdem ich die meldung "Location not Valid" beim debuggen bekam bei der 
Variable "pwmchan0" wurde ich hier im Forum fündig das es wohl an der 
optimierung liegt. Nun gut ich verwende die Variable zwar aber eine 
deklaration als volatile hat so gesehen geholfen.
Der Vergleich
1
if(global_pwm >= pwmchan0)
wird nicht ausgeführt obwohl im debug nun beide variablen angezeigt 
werden und global_pwm nach dem 10. überlauf von Timer0 grösser ist. Die 
Anweisung wird einfach ignoriert.
Versucht habe ich das ganze schon auf mehreren Optimierungsstufen und es 
ist überall dasselbe problem.

1
#include <avr/io.h>
2
#include <util/delay.h>
3
#include <stdint.h>
4
#include <avr/interrupt.h>
5
#include <inttypes.h>
6
7
uint8_t global_pwm = 0;
8
9
ISR(TIM0_OVF_vect)
10
{
11
  
12
  global_pwm++;
13
  if(global_pwm >= 256)
14
  {
15
    global_pwm = 0;
16
  }
17
  
18
}
19
20
int main(void) 
21
{
22
  volatile uint8_t pwmchan0 = 10;
23
24
  DDRB  = 0x00;
25
  DDRB = 0b00000111;
26
27
  //Timer setzten TCCR0B
28
  TCCR0B = 0b000001;
29
  TIMSK0 |= (1 << TOIE0);
30
31
    sei();
32
  while(1)
33
  {
34
    if(global_pwm >= pwmchan0)
35
    {
36
      PORTB &= (1 << PORTB0);
37
    }
38
    else
39
    {
40
      PORTB |= (1 << PORTB0);
41
    }
42
  
43
  }
44
  return 0;
45
}

Wenn mir da jemand helfen kann wär ich echt dankbar !

Gruß

von Christian Erker (Gast)


Lesenswert?

globalPwm auch volatile setzen, da sie im Interrupt verändert wird. So 
geht der Compiler davon aus das sie innerhalb der while(1) konstant ist 
und damit auch das Ergebnis der if-Abfrage konstant und löst die 
if-Abfrage zur Compilezeit auf. Er weiss ja nichts vom Interrupt.

Gruß,
Christian

von unsigned byte (Gast)


Lesenswert?

Jens Fiedler schrieb:

...
> uint8_t global_pwm = 0;
...
>   global_pwm++;
>   if(global_pwm >= 256)
...

wird so nicht klappen, da global_pwm nur werte zwischen 0 und 255 
annehmen kann, niemals größer oder gleich 256. dismissed

von Jens F. (insanitaeter)


Lesenswert?

Da muss ich dir recht geben, war vorher ein int. Hab das jetzt schon so 
oft geändert das sich fehler einschleichen.
Trotzdem sollte dann ja global_pwm Werte bis 256 annehmen, und damit 
grösser gleich pwmchan0 werden oder nicht ?

von Karl H. (kbuchegg)


Lesenswert?

Jens Fiedler schrieb:
> Da muss ich dir recht geben, war vorher ein int. Hab das jetzt schon so
> oft geändert das sich fehler einschleichen.
> Trotzdem sollte dann ja global_pwm Werte bis 256 annehmen, und damit
> grösser gleich pwmchan0 werden oder nicht ?

größer gleich pwmchan0 schon.
Aber der Wert 256 wird nie auftauchen. Die größte Zahl, die in eine 8 
Bit Variable passt, ist nun mal 255. Größer geht nicht.

von Jens F. (insanitaeter)


Lesenswert?

Danke Christian !

Deinen Beitrag hab ich erst übersehen. Jetzt funktionierts !
Dann kann ich ja nun daran gehn die eigentliche routine zu 
implementieren. Dann flackert die led nicht mehr so :)

Ja das mit den 256 ist mir schon klar, war wie gesagt ein Fehler der bei 
der ganzen änderei passiert ist. Die Werte habe ich nun eh angepasst das 
sowas nicht mehr auftreten kann !

Danke an alle für die schnelle Hilfe zu später Stunde dank euch komm ich 
ja heut nacht doch noch weiter :)

von Εrnst B. (ernst)


Lesenswert?

Bevor du die Optimierung einschaltest, und danach nix mehr geht:

dein "volatile" ist falsch verteilt.
1
volatile uint8_t pwmchan0
wird nur aus main, nie aus der ISR verwendet => volatile überflüssig
1
uint8_t global_pwm
wird in der ISR verändert, in main gelesen => volatile o.ä. nötig.


PS: Du benutzt WINAVR, nicht nur AVRstudio.

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.