Forum: Compiler & IDEs globale uint16_t Variable wird nur bis 8. Bit geschrieben


von Markus (Gast)


Lesenswert?

Hallo,

ich habe ein Problem. Ich möchte gerne eine globale volatile uint16_t 
Variable (g_time_sec) zum Datenaustausch zwischen ISR und Endlosschleife 
nutzen.
Der Wert wird beim Interrupt um 1 inkrementiert. Das Funktioniert auch 
bis 65536.
Später im Programm wird der Wert auf einen Default zurückgesetzt (2100).
In den RAM wird aber nur das letzte Byte geschrieben (52).
Wenn ich den default-Wert auf 257 setze steht im RAM 1. Die Variable 
wird also wie eine 8-Bit Variable behandelt, aber nicht beim 
inkrementieren.
im Ram ist die Variable übrigens auch 16 Bit lang.

1
#define F_CPU 16000000UL // 16,0000MHz
2
3
#include <avr/io.h>
4
#include <stdio.h>
5
#include <util/delay.h>
6
#include <avr/pgmspace.h>
7
#include <stdint.h>
8
#include <avr/interrupt.h>
9
...
10
volatile uint16_t g_time_sec = DEFAULT_TIME;
11
...
12
int main(void)
13
{
14
...
15
   while(1)
16
   {
17
      ...
18
      switch (g_state)
19
      {
20
      case STATE_STOPPED:
21
         g_time_sec = DEFAULT_TIME;
22
         g_speed_rph = 0;
23
         g_refresh_view = TRUE;
24
      break;
25
      case STATE_PAUSED:
26
         g_refresh_view = TRUE;
27
      break;
28
      case STATE_RUNNING:
29
         g_refresh_view = TRUE;
30
      break;
31
      }
32
      ...
33
   }
34
...
35
}

Der Mikrocontroller ist ein ATmega 2561.
Ich benutze Atmel Studio 6.1 mit folgender Toolchain:
Installed Packages: Atmel AVR (8 bit) GNU Toolchain - 3.4.2.1002
AVR Toolchain 8 Bit
Version: AVR8_Toolchain_Version:3.4.2.992 GCC_VERSION:4.7.2


mit einem volatile unsigned long int funktioniert es übrigens, aber ich 
wüsste gerne wieso es mit einem uint16_t nicht klappt und wer weiß was 
das noch für Seiteneffekte haben könnte.
Wenn ich die Variable mit einem Wert größer 256 initialisiere, wird 
dieser übrigens auch korrekt in den RAM geschrieben.
Ich habe auch schon versucht den Block atomar zu machen, aber das hat 
auch nicht geholfen.

von Karl H. (kbuchegg)


Lesenswert?

> In den RAM wird aber nur das letzte Byte geschrieben (52).

woher weißt du das?
Anzeige? Debugger?

Beim Debugger ist das was du siehst real. Bei 'Anzeige' könnte es auch 
ein Fehler in den Anzeigeroutinen sein.

von Karl H. (kbuchegg)


Lesenswert?

> Ich habe auch schon versucht den Block atomar zu machen, aber das hat auch nicht 
geholfen.

Das ist schon mal eine SPitzenidee.
Denn wenn dir die ISR dazwischenfunkt, während die Zuweisung läuft, dann 
hast du eine Mischung aus beiden Aktionen im uint16_t

von Markus (Gast)


Lesenswert?

Den RAM inhalt kenn ich vom debugger.  Es spricht aber auch dafür dass 
der Wer beim inkrementieren ja korrekt ist.

von Markus (Gast)


Lesenswert?

Markus schrieb:
> Den RAM inhalt kenn ich vom debugger.  Es spricht aber auch dafür
> dass
> der Wer beim inkrementieren ja korrekt ist.

Ich hatte da was falsch verstanden.
Den wert kenne ich vom debugger und einer anzeige.
Das problem habe ich übrigens auch bei lokalen uint16 variablen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Bei den ganzen ... im "Code" lässt sich das natürlich nicht 
nachvollziehen, denn der "Code" lässt sich nicht übersetzen.

Schau also ins Disassembly oder den vom Compiler erzeugten 
Assembler-Code. Wenn nur ein 8-Bit Zugriff erfolgt, ist es ein 
Compilerfehler. Ansonsten ist dein Problem in den ....

Darüber hinaus müssen die Zugriffe auf diese und ähnliche Variablen -- 
wie oben bereits angemerkt -- atomar gestaltet werden.

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.