Forum: Compiler & IDEs Probleme mit _delay_ AVR Atmel32


von Chris G. (kamp79)


Lesenswert?

Hallo, ich arbeite mich gerade erst in C und der 
Microcontrollerprogrammierung ein und habe das Problem, dass der 
Controller bei delay stehen bleibt und ich finde den Fehler einfach 
nicht.
Ich arbeite mit AtmelStudio 6.2

#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>


int main()
{

  DDRB = 255;

    while(1)
    {
         PORTB = 0b00001111;
   _delay_ms(200);
   PORTB = 0b11110000;
   _delay_ms(200);

  }

}

von Jim M. (turboj)


Lesenswert?

Ist die Optimierung eingeschaltet?

von Chris G. (kamp79)


Lesenswert?

Sorry, aber ich muss leider ganz dumm Fragen, welche Optimierung?

von M. S. (elpaco)


Lesenswert?

Es könnte sein, dass deine Frequenz hier falsch eingestellt ist, da 
standardmäßig ein Prescaler von 8 per Fusebit gesetzt ist. Das würde 
aber nur die Dauer des delay verachtfachen. Ansonsten könnte ein Fehler 
in der Schaltung dazu führen, dass dein Controller einen Reset bekommt 
und daher den Teil nach dem Delay nie erreicht bevor er resettet.

von Chris G. (kamp79)


Lesenswert?

Danke, aber die Schaltung ist ok, denke es liegt wirklich an der 
Optimierung, ich weiß nur leider noch nicht, wo ich die Abschalten 
kann!?

von Thomas E. (thomase)


Lesenswert?

Chris G. schrieb:
> Danke, aber die Schaltung ist ok, denke es liegt wirklich an der
> Optimierung, ich weiß nur leider noch nicht, wo ich die Abschalten
> kann!?

Du sollst die Optimierung nicht abschalten, sondern ggf. einschalten. 
Diese ist allerdings per default eingeschaltet. Ausserdem gibt es eine 
Warnung von der delay.h wenn die Optimierung nicht eingeschaltet ist. 
Wenn es keine Warnung gibt, kümmere dich also nicht darum.

Wie sind die Fuses eingestellt?
Und zeig deine Schaltung. Dass die OK ist, behauptet hier ausnahmslos 
jeder, bei dem eine LED nicht wie gewünscht blinkt.

Welcher Programmer? Vielleicht mag der das nicht wenn die Ports an denen 
er angeschlossen ist, auf Ausgang geschaltet werden. Dazu muss man aber 
wissen, ob das ein vernünftiger oder irgendein Gurkentool ist.

mfg.

: Bearbeitet durch User
von Chris G. (kamp79)


Lesenswert?

Ich habs außer mit der Schaltung auch mit dem AVR Simulator IDE versucht 
un das Ergebnis ist gleich.

Wo könnte ich die Optimierung denn abschalten? (nur zum testen)

von Thomas E. (thomase)


Lesenswert?

Chris G. schrieb:
> (nur zum testen)

Was willst du damit testen? Die Optimierung MUSS eingeschaltet sein, 
sonst funktioniert 'delay' nicht. Ist sie nicht eingeschaltet, bekommst 
du eine Warnung. Kompiliert dein Programm ohne Warnungen? Und zwar beim 
ersten Kompilieren, nachdem du etwas geändert hast. Nochmal kompilieren 
und sich freuen, dass die Warnungen dann weg sind, zählt nicht!

Das mit abgeschalteter Optimierung zu testen, ist das Gleiche als wenn 
bei deinem Fahrrad die Kette abgelaufen ist und du lässt hinten die Luft 
aus dem Reifen, in der Hoffnung, dass es dann wieder fährt.

Die Optimierung wird hier zwar ständig als Schlagwort in den Raum 
geworfen, ist aber äusserst selten der Grund für irgendwelche Fehler.

Kompilierst du für den richtigen Controller?

mfg.

: Bearbeitet durch User
von Chris G. (kamp79)


Lesenswert?

Ok danke, verstanden.
Beim complimieren bekomme ich weder Fehler, noch Warnungen.

Ich habe den ATmega32 ausgewählt, von daher denke ich, dass der Compiler 
entsprechend arbeitet...

von Chris G. (kamp79)


Lesenswert?

Der Debugger/Simulator reagiert übrigens genauso wie der AVR Simulator 
IDE und wenn ich den Breakpoint unter delay setzte, bekomme ich den 
Hinweis, dass dieser Punkt nicht erreicht werden kann...

von Thomas E. (thomase)


Lesenswert?

Chris G. schrieb:
> Ich habe den ATmega32 ausgewählt, von daher denke ich, dass der Compiler
> entsprechend arbeitet...
Zeig mal das .lss File.

mfg.

von Chris G. (kamp79)


Lesenswert?

Blinken.elf:     file format elf32-avr

Sections:
Idx Name          Size      VMA       LMA       File off  Algn
  0 .text         000000a2  00000000  00000000  00000074  2**1
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
  1 .data         00000000  00800060  000000a2  00000116  2**0
                  CONTENTS, ALLOC, LOAD, DATA
  2 .comment      00000030  00000000  00000000  00000116  2**0
                  CONTENTS, READONLY
  3 .debug_aranges 00000020  00000000  00000000  00000146  2**0
                  CONTENTS, READONLY, DEBUGGING
  4 .debug_info   00000144  00000000  00000000  00000166  2**0
                  CONTENTS, READONLY, DEBUGGING
  5 .debug_abbrev 000000d1  00000000  00000000  000002aa  2**0
                  CONTENTS, READONLY, DEBUGGING
  6 .debug_line   0000013b  00000000  00000000  0000037b  2**0
                  CONTENTS, READONLY, DEBUGGING
  7 .debug_frame  00000024  00000000  00000000  000004b8  2**2
                  CONTENTS, READONLY, DEBUGGING
  8 .debug_str    00000171  00000000  00000000  000004dc  2**0
                  CONTENTS, READONLY, DEBUGGING
  9 .debug_ranges 00000010  00000000  00000000  0000064d  2**0
                  CONTENTS, READONLY, DEBUGGING

Disassembly of section .text:

00000000 <__vectors>:
   0:  0c 94 2a 00   jmp  0x54  ; 0x54 <__ctors_end>
   4:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
   8:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
   c:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  10:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  14:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  18:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  1c:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  20:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  24:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  28:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  2c:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  30:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  34:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  38:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  3c:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  40:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  44:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  48:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  4c:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>
  50:  0c 94 34 00   jmp  0x68  ; 0x68 <__bad_interrupt>

00000054 <__ctors_end>:
  54:  11 24         eor  r1, r1
  56:  1f be         out  0x3f, r1  ; 63
  58:  cf e5         ldi  r28, 0x5F  ; 95
  5a:  d8 e0         ldi  r29, 0x08  ; 8
  5c:  de bf         out  0x3e, r29  ; 62
  5e:  cd bf         out  0x3d, r28  ; 61
  60:  0e 94 36 00   call  0x6c  ; 0x6c <main>
  64:  0c 94 4f 00   jmp  0x9e  ; 0x9e <_exit>

00000068 <__bad_interrupt>:
  68:  0c 94 00 00   jmp  0  ; 0x0 <__vectors>

0000006c <main>:


int main()
{

  DDRB = 255;
  6c:  8f ef         ldi  r24, 0xFF  ; 255
  6e:  87 bb         out  0x17, r24  ; 23

    while(1)
    {
     PORTB = 0b00001111;
  70:  9f e0         ldi  r25, 0x0F  ; 15
   _delay_ms(200);
   PORTB = 0b11110000;
  72:  80 ef         ldi  r24, 0xF0  ; 240

  DDRB = 255;

    while(1)
    {
     PORTB = 0b00001111;
  74:  98 bb         out  0x18, r25  ; 24
  #else
    //round up by default
    __ticks_dc = (uint32_t)(ceil(fabs(__tmp)));
  #endif

  __builtin_avr_delay_cycles(__ticks_dc);
  76:  2f ef         ldi  r18, 0xFF  ; 255
  78:  31 ee         ldi  r19, 0xE1  ; 225
  7a:  44 e0         ldi  r20, 0x04  ; 4
  7c:  21 50         subi  r18, 0x01  ; 1
  7e:  30 40         sbci  r19, 0x00  ; 0
  80:  40 40         sbci  r20, 0x00  ; 0
  82:  e1 f7         brne  .-8        ; 0x7c <main+0x10>
  84:  00 c0         rjmp  .+0        ; 0x86 <main+0x1a>
  86:  00 00         nop
   _delay_ms(200);
   PORTB = 0b11110000;
  88:  88 bb         out  0x18, r24  ; 24
  8a:  2f ef         ldi  r18, 0xFF  ; 255
  8c:  31 ee         ldi  r19, 0xE1  ; 225
  8e:  44 e0         ldi  r20, 0x04  ; 4
  90:  21 50         subi  r18, 0x01  ; 1
  92:  30 40         sbci  r19, 0x00  ; 0
  94:  40 40         sbci  r20, 0x00  ; 0
  96:  e1 f7         brne  .-8        ; 0x90 <main+0x24>
  98:  00 c0         rjmp  .+0        ; 0x9a <main+0x2e>
  9a:  00 00         nop
  9c:  eb cf         rjmp  .-42       ; 0x74 <main+0x8>

0000009e <_exit>:
  9e:  f8 94         cli

000000a0 <__stop_program>:
  a0:  ff cf         rjmp  .-2        ; 0xa0 <__stop_program>

von Loocee L. (loocee)


Lesenswert?

Chris G. schrieb:
> dass der
> Controller bei delay stehen bleibt und ich finde den Fehler einfach
> nicht.

Vermutlich belibt der Controller nicht stehen sondern braucht
nur sehr lang. Das wäre bei internem RC-Oszillator der Fall....

Abzuchecken wäre:

- sind die Fuses für den externen Quarz oder Ozillator rchtig gesetzt
- ist der Oszillator aktiv (an den Quarz-Pins Sinal prüfen)

von Loocee L. (loocee)


Lesenswert?

Alternativ könntest du die delays mal herausnehmen und
sehen ob die Pins getoggeld werden (müsste in der
Gegend von 1..4 Mhz passieren)

von Thomas E. (thomase)


Lesenswert?

Chris G. schrieb:
> Blinken.elf:     file format elf32-avr
Das sieht leider alles gut aus.

Wie sind die Fuses eingestellt?

mfg.

von Chris G. (kamp79)


Lesenswert?

wenn ich delay herausnehme, läufts wie erwartet.

von Loocee L. (loocee)


Lesenswert?

Chris G. schrieb:
> wenn ich delay herausnehme, läufts wie erwartet.

Und der Prozessortakt, die Fuses ??

von Chris G. (kamp79)


Lesenswert?

Der Prozesortakt ist auf 8MHz eingestellt.

Wo finde ich denn die Einstellungen der Fuses?

von Bernd K. (prof7bit)


Lesenswert?

Fuses kannst Du auslesen mit dem Programmiergerät und meist 
(Atmel-Studio, Eclipse AVR, etc.) hast Du auch gleich eine graphische 
Oberfläche dabei die Dir die Fuse-bits in menschenlesbare Information 
übersetzt. Ansonsten (wenn Du es zu Fuß machst mit Batch oder Makefile 
dann google mal nach fuse calculator).

Apropos Fuse: Hast Du eventuell die Watchdog-Fuse gesetzt?

Was passiert wenn Du statt 200ms mal was kürzeres nimmst, z.B. 2ms? 
(wirst ein Oszi brauchen um das zu sehen)

von Loocee L. (loocee)


Lesenswert?

Chris G. schrieb:
> Der Prozesortakt ist auf 8MHz eingestellt.

Es ist nicht entscheidend was du eingestellt hast sondern
mit welcher Frequenz der Prozessor läuft. Ja, das kann was ganz
unterschiedliches sein.

Bis jetzt habe ich noch nicht gehört ob er mit externem Takt,
internem Takt, mit Quarz oder mit keramischen Schwinger
betrieben wird. An den XTAL Pins musst du - um Sicher zu sein -
die gewünschte Frequenz nachweisen. Mit einem Oszilloskop.

>
> Wo finde ich denn die Einstellungen der Fuses?

Die Aussage ganz oben und diese Frage zeigt doch dass du deine
Schaltung bzw. deinen Prozessor noch lange nicht im Griff hast.
Zuerst musst du mal das Datenblatt lesen und wissen was du
willst und was du machst.

: Bearbeitet durch User
von Thomas E. (thomase)


Lesenswert?

Chris G. schrieb:
> Der Prozesortakt ist auf 8MHz eingestellt.
>
> Wo finde ich denn die Einstellungen der Fuses?

Das widerspricht sich. Einerseits hast du deinen Controller auf 8MHz 
eingestellt, andererseits weisst du nicht, wie man die Fuses einstellt 
bzw. ausliest.
Der Takt wird mit den Fuses eingestellt. Der Eintrag von F_CPU dient 
dazu, dem Compiler mitzuteilen, mit welchem Takt der Controller 
tatsächlich läuft. Mit dieser Angabe wird z.B. das Delay 
mikrosekundengenau berechnet.

Dein Controller läuft deswegen nach wie vor mit 1MHz.

mfg.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Was ist mit Watchdog?

von Chris G. (kamp79)


Lesenswert?

Also erstmal vielen Dank für die Hilfe. Durch ein Gespräch mit meinem 
Prof. von der Uni, habe ich jetzt die Lösung:

Am We hatte ich kein reales Board zur Verfügung und habe deshalb mit dem 
AVR Simulator IDE und mit der im AVR Studio enthaltenen Debugfunktion 
gearbeitet. Das Problem liegt hier in der Delayfunktion, da diese sehr 
kritisch programmiert ist (siehe Dokumentation) und die Simulatoren 
damit so ihre Probleme haben. Heute habe ich ein reales Board (Easy AVR 
V6) angeschlossen und schon lief das Ganze auf Anhieb...

von Oliver S. (oliverso)


Lesenswert?

Chris G. schrieb:
> und mit der im AVR Studio enthaltenen Debugfunktion
> gearbeitet.

Wäre natürlich hilfreich gewesen, du hättest darauf hingewiesen ...

Chris G. schrieb:
> Das Problem liegt hier in der Delayfunktion, da diese sehr
> kritisch programmiert ist (siehe Dokumentation) und die Simulatoren
> damit so ihre Probleme haben.

Das ist allerdings Unsinn. Das ist ganz normaler Code, und der wird von 
jedem Simulator problemlos ausgeführt. Du hast schlicht nicht lange 
genug gewartet, der Simulator läuft halt nicht in Echtzeit. Nach ein 
paar Stunden hätte das schon geblinkt...

Oliver

von Loocee L. (loocee)


Lesenswert?

Chris G. schrieb:
> Am We hatte ich kein reales Board zur Verfügung und habe deshalb mit dem
> AVR Simulator IDE und mit der im AVR Studio enthaltenen Debugfunktion
> gearbeitet.

Das nennen ich Verarschung eines Forums das du um Hilfe bittest.
Mit keinem Wort hast du eine Simulation erwähnt, selbst als man
darauf hingewiesen hat dass an der Hardware zu "drehen" wäre.

von Oliver S. (oliverso)


Lesenswert?

Chris G. schrieb:
> Ich habs außer mit der Schaltung auch mit dem AVR Simulator IDE versucht
> un das Ergebnis ist gleich.

Chris G. schrieb:
> Am We hatte ich kein reales Board zur Verfügung und habe deshalb mit dem
> AVR Simulator IDE und mit der im AVR Studio enthaltenen Debugfunktion
> gearbeitet.

Eberhard F. schrieb:
> Das nennen ich Verarschung eines Forums das du um Hilfe bittest.

So ist es...

Oliver

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.