Forum: Compiler & IDEs Komm net drauf :-(


von ghost (Gast)


Lesenswert?

Hi!

Hier mal mein Gesamtprogramm...

Ich habe noch nicht viel verändert, da ich mir über die Timer nicht ganz 
im klaren bin.

Müsste ich die Timer Einstellungen in die while(g_run) Schleife 
schreiben, damit sie erst beim Start anfangen zu zählen?

Und mach ich dann im Timeroverflow Interrupt eine Schleife die 
Hochzählt?

#include <avr/io.h>
#include <inttypes.h>
#include <avr/delay.h>      // definiert _delay_ms()
#include <avr/interrupt.h>
#include <util/delay.h>     // aktuelle Version in util
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef F_CPU
#define F_CPU 3686400UL     // Quarz mit 3.6864 Mhz ?? noch prüfen!!
#endif

#define true 1
#define false 0


// Funktion zum Entprellen
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
{
    if ( ! (*port & (1 << pin)) )
    {
        // Pin wurde auf Masse gezogen, 100ms warten
        _delay_ms(100);
        if ( *port & (1 << pin) )
        {
            // Anwender Zeit zum Loslassen des Tasters geben
            _delay_ms(100);
            return 1;
        }
    }
    return 0;
};


//---------------- Global variables ------------------------

char g_run; // Variable zum Stoppen
int g_count; // Zähler

// ---------------------------------------------------------

// --------------- Interrupt zum Umschalten von g_run ------
ISR(INT0_vect)
{
  // toggle
  g_run = false;
}

// --------------- Interrupt bei Timeroverflow --------------
ISR(TIMER1_OVF_vect)
{
  g_count = 0;
  g_count++;



int main(void)
{
  DDRD = 0x00; // Port D ist Eingang
  PORTD = 0xFF; // interne Pullup-Widerstände aktiviert

  DDRB = 0xFF; // Port B ist Ausgang
  PORTB = 0x00;
  EICRA |= (1<<ISC01); // Fallende Flanke löst Interrupt aus
  EIMSK |= (1<<INT0);

  TIMSK |= (1<<TOIE1); // Bei Überlauf des Datenregisters von Timer 1 
wird Timer Overflow 1 Interruot ausgelöst

  //Konfiguration von Timer 1
  TCCR1A = 0x00; // Timer 1 ohne Outputpins und ohne PWM
  TCCR1B |= (1<<CS12) | (1<<CS10); // CPU-Takt/ 1024


  sei(); // Interrupts eingeschaltet

  g_run = 1;

  while( ! debounce(&PIND, PD0) );    //Wenn Taster an PIN PD0 gedrueckt 
wird while verlassen.

  while(g_run == 1)
  {
    int i;
    long j;
    i = rand() % 20; // Generierung der "Pulsbreite"
    j = rand() % 20; // Generierung der Zeit zwischen zwei Pulsen
    j = j * 60000; // Umrechnung in Millisekunden
    _delay_ms(j); // Verzögerungszeit zwischen zwei Pulsen
    PORTB |= (1<<PB0); // PB0 auf high
    _delay_ms(i); // PB0 für 1-20 ms auf high
    PORTB &= ~ (1<<PB0); // PB0 wieder auf low
    PORTB |= (1<<PB1); // PB1 auf high
    _delay_ms(10); // PB1 immer für 10 ms auf high
    PORTB &= ~ (1<<PB1); // PB1 wieder auf low
  };


  cli(); // Interrupts ausgeschaltet

  while(1);
  return 0;
}

Danke für eure Hilfe...

von johnny.m (Gast)


Lesenswert?

> j = j * 60000; // Umrechnung in Millisekunden
> _delay_ms(j); // Verzögerungszeit zwischen zwei Pulsen
Hatten wir das nicht schon mal? Die _delay_xx-Funktionen funktionieren 
nur dann korrekt, wenn sie mit zur compile-Zeit bekannten Konstanten 
Werten aufgerufen werden und sie sind in Abhängigkeit von der 
CPU-Frequenz begrenzt!

> Und mach ich dann im Timeroverflow Interrupt eine Schleife die Hochzählt?
Zählschleifen haben in einer ISR eigentlich nichts verloren.

Was soll das Programm überhaupt machen? Warum postest Du sowas nicht in 
Deinem originalen Thread? Dann müsste man sich jetzt nicht den anderen 
Thread raussuchen um zu erfahren worum es eigentlich geht!

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Außerdem fehlt mindestens bei g_run auf jeden Fall das "volatile".

von Falk (Gast)


Lesenswert?

@ ghost

>Hier mal mein Gesamtprogramm...

Aha, es geht immer noch um die 1..20 min Verzögerung zur LED-Ansteuerung

>Und mach ich dann im Timeroverflow Interrupt eine Schleife die
>Hochzählt?

Nö.

>#define true 1
>#define false 0

Das kannst du dir sparen.

>// --------------- Interrupt bei Timeroverflow --------------
>ISR(TIMER1_OVF_vect)
>{
>  g_count = 0;
>  g_count++;

} fehlt hier

Die Initialisierung sieht mal gut aus. Dein Main läuft dann eigentlich 
nur noch in einer Endlosschleife etwas so

while(1);

Die Schow findet im Interrupt statt.

// --------------- Interrupt bei Timeroverflow --------------
ISR(TIMER1_OVF_vect)
{
  static uin16_t i, j;
  static uin8_t state=0;

  switch (state)
  {
   case 0:        // start, get new random values
      i = rand() % 20;   // Generierung der "Pulsbreite"
      j = rand() % 20;   // Generierung der Zeit zwischen zwei Pulsen
      j = j * 60000;     // Umrechnung in Millisekunden
      state = 1;
    break;

   case 1:        // first delay
      j--;
    if (j==0) state =2;
    break;

   case 2:        // first LED action
      PORTB |= (1<<PB0); // PB0 auf high
    state =3;
    break;

   case 3:        // second delay
      i--;
    if (i==0) state =4;
    break;

   case 4:        // second LED action
      PORTB &= ~ (1<<PB0); // PB0 wieder auf low
      PORTB |= (1<<PB1); // PB1 auf high
    state =5;
      i = 10;
    break;

   case 5:        // second delay
      i--;
    if (i==0) state =6;
    break;

   case 6:        // third LED action
      PORTB &= ~ (1<<PB1); // PB1 wieder auf low
    state =0;
    break;

  default: state = 0;      // just in case ;-)
  }
}

MfG
Falk

von Jupp (Gast)


Lesenswert?

>> #define true 1
>> #define false 0

> Das kannst du dir sparen.

Nö.

#define TRUE 1
#define FALSE 0

könnte er sich sparen.


von Falk (Gast)


Lesenswert?

@ Jupp

>>> #define true 1
>>> #define false 0

>> Das kannst du dir sparen.

>Nö.

>#define TRUE 1
>#define FALSE 0

>könnte er sich sparen.

Warum muss ich da gerade wieder an eine griechische Stadt mit K und den 
Auswurf von Exkrementen denken . . .?

MFG
Falk


von ghost (Gast)


Lesenswert?

@Falk

Merci, sowas hab ich gesucht.

von Falk (Gast)


Lesenswert?

@ ghost

>Merci, sowas hab ich gesucht.

Ich hoffe du verstehst auch den Unterschied?

MFG
Falk


von ghost (Gast)


Lesenswert?

>Ich hoffe du verstehst auch den Unterschied?

Ich denke schon.

Der Compiler scheint nur die zwei Zeilen net zu mögen:

  static uin16_t i, j;
  static uin8_t state=0;

main.c:53: error: expected '=', ',', ';', 'asm' or '__attribute__' 
before 'i'
main.c:53: error: 'i' undeclared (first use in this function)
main.c:53: error: (Each undeclared identifier is reported only once
main.c:53: error: for each function it appears in.)
main.c:53: error: 'j' undeclared (first use in this function)
main.c:53: warning: left-hand operand of comma expression has no effect
main.c:53: warning: statement with no effect
main.c:56: error: 'state' undeclared (first use in this function
)

von Karl H. (kbuchegg)


Lesenswert?

ghost wrote:
>>Ich hoffe du verstehst auch den Unterschied?
>
> Ich denke schon.
>
> Der Compiler scheint nur die zwei Zeilen net zu mögen:
>
>   static uin16_t i, j;
>   static uin8_t state=0;
>
> main.c:53: error: expected '=', ',', ';', 'asm' or '__attribute__'
> before 'i'

mach noch ein
#include <stdint.h>
ganz an den Anfang.

Der Compiler weiss nicht was ein uint16_t ist. stdint.h
enthält die dazu notwendigen Definitionen.

von johnny.m (Gast)


Lesenswert?

Da fehlen ja auch zwei 't'! uin8_t und uin16_t findet er sicher auch mit 
der stdint.h nicht...

von Falk (Gast)


Lesenswert?

@ johnny.m

>Da fehlen ja auch zwei 't'! uin8_t und uin16_t findet er sicher auch mit
>der stdint.h nicht...

Ich sach nur Licherkette. An alle Badesalz-Fans ;-)

MFG
Falk


von johnny.m (Gast)


Lesenswert?

> ...Licherkette...
Ne Krombacherkette wär mir lieber...

von ghost (Gast)


Lesenswert?

So schaut jetzt main() aus:

int main(void)
{
  DDRD = 0x00; // Port D ist Eingang
  PORTD = 0xFF; // interne Pullup-Widerstände aktiviert

  DDRB = 0xFF; // Port B ist Ausgang
  PORTB = 0x00;

  // ------- Einstellungen für Ext. Interrupt zum Stoppen des Programms 
----
  EICRA |= (1<<ISC01); // Fallende Flanke löst Interrupt aus
  EIMSK |= (1<<INT0);
  // 
-----------------------------------------------------------------------


  TIMSK1 |= (1<<TOIE1); // Bei Überlauf des Datenregisters von Timer 1 
wird Timer Overflow 1 Interrupt ausgelöst

  //Konfiguration von Timer 1
  TCCR1A = 0x00; // Timer 1 ohne Outputpins und ohne PWM
  TCCR1B |= (1<<CS12) | (1<<CS10); // 3,6864MHZ/ 1024 = 3600 Hz


  sei(); // Interrupts eingeschaltet

  g_run = 1;

  while( ! debounce(&PIND, PD0) );    //Wenn Taster an PIN PD0 gedrueckt 
wird, wird while verlassen

  cli(); // Interrupts ausgeschaltet

  while(1);
  return 0;
}

Ich habe in switch mal i recht groß gemacht um ein Blinken zu sehen, 
aber es tut sich nix. Hab ich in main noch nen groben Bock drin??

von Karl H. (kbuchegg)


Lesenswert?

ghost wrote:
> So schaut jetzt main() aus:

...

>
>   sei(); // Interrupts eingeschaltet
>
>   g_run = 1;
>
>   while( ! debounce(&PIND, PD0) );    //Wenn Taster an PIN PD0 gedrueckt
> wird, wird while verlassen
>
>   cli(); // Interrupts ausgeschaltet
>
>   while(1);
>   return 0;
> }

Wenn du mittels cli() die Interrupts global ausschaltest, kannst
du lange warten, bis ein Overflow Interrupt durchkommt. Die
eigentliche Arbeit wird während

   while(1)
     ;

im Hintergrund von einer ISR (Interrupt Service Routine) erledigt.
Die muss aber auch aufgerufen werden können! Das kann sie aber
nicht, wenn du mittels cli() die Interrupts sperrst.

von Regler (Gast)


Lesenswert?

@Falk

>Warum muss ich da gerade wieder an eine griechische Stadt mit K und den
>Auswurf von Exkrementen denken . . .?

Keine Ahnung, vielleicht hast du ein Problem mit deiner Verdauung?

Wie auch immer, ich wollte es nur klarstellen, denn ich hasse 
Halbwissen, welches du hier gezeigt hast. LOL


von ghost (Gast)


Lesenswert?

Also irgendwie funzt es net so wie ich will.

Das Programm soll nach 1- 20 Minuten einen Pin für ca 10 ms auf high 
legen und dann wieder auf low. Sofort danach einen anderen Pin auf high 
für ca 10 ms und dann wieder auf low. Und das ganze halt immer wieder 
bis man stoppen will.

Und halt noch ne Stop-Taste, die aber schon funktioniert ( mit dem 
externen interrupt).

Der Vorschlag von Falk ist ja ok, aber da muss ich doch irgendwie noch 
meine Frequenz anpassen? Könnte da der Fehler liegen?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Regler wrote:

> Wie auch immer, ich wollte es nur klarstellen, denn ich hasse
> Halbwissen, welches du hier gezeigt hast. LOL

Du meinst, solcherart wie du gerade zur Schau stellst?  (Falls Regler
derselbe wie Yupp sein sollte.)

Guck dir mal <stdbool.h> von C99 an.

von Regler (Gast)


Lesenswert?

Tja, dann muß ich das wohl zurücknehmen.

Dennoch ist es schon bescheuert, dass einerseits in der von dir 
genannten Datei

#define true 1
#define false 0

auftaucht, man aber andererseits ohne die Inkludierung dieser Datei

#define TRUE 1
#define FALSE 0

definiert wurde, wo auch immer. Frei nach dem Motto: doppelt gemoppelt 
hält besser.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Regler wrote:

> auftaucht, man aber andererseits ohne die Inkludierung dieser Datei
>
> #define TRUE 1
> #define FALSE 0
>
> definiert wurde, wo auch immer.

Wo denn?  Bei mir nicht.  Keine der avr-libc- oder GCC-Headerdateien
bringt das mit.
1
$ cat foo.c
2
#include <avr/io.h>
3
4
int
5
main(void)
6
{
7
        return TRUE;
8
}
9
$ avr-gcc -mmcu=atmega1281 -c foo.c
10
foo.c: In function 'main':
11
foo.c:6: error: 'TRUE' undeclared (first use in this function)
12
foo.c:6: error: (Each undeclared identifier is reported only once
13
foo.c:6: error: for each function it appears in.)

von ghost (Gast)


Lesenswert?

Hab des Programm jetzt so geschrieben:

#include <avr/io.h>
#include <inttypes.h>
#include <avr/delay.h>      // definiert _delay_ms()
#include <avr/interrupt.h>
#include <util/delay.h>     // aktuelle Version in util
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#ifndef F_CPU
#define F_CPU 3686400UL     // Quarz mit 3.6864 Mhz ?? noch prüfen!!
#endif

#define true 1
#define false 0


// -------- Funktion zum Entprellen --------------------------
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
{
    if ( ! (*port & (1 << pin)) )
    {
        // Pin wurde auf Masse gezogen, 100ms warten
        _delay_ms(100);
        if ( *port & (1 << pin) )
        {
            // Anwender Zeit zum Loslassen des Tasters geben
            _delay_ms(100);
            return 1;
        }
    }
    return 0;
};


//---------------- Global variables ------------------------

char g_run; // Variable zum Stoppen

// ---------------------------------------------------------

// --------------- Interrupt zum Umschalten von g_run ------
ISR(INT0_vect)
{
  // toggle
  g_run = false;
}

// --------------- Interrupt bei Timeroverflow --------------
ISR(TIMER1_OVF_vect)
{
  static uint16_t i, j;
  static uint8_t state=0;

  switch (state)
  {
    case 0:        // Start, Erzeugung der neuen Zufallszahlen
    i = rand() % 20;   // Generierung der "Pulsbreite"
    j = rand() % 20;   // Generierung der Zeit zwischen zwei Pulsen
    j = j * 60000;     // Umrechnung in Millisekunden

    state = 1;
    break;

    case 1:        // Erste Verzögerung: 1 - 20 Minuten
    j--;
    if (j==0) state =2;
    break;

    case 2:
    PORTB |= (1<<PB0); // PB0 auf high
    state =3;
    break;

    case 3:        // Verzögerung 1 - 20 ms
    i--;
    if (i==0) state =4;
    break;

    case 4:
    PORTB &= ~ (1<<PB0); // PB0 wieder auf low
    PORTB |= (1<<PB1); // PB1 auf high
    state =5;
    i = 10;
    break;

    case 5:        // 10ms Verzögerung
    i--;
    if (i==0) state =6;
    break;

    case 6:
    PORTB &= ~ (1<<PB1); // PB1 wieder auf low
    state =0;
    break;

    default: state = 0;
  }
}


int main(void)
{
  DDRD = 0x00; // Port D ist Eingang
  PORTD = 0xFF; // interne Pullup-Widerstände aktiviert

  DDRB = 0xFF; // Port B ist Ausgang
  PORTB = 0xFC;

  // ------- Einstellungen für Ext. Interrupt zum Stoppen des Programms 
----
  EICRA |= (1<<ISC01); // Fallende Flanke löst Interrupt aus
  EIMSK |= (1<<INT0);
  // 
-----------------------------------------------------------------------
  sei(); // Interrupts eingeschaltet

  g_run = 1;
  while( ! debounce(&PIND, PD0) );    //Wenn Taster an PIN PD0 gedrueckt 
wird, wird while verlassen
  while(g_run == 1)
  {
  TIMSK1 |= (1<<TOIE1); // Bei Überlauf des Datenregisters von Timer 1 
wird Timer Overflow 1 Interrupt ausgelöst

  //Konfiguration von Timer 1
  TCCR1A = 0x00; // Timer 1 ohne Outputpins und ohne PWM
  TCCR1B |= (1<<CS12) | (1<<CS10); // 3,6864MHZ/ 1024 = 3600 Hz




  };



  while(1);
  return 0;
}

Jetzt sollte es doch eigentlich beim drücken des Tasters an Pin PD0 
starten und solange durchlaufen bis ich den externen Interrupt durch 
drücken des Tasters an PD2 auslöse.

Das ganze ist ein kleines Teil für meine BA und sollte mich eigentlich 
nicht zu lange damit aufhalten ( auch wenn ich das Programmieren schon 
interessant finde...)

Habe ich evtl. den Overflow Vektor falsch gewählt? Oder noch ein 
Register falsch belegt?

von Karl H. (kbuchegg)


Lesenswert?

ghost wrote:

> Habe ich evtl. den Overflow Vektor falsch gewählt? Oder noch ein
> Register falsch belegt?

Schmeiss mal das ganze Gerödel mit deinen Tastern raus.
Da blickt doch keiner mehr durch.

Halte dich an das einfache Schema:

int main()
{

   alles initialisieren

   //
   // Endlosschleife und den Timer Interrupt
   // machen lassen
   //
   while(1)
     ;
}

Dazu packst du dann noch die ISR und alles was an globalen
Variablen dazugehört. Dann setzt du den Vorteiler für
den Timer mal auf 1 (*) und gehst mit dem Ganzen in den Simulator
zum durchdebuggen.


(*) 1 deswegen, damit du dir im Simulator keinen Wolf auf der
F10 Taste tippst um den Timerwert um 1 zu erhöhen.

von Falk (Gast)


Lesenswert?

@ ghost

Deine Programmierkenntnisse sind wohl schon ein wenig arg rostig, was?

int main(void)
{
  DDRD = 0x00; // Port D ist Eingang
  PORTD = 0xFF; // interne Pullup-Widerstände aktiviert

  DDRB = 0xFF; // Port B ist Ausgang
  PORTB = 0xFC;

  // ------- Einstellungen für Ext. Interrupt zum Stoppen des Programms
----
  EICRA |= (1<<ISC01); // Fallende Flanke löst Interrupt aus
  EIMSK |= (1<<INT0);
  //

  TIMSK1 |= (1<<TOIE1); // Bei Überlauf des Datenregisters von Timer 1
wird Timer Overflow 1 Interrupt ausgelöst

  //Konfiguration von Timer 1
  TCCR1A = 0x00; // Timer 1 ohne Outputpins und ohne PWM
  TCCR1B |= (1<<CS12) | (1<<CS10); // 3,6864MHZ/ 1024 = 3600 Hz

// sämtliche Konfiguration VOR das Aktivieren der Interrupts
-----------------------------------------------------------------------
  sei(); // Interrupts eingeschaltet

  g_run = 1;
  while( ! debounce(&PIND, PD0) );    //Wenn Taster an PIN PD0 gedrueckt
wird, wird while verlassen

  while(g_run == 1);      // Endlosschleife, bis durch INT0 G_run false 
wird, das Semikolon ist wichtig!

  cli();            // alle Interrupts, aus, das wars
  while(1);            // bis zum Sant Nimmerleinstag
}

>Habe ich evtl. den Overflow Vektor falsch gewählt? Oder noch ein
>Register falsch belegt?

Nur kleinere logische Schwächen ;-). Die Interrupts hast du nicht 
wirklich kapiert, oder?
Ausserdem musst du noch die Multiplikatoren anpassen, bei ~3600 Hz 
Timertakt ist deine Überlauf (=Interrupt)freqeunz 3600/256 ~14 Hz, 
sprich 71ms. Das ist dein Zeitraster.

MfG
Falk




von ghost (Gast)


Lesenswert?

Hab mittlerweile das Programm nochmal neu geschrieben. Jetzt 
funktioniert eigentlich alles so wie es soll. Nur mit dem externen 
Interrupt klappt es net so gut.

Wenn in der ISR meine globale Variable g_run = 0 gesetzt wird, sollte 
mein programm die while(g_run == 1) schleife verlassen und in die 
while(1) schleife laufen. Dann dürfte aber eigentlich nichts mehr 
passieren, oder? weil bei mir die testLEDs weiterhin blinken...

von Falk B. (falk)


Lesenswert?

Aktueller Sourcecode?

MFG
Falk

von ghost (Gast)


Lesenswert?

#include <avr/io.h>
#include <inttypes.h>
#include <avr/delay.h>      // definiert _delay_ms()
#include <avr/interrupt.h>
#include <util/delay.h>     // aktuelle Version in util
#include <stdio.h>
#include <stdio.h>
#include <stdlib.h>
#ifndef F_CPU
#define F_CPU 3686400UL     // Quarz mit 3.6864 Mhz ?? noch prüfen!!
#endif


// Funktion zum Entprellen
inline uint8_t debounce(volatile uint8_t *port, uint8_t pin)
{
    if ( ! (*port & (1 << pin)) )
    {
        // Pin wurde auf Masse gezogen, 100ms warten
        _delay_ms(100);
        if ( *port & (1 << pin) )
        {
            // Anwender Zeit zum Loslassen des Tasters geben
            _delay_ms(100);
            return 1;
        }
    }
    return 0;
};


//---------------- Global variables ------------------------

// Variable zum Stoppen
char g_run;

// ---------------------------------------------------------

// --------------- Interrupt zum Umschalten von g_run ------
ISR(INT0_vect) // Externer Interrupt beim Drücken von Taster an PD2
{
  // toggle
  g_run = 0;
}

int main(void)
{
  DDRD = 0x00; // Port D ist Eingang
  PORTD = 0xFF; // interne Pullup-Widerstände aktiviert

  DDRB |= (1<<DDB0) | (1<<DDB1); // Pin 0 und 1 von Port B als Ausgang 
definiert
  PORTB = 0x00;
  EICRA |= (1<<ISC01); // fallende Flanke löst Interrupt aus
  EIMSK |= (1<<INT0);

  sei(); // Interrupts eingeschaltet

  g_run = 1;

  while( ! debounce(&PIND, PD0) );    //Wenn Taster an PIN PD0 gedrueckt 
wird while verlassen.

  while(g_run == 1)
  {

    _delay_ms(60);

    PORTB |= (1<<PB0); // PB0 auf high
    _delay_ms(10); // PB0 für 10 ms auf high
    PORTB &= ~ (1<<PB0); // PB0 wieder auf low
    PORTB |= (1<<PB1); // PB1 auf high
    _delay_ms(10); // PB1 immer für 10 ms auf high
    PORTB &= ~ (1<<PB1); // PB1 wieder auf low
  };

  while(1);
  return 0;
}

von Falk B. (falk)


Lesenswert?

@ ghost

>Wenn in der ISR meine globale Variable g_run = 0 gesetzt wird, sollte
>mein programm die while(g_run == 1) schleife verlassen und in die
>while(1) schleife laufen. Dann dürfte aber eigentlich nichts mehr
>passieren, oder?

Ja.

Aber erstzte mal

char g_run;

durch

volatile char g_run;

> weil bei mir die testLEDs weiterhin blinken...

Dann wird dein Interrupt nicht ausgeführt. Hast du deinen 2. Taster, 
welcher den Interrupt auslösen soll auch and PD2 angeschlossen?.

MFG
Falk


von ghost (Gast)


Lesenswert?

hab das mit volatile grad selber bei AVR freaks gefunden...

jetzt klappt es. volatile heißt also, dass der wert global also auch in 
main geändert wird oder? dacht immer das macht eine globale variable 
sowieso??

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

ghost wrote:

> volatile heißt also, dass der wert global also auch in
> main geändert wird oder? dacht immer das macht eine globale variable
> sowieso?

Das macht eine globale Variable immer, ja.

`volatile' besagt, dass der Compiler den Code so schreiben muss, dass
an einem sogenannten sequence point der Inhalt der Variablen auch
tatsächlich dem Ergebnis entsprechend der abstrakten Maschine
entsprechen soll.  In freier Übersetzung bedeutet das etwa so viel
wie, dass er jegliche Zugriffsoptimierung auf derartige Variablen
sein lassen soll.

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.