PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Seltsames Problem



Thalhammer
07.10.2012, 22:22
Hallo, ich ein total komisches Problem:
Wenn ich _delay_ms() aufrufe wartet es nicht nur ungenau, nein viel schlimmer, es wartet jedesmal anders.

#include <avr/io.h>
#include <util/delay.h>


void long_delay(uint16_t ms) {

for(; ms>0; ms--) _delay_us(1000);

}


int main(void)
{
DDRB=0xFF;
// Insert code
//init();
//set_pin(PORTB,PIN1);
while(1)
{
long_delay(100);
clear_pin(PORTB,PIN0);
long_delay(10000);
set_pin(PORTB,PIN0);
}

return 0;
}
Wenn ich das baue und auf meinen Mega8@1MHz lade ist die an phase länger als die ausphase (obwohl es eigentlich umgekehrt sein sollte) und die Wartezeit mit nichten 100ms sondern deutlich über 1 Sekunde.
Ich hab nicht die leiseste Ahnung woran das liegen könnte.
Im simulator funktioniert das Programm einwandfrei.
Ich werde es morgen auch noch auf einem anderen AVR Testen

markusj
07.10.2012, 23:12
Wird irgendwo F_CPU gesetzt? (Bevorzugt über die Entwicklungsumgebung oder das Makefile, wenn es Quick & Dirty sein muss, auch über #define F_CPU 1000000UL als erste Zeile im Code)

Davon abgesehen: Wie überprüfst du das Ausgangssignal? Mit einer LED? Ist die auch entsprechend verdrahtet (gegen GND)?

mfG
Markus

Thalhammer
08.10.2012, 16:00
F_CPU wird von der IDE gesetzt, ich prüfe die Ausgabe mit einer LED, die gegen GND liegt.
Der Takt kommt vom internen Oscillator und laut fuses auf 1MHz gesetz.
Hab jetzt mal was neues Probiert:

int main(void)
{
DDRB=0xFF;
// Insert code
//init();
//set_pin(PORTB,PIN1);
while(1)
{
for(uint8_t i=0;i<10;i++) {
_delay_ms(100);
toogle_pin(PORTB,PIN1);
}
toogle_pin(PORTB,PIN0);
}

return 0;
}
Funktionierd prima, solange die funktion nicht das ende der while schleife erreicht.
Auf Deutsch:
Die Led an PB1 blinkt genau 5 mal und dann schaltet sich die grüne ein.
Sobald die grüne leuchtet bleibt der controller stehen.

markusj
08.10.2012, 17:48
Davon abgesehen, dass du mit einer Menge Funktionen um dich wirfst, die ich nie gesehen/gebraucht habe, folgender Code funktioniert in der Simulation ohne Probleme:

#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
DDRB=0xFF;

while(1)
{
for(uint8_t i=0;i<10;i++) {
_delay_ms(100);
PORTB ^= (1 << PB1);
}
PORTB ^= (1 << PB0);
}

return 0;
}

Unterschiede: Keine komischen Funktionen zum setzen/umschalten von Pins, keine komischen Bezeichner für die einzelnen Pins.

mfG
Markus

Thalhammer
08.10.2012, 18:01
Bei mir ist nichts komisch, die Bezeichner werden vom GCC definiert und sind mit denen von PB0 etc identisch.
Und die "unbekannten" Funktionen sind Compiler Makros, die genau das machen was du geschrieben hast.
In der Simulation (SimulAVR) funktionierds bei mir auch ganz normal, aber auf dem Mega nicht.
//EDIT:
Hab grade den Code von dir gebaut und auf den AVR gebrannt, gleiches Phänomen.
Die LED an PB1 blinkt bis die an PB0 angeht und dann ist schluss.
Die an PB0 bleibt an und die an PB1 aus.

Hubert.G
08.10.2012, 18:11
Habe beide Programme mit dem AVR-Studio4 kompiliert, funktionieren beide.
Das tooggle_pin und clear_pin kenne ich allerdings nicht, vielleicht liegt dort der Fehler?

Thalhammer
08.10.2012, 18:14
habs grade editierd:
Hier noch die Macros:

#define set_pin(port,pin) ((port) |= (1<<pin))
#define clear_pin(port,pin) ((port) &= ~(1 <<pin))
#define toogle_pin(port,pin) ((port) ^= (1<<pin))
Der bleibt einfach stehen sobald er das ende der while schleife erreicht.

Hubert.G
08.10.2012, 18:18
Funktioniert auch mit deinen define.

Thalhammer
08.10.2012, 18:36
Hm dann probier ich mal nen anderen AVR, denn meiner bleibt einfach stehen.
So hab grade nochmal einen neuen AVR genommen, gleiches Problem.
Ist das möglicherweise ein Bug im avr-gcc oder der avr-libc ?

markusj
08.10.2012, 19:14
Probleme mit der Spannungsversorgung? Eine LED funktioniert, die zweite bringt den AVR in einen instabilen Zustand. Aber dass der Fehler so reproduzierbar auftritt, macht mich stutzig ...

mfG
Markus

Thalhammer
08.10.2012, 20:32
Nein Probleme mit der Hardware kann ich ausschliesen, da ich den zweiten AVR in meinem MyAVR MK2 probiert hab und das ist definitv i.O.
Ich werde morgen das ganze mal von meinem anderen PC aus und später vieleicht auch unter Windows probieren, ich denke das es am compiler liegt, da ich noch nie solche Probleme hatte.

Hubert.G
08.10.2012, 20:39
Also Compiler kann ich mir nicht vorstellen, es sei denn du verwendest irgend was Exotisches.
Das sind Standardzeilen die du da schreibst. Über einen Fehler wären da schon viele drüber gefallen.

Thalhammer
08.10.2012, 20:46
Aber was soll das sonst sein ?
Hardware kann es nicht sein, Software ist wie du schon sagst Standart und der Compiler ist der Standartgcc aus dem Ubuntu repository.
könnte vileicht mal einer von euch die hexdatei anhängen, dann würd ich dass mal flashen.

radbruch
08.10.2012, 20:48
Bekommst du eine Warnung beim Kompilieren?


#ifndef F_CPU
/* prevent compiler error by supplying a default */
# warning "F_CPU not defined for <util/delay.h>"
# define F_CPU 1000000UL
#endif

#ifndef __OPTIMIZE__
# warning "Compiler optimizations disabled; functions from <util/delay.h> won't work as designed"
#endif(Aus util/delay.h)

Thalhammer
08.10.2012, 20:51
Nein, warum sollte ich auch, es ist ja auf der Commandozeile mit -DF_CPU=1000000UL definiert.

radbruch
08.10.2012, 20:58
Zeig doch mal die Kommandozeile

Thalhammer
08.10.2012, 21:08
avr-gcc -o test.elf main.c -Os -DF_CPU=1000000UL -mmcu=atmega8 -std=gnu99
zum bauen und um daraus ne hex zu machen

avr-objcopy -O ihex test.elf test.hex
Und noch ein paar infos


$avr-gcc --version
avr-gcc (GCC) 4.5.3
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
$avr-objcopy --version
GNU objcopy (GNU Binutils) 2.20.1.20100303
Copyright 2009 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) any later version.
This program has absolutely no warranty.

Hoffe das hilft.

SprinterSB
08.10.2012, 21:36
Watchdog ist aus?

Stannungsversorgung ist sauber?

Welchen Code macht der Compiler?

Setze mal zusätzlich -dp -save-temps und zeige das s-File (ist Text)

Hubert.G
09.10.2012, 09:27
Das sollte das *.hex File sein mit den zwei Leds.

Thalhammer
09.10.2012, 13:29
@ SprinterSB ich geh mal davon aus dass er aus ist, ich hab den AVR in meinen Probierereien schon auf Werkseinstellungen zurückgesetzt.
@Hubert.G Werd ich heute ausprobieren
Ich weis zwar nicht was das Programm hätte tun sollen, aber ich weis was es tut, nähmlich nichts.
Keine Sichtbare Reaktion des Microcontrollers.
Auch erscheint mir das Programm mit 202 byte ein wenig klein.
Ich werde mir mal noch den ASM output des GCC ansehen.

HeXPloreR
09.10.2012, 15:27
Also bei mir tut die Hex vom Hubert genau das was sie soll: 5x PB1 an/aus, PB0 an, 5x PB1 an/aus, PB0 aus und wieder von vorne...
Wo der Fehler bei Dir liegt kann ich nicht sagen, ich tippe: Frequenz...oder einfach falschrum eingesetzt ;)

viele grüße

Thalhammer
09.10.2012, 15:37
Hm also ich hab jetzt nochmal mein Programm auf das wesentlich wichtige beschränkt:

#define F_CPU 8000000UL
#include <avr/io.h>
#include <util/delay.h>
#include "port.h"
int main(void)
{
DDRB=0xFF;
while(1)
{
_delay_ms(100);
toogle_pin(PORTB,PB0);
}
return 0;
}


was von GCC wie folgt übersetzt wird:

.file "main.c"
__SREG__ = 0x3f
__SP_H__ = 0x3e
__SP_L__ = 0x3d
__CCP__ = 0x34
__tmp_reg__ = 0
__zero_reg__ = 1
.text
.global main
.type main, @function
main:
/* prologue: function */
/* frame size = 0 */
/* stack size = 0 */
.L__stack_usage = 0
ldi r24,lo8(-1)
out 55-32,r24
ldi r25,lo8(1)
.L2:
ldi r18,lo8(159999)
ldi r19,hi8(159999)
ldi r20,hlo8(159999)
1:subi r18,1
sbci r19,0
sbci r20,0
brne 1b
rjmp .
nop
in r24,56-32
eor r24,r25
out 56-32,r24
rjmp .L2
.size main, .-main
Und erstaunlicherweise funktionierd.
Ich hab keine Ahnung woran es lag, aber jetzt schein alles zu funktionieren.
Auch sachen ala

for(uint8_t i=0;i<10;i++) _delay_ms(100);
gehen plötzlich.
Obwohl ich schwören könnte vorher alles richtig gemacht zu haben.

HeXPloreR
09.10.2012, 15:41
Und wieso benutzt Du jetzt eine port.h - und woher hast Du die? Hast Du nicht schon io.h drin? Und 8MHz???? naja, was denn nun...1MHz oder 8MHz?
Ich vermute dass das neue Programm garnicht auf dem µC angekommen ist vorher.

Thalhammer
09.10.2012, 16:15
8MHz weil ich die Fuses wieder umgestellt hab.
port ist ne eigene die ich schon weiter oben gepostet hab.
und irgendwie hast mich das zeug trotzdem, nachdem das Programm größer wird bleibt es wieder einfach stehen.
Also zumindest hab ich nen neuen ansatz:
Wenn ich den MC auf 1MHz stelle läuft das Programm und wenn ich ihn auf 8MHz stelle läuft es nicht.(natürlich takt im code angepasst.

HeXPloreR
09.10.2012, 17:01
jetzt versteh ich nixhts mehr...mit 8MHz läuft es, dann mit 1MHz auch...und jetzt wieder mit 8MHz nicht mehr?
Welche Spannung nutzt Du,das wurde weiter oben schon mal gefragt? Kann es sein das er mit deiner Spannung nicht mit 8MHz läüft bzw sobald Du LED zuschaltets die knappe Spannung einbricht und der µC resetet wird bzw die Brown Out detection anspricht?

Habe diese Probleme nicht bei 5V.
Beide GND Pins angeschlossen?
Du weißt, das Du die Hex von Hubert jetzt nur an 1MHz verwenden kannst/solltest!?

Viele Grüße

Thalhammer
09.10.2012, 19:57
Also mal ganz von vorne:
Ich nutze via die Stromversorgung des MyAVR MK2, das sind 5V, aus dem USB anschluss.
Ich takte den AVR über den internen Taktgenerator.
Ich habe folgendes Programm erstellt:


#include <avr/io.h>
#include <util/delay.h>
#include "port.h"

int main()
{
DDRB=0xFF;
while(1)
{
_delay_ms(100);
toogle_pin(PORTB,PB0);
}
}
Das läuft mit 1MHz prima, nutze ich jedoch 8MHz geht die LED einmal an und bleibt an.
Es sind beide AGND-GND->MyAVR GND
AVCC->VCC-> MyavrVCC
PB0->LED rot->GND
PB1->LED grün->GND
Reset->R4,7k->VCC
zwischen GND und VCC hängt ein 100nf cap und die ISP pins sind direkt durchgeschlossen.
Ja mir ist klar das ich das von Hubert nur mit 1MHz nutzen kann, allerdings funktionierd das von Hubert auch mit 1MHz nicht.
Ich glaube ich weis das Problem, meine _delay_ms routine ignoriert irgendwie die Takt angabe.
Folgendes Szenario:
Wenn ich den AVR auf 1MHz stelle und im Quellcode F_CPU mit 1MHz definiere wartet er bei
for(uint8_t i=0;i<10;i++) _delay_ms(100); genau 1s.
Stelle ich nun den AVR auf 2MHz, schreibe in den Quellcode F_CPU mit 2MHz müsste er ja bei obigem Code wieder 1s warten, tut er aber nicht. er wartet eine halbe sekunde.
bei 4MHz dementsprechend 250ms, bei 8 MHz 125ms.
Daher dachte ich vorhin er würde hängen, da ich als zeitspanne nur 100ms hatte, er aber bei 8MHz nur 12.5ms gewartet hat konnte ich das An und aus schlicht nicht mehr erkennen.
Um diese Erkenntnis auszuprobieren hab ich promt an F_CPU rumgespielt.
Ich habe Werte zwischen 100kHz und 100GHz eingestellt, dabei war es vollkommen egal, die Led blinkt bei einem CPUTakt von 8MHz mit konstanten 8Hz vor sich hin, egal wie ich F_CPU definiere.
Hoffe das hat jetzt jemand verstanden.

HeXPloreR
09.10.2012, 20:07
okay, ich nehme an Du hast zwischen LED die min 470Ohm Widerstände extern verbaut? Ich schlage vor Du entfernst mal die Verbindung bei AVCC - denke die benötigt man hier nicht - und schon garnicht einfach so angeschlossen - und das dadurch der fehler entsteht ist naheliegend.

Dann liesst du bitte einmal die Low-Fuses aus, um die Anzeige zu aktualisieren. Dann prüfst Du ob 1MHz (+64ms)
Und dann nimmst Du bitte nochmal die Hex von Hubert und brennst es in den Flash.

Thalhammer
09.10.2012, 20:19
Lies mal oben, ich hab was ergänzt, ich denke der Fehler liegt bei der PC Software.

HeXPloreR
09.10.2012, 20:33
...und ich denke Du schreibst die Fuses einfach nicht in den µC...nur im Programm reicht eben einfach nicht, da kannst Du rein schreiben was du möchtest an Frequenzen, damit versaust Du Dir nur die Zeiten, dein µC läuft fleissig mit 1MHz - weil Du es nicht für nötig hälst den "manuell" auszulesen(zur Kontrolle) und dann "um zu stellen", und dann in den Fuse Speicher "einzuschreiben".



$regfile = "m8adef.dat"
$crystal = 8000000

$baud = 19200


$hwstack = 40
$swstack = 16
$framesize = 32

Led Alias Portb.0 'the anode of the LED connected to PortB.0, cathode with resistor (470 Ohm) to ground
Config Pinb.0 = Output

Do
Waitms 500
Toggle Led
Loop


Geht sogar in Bascom...hab 100 zu 500 ms geändert damit man es besser sehen kann

Wenn ich meine Fuses über mySmartUSB mit myAVR öffne, dann steht dort JEDESMAL 1MHz is default, erst nach dem auslesen der Fuses zeigt es den richtigen Wert von 8MHz an.

Thalhammer
09.10.2012, 20:51
Bei dem Satz komm ich nicht mit.
Egal, hier meine Vorgehensweise:
Ich stelle den AVR auf 1MHz (lfuse=0xE1) und gebe im File F_CPU 1000000UL an.
Ich baue und flashe mein Programm.
Die LEd blinkt mit 1Hz->Stimmt so.
Ich stelle den AVR auf 2MHz (lfuse=0xE2).
Die Led blinkt mit 2Hz->Stimmt so, da das neue Programm noch nicht geflasht wurde, also stimmen die Zeiten nicht.
Ich ändere im File auf f_CPU 2000000UL.
bauen, übertragen.
Die Led blinkt aber nach dem flashen immernoch mit 2Hz->Stimmt nicht, da er eigentlich die Zeiten anpassen müsste.
---->>>Der Compiler passt die Zeiten nicht an.
Und ich hab jetzt in das ASM File gekuckt und einmal für 1MHz erstellt und einmal für 8MHz, die Dateien sind absolut identisch.
Falls jetzt noch einer an einen Hardware defekt glaubt muss er schon ein verdammt gutes argument haben.
Ich hab mal die ASM files als zip angehängt damit ihr euch überzeugen könnt.

HeXPloreR
09.10.2012, 21:02
Also ich habe das jetz mal gemacht so wie Du es beschreibst, nur habe ich auf 8Mhz kompiliert und dann 1Mhz auf dem µC eingestellt ... und was denkst Du passier?
Richtig die Led geht jetzt alle 4000ms aus und an. Warum? Weil die frequenz nun um das 8fache langsamer ist.

ich würde sagen Dein programm stimmt dann so.

Tu mir bitte einen gefallen und ändere die Zeiten in Deinem Programm in werte die man auch mal mit dem Auge mitverfolgen kann 100ms kann sind da doch etwas schnell

Thalhammer
09.10.2012, 21:15
Willst du es nicht verstehen oder kanst du nicht.
ES IST VOLLKOMMEN EGAL WIE ICH F_CPU EINSTELLE!!!!!!!!!!
Wenn ich meinen uC auf 1MHz stelle und F_CPU auf 1Mhz stelle kommt ein blinken im sekundentakt raus

for(uint8_t i=0;i<10;i++) _delay_ms(100);
Lasse ich meinen uC auf 1Mhz und stelle im File z.b. F_CPU=80000000000000000UL ein kommt trotzdem ein blinken im sekunden takt raus.
Die ausgabe des avr-gcc ist genau gleich, scheiß egal was ich bei F_CPU einstelle. Sei es nun 1Hz oder 3Billionen Gigaherz, er rechnet IMMER MIT 1MHz.

markusj
09.10.2012, 21:25
Ich schlage vor Du entfernst mal die Verbindung bei AVCC - denke die benötigt man hier nicht - und schon garnicht einfach so angeschlossen - und das dadurch der fehler entsteht ist naheliegend.
Mit Verlaub, das ist Quatsch. AVCC wird entweder direkt oder über eine Filter-/Glättungsschaltung an VCC angeschlossen. Immer!

@Topic: Ich glaube immer noch, dass die Spannungsversorgung schuld ist. Evtl. ist der USB-Port am Limit?
Nachtrag: Sorry, was ist das für ein rumgemurkse? Entweder F_CPU im File ODER in der IDE. Weiß der Geier was der Compiler gerade tut und was nicht.

mfG
Markus

Thalhammer
09.10.2012, 21:29
Wegen eines AVR und einer LED ?
Ne nie und nimmer, USB Ports müssen laut spezifikation mindestens 100ma für jedes gerät geben.
Wie schon gesagt ich bin mir absolut sicher dass es am kompiler liegt.

markusj
09.10.2012, 21:32
Wegen eines AVR und einer LED ?
Ne nie und nimmer, USB Ports müssen laut spezifikation mindestens 100ma für jedes gerät geben.
Wie schon gesagt ich bin mir absolut sicher dass es am kompiler liegt.

Der myAVR zieht ja auch Strom. Und nein, müssen sie nicht. Die Ports können einem USB-Device jederzeit untersagen, nennenswerten Strom (jenseits von etwas Standby) zu ziehen.
Und ich bin mir absolut Sicher, dass der Fehler irgendwo zwischen Dir, deiner IDE und deinem Programmer zu finden ist. Irgendwas machst du falsch, Compiler bauen nicht einmal richtig und dann wieder falsch bei gleichem Input.

mfG
Markus

Thalhammer
09.10.2012, 21:41
Tun sie auch nicht, aber was er tut ist gleiches ergebnis bei anderem Input.
Schau mal weiter unten auf der letzten seite, dort habe ich mein Programm bei zwei völlig verschiedenen F_CPU werten erstellt, aber das asm file ist das selbe.
bzg USB:
http://de.wikipedia.org/wiki/Universal_Serial_Bus#Spannungsversorgung

Sie ist stabilisiert, liegt bei 5 V ±5 % und liefert einen Strom von mindestens 100 mA (http://de.wikipedia.org/wiki/Ampere).

HeXPloreR
09.10.2012, 21:41
Es sind beide AGND-GND->MyAVR GND
AVCC->VCC-> MyavrVCC
PB0->LED rot->GND
PB1->LED grün->GND
Reset->R4,7k->VCC

immer?
Mit AVCC - dann muß aber auch AREF mit GND und 100nF Kondensator verschaltet werden.

Also ich habe sie nicht verschaltet, weil ich sie nicht benötige zum messen.
Wenn ich das richtig verstanden habe, darf/kann man diese Pins ausschliesslig dafür benutzen.

Und naja, es läuft ja ... die Hex (für 1Mhz compiliert) von Hubert und mein Bascom Programm...in 1MHz und in 8Mhz :-#

Hubert.G
09.10.2012, 21:47
Mir ist nicht klar wie es ein Compilerproblem sein kann wenn meine *.hex nur bei dir nicht läuft.
Hast du in den Fuses BODEN auf 4V gestellt?

Thalhammer
09.10.2012, 21:47
Also ich mach es so schon seit geschätzten 4 Jahren und es hat bisher bei allen meinen Projekten einwandfrei funktionierd.
BODEN und BODLEVEL sind beide unprogrammiert.

markusj
09.10.2012, 21:48
bzg USB:
http://de.wikipedia.org/wiki/Universal_Serial_Bus#Spannungsversorgung
Außer wenn der Host dich in USB-Standby schickt, dann darfst du nur noch 500µA ziehen.

Zu deinem F_CPU: Ich habe den Überblick verloren. Mal hat es getan was du erwartet hast, dann wieder nicht. Wenn du F_CPU verändern kannst ohne dass das Hexfile sich ändert, dann ist die Information über das geänderte F_CPU nicht beim Compiler angekommen. Der Fehler ist nicht im Compiler sondern auf dem Weg zum Compiler zu suchen. Die IDE ist ein ganz heißer Favorit.


immer?
Mit AVCC - dann muß aber auch AREF mit GND und 100nF Kondensator verschaltet werden.
Immer! AVCC ist die Spannungsversorgung für den ADC sowie die Pins die als Eingang für den ADC verwendet werden können. Intern zwar mit VCC verbunden, legt das Datenblatt einem auch bei Nichtbenutzung des ADC nahe, den Pin an VCC anzuschließen. Er ist nur deshalb getrennt ausgeführt, um den Analogteil besser entstören zu können.
AREF hat mit AVCC erst Mal nichts zu tun und muss nicht beschaltet werden. Bei vielen AVRs macht es Sinn, 100nF gegen GND anzuschließen, weil man bei diesen die interne Referenzspannung an den Pin anlegen, und somit stabilisieren, kann. Bei manchen kleineren AVRs gibt es diese Funktion nicht, dann kann man sich die 100nF sparen.

mfG
Markus

Hubert.G
09.10.2012, 21:51
@markusj Bei neueren Mega8 ist AVCC nicht mehr mit VCC verbunden, das war ein Layoutfehler der mittlerweile behoben ist.

markusj
09.10.2012, 21:58
@markusj Bei neueren Mega8 ist AVCC nicht mehr mit VCC verbunden, das war ein Layoutfehler der mittlerweile behoben ist.
Danke für den Hinweis, das war mir neu. Weißt du zufällig, woher du diese Information hast? Im Datenblatt findet sich dazu nämlich keine Aussage.

Thalhammer
09.10.2012, 22:07
Also ich kann jetzt einen Hardware Fehler definitiv und einfüralle mal ausschliesen.
Ich habe mal mein Windows vorgekramt und das gleiche Programm in AVRStudio 5 erstellt, da geht es perfekt.
Nur unter Linux macht es zicken.
Ich kann mir aber nicht erklären warum es nicht am Compiler an kommen sollte, ich hab mitlerweile F_CPU direkt in der main.c definiert, vor allen includes natürlich.
Keine veränderung.
Ich kann mir das echt nicht mehr erklären.

Hubert.G
09.10.2012, 22:10
Da hält sich Atmel ziemlich bedeckt.
Den Hinweis bekam ich im mikrocontroller.net in Zusammenhang mit Probleme bei einem Mega8A und Reset.
Ich habe Mega8 da steht oben neben Atmel 0931G, bei denen ist der Schluss noch vorhanden, bei 1045 nicht mehr. Lässt sich leicht mit einem Ohmmeter überprüfen.

markusj
09.10.2012, 22:22
Thalhammer: Ok, dann gehen wir das jetzt Mal ganz systematisch an. Zuerst einmal wird die IDE ausgenockt.

Anbei dein Minimalcode, leicht modifiziert so dass anstelle der Makros direkt auf die Portregister zugegriffen wird, und ein Shellscript zum Bauen des ganzen. Beides abspeichern, Shellscript ausführbar machen und ausführen. Du kannst die Variable F_CPU im Skript variieren und kontrollieren ob sich dann das .hex-File und das .lss-File ändern. (Tun sie bei mir).

main.c

#include <avr/io.h>
#include <util/delay.h>

int main()
{
DDRB=0xFF;
while(1)
{
_delay_ms(100);
PORTB ^= (1 << PB0);
}
}

build.sh

#!/bin/bash

F_CPU=8000000UL

avr-gcc -Wall -Os -fpack-struct -fshort-enums -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega8 "-DF_CPU=$F_CPU" -MMD -MP -MF"main.d" -MT"main.d" -c -o "main.o" "main.c"
avr-gcc -Wl,-Map,main.map -mmcu=atmega8 -o "main.elf" ./main.o
avr-objdump -h -S main.elf > "main.lss"
avr-objcopy -R .eeprom -O ihex main.elf "main.hex"

Hubert.G
09.10.2012, 22:31
Eine Frage hätte ich da noch.
Was verwendest du für eine Version von GCC.
Es gab doch in älteren Versionen der AVR-Lib-C den Hinweis das _delay_ms() nur bis zu einem gewissen Wert funktioniert, abhängig von der Taktfrequenz.

markusj
09.10.2012, 22:36
@Hubert: Nein, 4.5.3 laut #17

radbruch
09.10.2012, 23:48
Willst du es nicht verstehen oder kanst du nicht.
ES IST VOLLKOMMEN EGAL WIE ICH F_CPU EINSTELLE!!!!!!!!!!Huch?

Ich würde die Datei delay.h im util-Verzeichniss umbenennen. Der zu erwartende Kompilerfehler würde zeigen, dass wirklich diese Datei eingebunden wird. Oder hier mal 8MHz eintragen:


#ifndef F_CPU
/* prevent compiler error by supplying a default */
# warning "F_CPU not defined for <util/delay.h>"
# define F_CPU 1000000UL
#endif

[Edit]
Echt spannend. Minimalprogramm:


#include <avr/io.h>
#include <util/delay.h>

int main(void)
{
_delay_ms(100);
while(1);
}

mit 8MHz:

1 .file "temp.c"
2 __SREG__ = 0x3f
3 __SP_H__ = 0x3e
4 __SP_L__ = 0x3d
5 __CCP__ = 0x34
6 __tmp_reg__ = 0
7 __zero_reg__ = 1
15 .Ltext0:
16 .global main
18 main:
19 .LFB6:
20 .LM1:
21 /* prologue: function */
22 /* frame size = 0 */
23 .LM2:
24 0000 88EE ldi r24,lo8(1000)
25 0002 93E0 ldi r25,hi8(1000)
26 .LVL0:
27 .LBB12:
28 .LBB13:
29 .LBB14:
30 .LBB15:
31 .LM3:
32 0004 28EC ldi r18,lo8(200)
33 0006 30E0 ldi r19,hi8(200)
34 .L2:
35 0008 F901 movw r30,r18
36 .LVL1:
37 /* #APP */
38 ; 105 "c:/winavr/lib/gcc/../../avr/include/util/delay_basic.h" 1
39 000a 3197 1: sbiw r30,1
40 000c 01F4 brne 1b
41 ; 0 "" 2
42 /* #NOAPP */
43 .LBE15:
44 .LBE14:
45 .LM4:
46 000e 0197 sbiw r24,1
47 .LM5:
48 0010 01F4 brne .L2
49 .L6:
50 0012 00C0 rjmp .L6
51 .LBE13:
52 .LBE12:
53 .LFE6:
79 .Letext0:


mit 1MHz:

1 .file "temp.c"
2 __SREG__ = 0x3f
3 __SP_H__ = 0x3e
4 __SP_L__ = 0x3d
5 __CCP__ = 0x34
6 __tmp_reg__ = 0
7 __zero_reg__ = 1
15 .Ltext0:
16 .global main
18 main:
19 .LFB6:
20 .LM1:
21 /* prologue: function */
22 /* frame size = 0 */
23 .LBB12:
24 .LBB13:
25 .LBB14:
26 .LBB15:
27 .LM2:
28 0000 88EA ldi r24,lo8(25000)
29 0002 91E6 ldi r25,hi8(25000)
30 .LVL0:
31 /* #APP */
32 ; 105 "c:/winavr/lib/gcc/../../avr/include/util/delay_basic.h" 1
33 0004 0197 1: sbiw r24,1
34 0006 01F4 brne 1b
35 ; 0 "" 2
36 /* #NOAPP */
37 .L2:
38 0008 00C0 rjmp .L2
39 .LBE15:
40 .LBE14:
41 .LBE13:
42 .LBE12:
43 .LFE6:
69 .Letext0: