Forum: Mikrocontroller und Digitale Elektronik ATmega32 uint32_t Problem


von cemizm (Gast)


Lesenswert?

Hallo Ihrs,

ich habe ein merkwürdiges Problem bei meinem kleinen Test Uhr Projekt.
Erstmal der Code dazu:
1
volatile unsigned long int seconds;
2
3
int main(void)
4
{
5
  seconds = 10; //Im Debugger wird immernoch 0 anezgeigt
6
  while(1)
7
  {
8
    if(seconds > 0) //trift nicht zu
9
      seconds--;
10
    
11
    seconds++; //keine Änderung.
12
  }
13
}

Das ist jetzt nicht mein Projekt aber ich habe im Zuge des debbugens ein 
neues Projekt zum lokalisieren des Problems erstellt.

Debugge ich den Code oben mit dem AVR-Simulator tut es genau was es 
soll. Seconds wird auf 10 gesetzt, in der Schleife trifft die Bedingung 
zu und es wird dekrementiert und im Anschluss wieder erhöht.

Wenn ich das ganze mit meinem Dragon auf dem STK500 debugge, ändert sich 
'seconds' nie.

Um ein Problem mit dem Dragon auszuschliessen habe ich auch ein Projekt 
erstellt bei dem eine LED aufleuchten sollte wenn 'seconds > 0'. Dies 
habe ich dann einfach per ISP übertragen, doch das Ergebnis ist das 
selbe.

Was mir aufgefallen ist wenn ich statt usinged long int einfach nur int 
nehme funktioniert das ganze wunderbar.

Wird hier irgendwas wegoptimiert oder hat der ATmega32 ein Problem mit 
dem uint32_t? Hier noch mal den Inhalt der .lss:
1
Test.elf:     file format elf32-avr
2
3
Sections:
4
Idx Name          Size      VMA       LMA       File off  Algn
5
  0 .text         000000ee  00000000  00000000  00000074  2**1
6
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
7
  1 .bss          00000004  00800060  00800060  00000162  2**0
8
                  ALLOC
9
  2 .debug_aranges 00000020  00000000  00000000  00000162  2**0
10
                  CONTENTS, READONLY, DEBUGGING
11
  3 .debug_pubnames 00000027  00000000  00000000  00000182  2**0
12
                  CONTENTS, READONLY, DEBUGGING
13
  4 .debug_info   00000063  00000000  00000000  000001a9  2**0
14
                  CONTENTS, READONLY, DEBUGGING
15
  5 .debug_abbrev 00000059  00000000  00000000  0000020c  2**0
16
                  CONTENTS, READONLY, DEBUGGING
17
  6 .debug_line   00000073  00000000  00000000  00000265  2**0
18
                  CONTENTS, READONLY, DEBUGGING
19
  7 .debug_frame  00000020  00000000  00000000  000002d8  2**2
20
                  CONTENTS, READONLY, DEBUGGING
21
  8 .debug_str    0000004d  00000000  00000000  000002f8  2**0
22
                  CONTENTS, READONLY, DEBUGGING
23
24
Disassembly of section .text:
25
26
00000000 <__vectors>:
27
   0:  0c 94 2a 00   jmp  0x54  ; 0x54 <__ctors_end>
28
   4:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
29
   8:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
30
   c:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
31
  10:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
32
  14:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
33
  18:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
34
  1c:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
35
  20:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
36
  24:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
37
  28:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
38
  2c:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
39
  30:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
40
  34:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
41
  38:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
42
  3c:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
43
  40:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
44
  44:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
45
  48:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
46
  4c:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
47
  50:  0c 94 3c 00   jmp  0x78  ; 0x78 <__bad_interrupt>
48
49
00000054 <__ctors_end>:
50
  54:  11 24         eor  r1, r1
51
  56:  1f be         out  0x3f, r1  ; 63
52
  58:  cf e5         ldi  r28, 0x5F  ; 95
53
  5a:  d8 e0         ldi  r29, 0x08  ; 8
54
  5c:  de bf         out  0x3e, r29  ; 62
55
  5e:  cd bf         out  0x3d, r28  ; 61
56
57
00000060 <__do_clear_bss>:
58
  60:  10 e0         ldi  r17, 0x00  ; 0
59
  62:  a0 e6         ldi  r26, 0x60  ; 96
60
  64:  b0 e0         ldi  r27, 0x00  ; 0
61
  66:  01 c0         rjmp  .+2        ; 0x6a <.do_clear_bss_start>
62
63
00000068 <.do_clear_bss_loop>:
64
  68:  1d 92         st  X+, r1
65
66
0000006a <.do_clear_bss_start>:
67
  6a:  a4 36         cpi  r26, 0x64  ; 100
68
  6c:  b1 07         cpc  r27, r17
69
  6e:  e1 f7         brne  .-8        ; 0x68 <.do_clear_bss_loop>
70
  70:  0e 94 3e 00   call  0x7c  ; 0x7c <main>
71
  74:  0c 94 75 00   jmp  0xea  ; 0xea <_exit>
72
73
00000078 <__bad_interrupt>:
74
  78:  0c 94 00 00   jmp  0  ; 0x0 <__vectors>
75
76
0000007c <main>:
77
78
volatile unsigned long int seconds;
79
80
int main(void)
81
{
82
  seconds = 10; //Im Debugger wird immernoch 0 anezgeigt
83
  7c:  8a e0         ldi  r24, 0x0A  ; 10
84
  7e:  90 e0         ldi  r25, 0x00  ; 0
85
  80:  a0 e0         ldi  r26, 0x00  ; 0
86
  82:  b0 e0         ldi  r27, 0x00  ; 0
87
  84:  80 93 60 00   sts  0x0060, r24
88
  88:  90 93 61 00   sts  0x0061, r25
89
  8c:  a0 93 62 00   sts  0x0062, r26
90
  90:  b0 93 63 00   sts  0x0063, r27
91
  while(1)
92
  {
93
    if(seconds > 0) //trift nicht zu
94
  94:  80 91 60 00   lds  r24, 0x0060
95
  98:  90 91 61 00   lds  r25, 0x0061
96
  9c:  a0 91 62 00   lds  r26, 0x0062
97
  a0:  b0 91 63 00   lds  r27, 0x0063
98
  a4:  00 97         sbiw  r24, 0x00  ; 0
99
  a6:  a1 05         cpc  r26, r1
100
  a8:  b1 05         cpc  r27, r1
101
  aa:  99 f0         breq  .+38       ; 0xd2 <main+0x56>
102
      seconds--;
103
  ac:  80 91 60 00   lds  r24, 0x0060
104
  b0:  90 91 61 00   lds  r25, 0x0061
105
  b4:  a0 91 62 00   lds  r26, 0x0062
106
  b8:  b0 91 63 00   lds  r27, 0x0063
107
  bc:  01 97         sbiw  r24, 0x01  ; 1
108
  be:  a1 09         sbc  r26, r1
109
  c0:  b1 09         sbc  r27, r1
110
  c2:  80 93 60 00   sts  0x0060, r24
111
  c6:  90 93 61 00   sts  0x0061, r25
112
  ca:  a0 93 62 00   sts  0x0062, r26
113
  ce:  b0 93 63 00   sts  0x0063, r27
114
    
115
    seconds++; //keine Änderung.
116
  d2:  80 91 60 00   lds  r24, 0x0060
117
  d6:  90 91 61 00   lds  r25, 0x0061
118
  da:  a0 91 62 00   lds  r26, 0x0062
119
  de:  b0 91 63 00   lds  r27, 0x0063
120
  e2:  01 96         adiw  r24, 0x01  ; 1
121
  e4:  a1 1d         adc  r26, r1
122
  e6:  b1 1d         adc  r27, r1
123
  e8:  cd cf         rjmp  .-102      ; 0x84 <main+0x8>
124
125
000000ea <_exit>:
126
  ea:  f8 94         cli
127
128
000000ec <__stop_program>:
129
  ec:  ff cf         rjmp  .-2        ; 0xec <__stop_program>

Ich kann leider (noch) kein Assembler aber vielleicht seht ihr ja was??

Gruß

von Julian B. (julinho)


Lesenswert?

Der assemblercode sieht etwas merkwürdig aus, die long int variable wird 
in die register r24-r27 geladen, r25 wird allerdings nie berücksichtigt.
Hast du schon mal verschiedene Optimierungsstufen getestet?

von Rolf Magnus (Gast)


Lesenswert?

Julian Baugatz schrieb:
> r25 wird allerdings nie berücksichtigt.

Doch, wird es. Hier z.B.:
1
  a4:  00 97         sbiw  r24, 0x00  ; 0
2
  a6:  a1 05         cpc  r26, r1
3
  a8:  b1 05         cpc  r27, r1

Die erste Instruktion (subtract immediate from word) subtrahiert 0 vom 
Registerpaar r24:r25, was die Registerwerte nicht ändert, aber die Flags 
wie bei einem Vergleich mit 0 setzt. Das spart eine Instruktion 
gegenüber einer Kombination aus einem cp und einem cpc. Danach wird dann 
noch ggf. ein Übertrag nach r26 und r27 weitergereicht (r1 wird vom 
Compiler als 0-Register verwendet).

Und auch hier:
1
  bc:  01 97         sbiw  r24, 0x01  ; 1
2
  be:  a1 09         sbc  r26, r1
3
  c0:  b1 09         sbc  r27, r1

Da wird in der ersten Instruktion das Registerpaar r24:r25 
dekrementiert.

Und hier das selbe Spiel beim Inkrementieren:
1
  e2:  01 96         adiw  r24, 0x01  ; 1
2
  e4:  a1 1d         adc  r26, r1
3
  e6:  b1 1d         adc  r27, r1

Also der Code sieht an sich korrekt aus.

von Thomas E. (thomase)


Lesenswert?

cemizm schrieb:
> Wenn ich das ganze mit meinem Dragon auf dem STK500 debugge, ändert sich
> 'seconds' nie.

Wieviele Breakpoints setzt du denn?

Wenn du einen Breakpoint auf ein "seconds" setzt, ändert sich nichts, 
weil die Programmschleife im Resultat nichts macht. Setzt du auf beide 
"seconds" in der Schleife jeweils einen Breakpoint, kannst du sehen, wie 
der Inhalt von "seconds" zwischen 10 (1. "second") und 9 (2."second") 
"pendelt".

Wenn dem nicht so ist, hat entweder dein STK500 oder dein Dragon 'ne
Macke oder das Programm wurde nicht richtig übertragen. Denn der Code 
ist richtig und macht genau, was er soll.

>>seconds = 10; //Im Debugger wird immernoch 0 anezgeigt
Daß hier "0" angezeigt wird, ist vollkommen richtig, da der Debugger das 
Programm VOR der Ausführung des Befehls anhält.

Aus dem gleichen Grund bekommst du hier
>>seconds--; "10" angezeigt.

usw.


mfg.

von cemizm (Gast)


Lesenswert?

Erstmal vielen Dank für die Hilfestellungen. Habe jetzt meinen AVR 
ausgetauscht und mit dem funktioniert es.

Hatte keinen Breakpoint gesetzt sondern zeilenweise debuggt und seconds 
im Watch gehabt.

Dennoch merkwürdig da der AVR sonst einwandfrei arbeitet??!

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.