Probleme mit _delay_ AVR Atmel32

#3874983
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);

  }

}
#3875058
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.
#3875094
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.
#3875139
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.
#3875167
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>
#3875168
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)
#3875997
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)
#3876046
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.
#3876199
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.
#3880252
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...
#3880262
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
#3880370
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren