Hallo Zusammen!
Ich hba leider ein Problem bei dem ich nicht weiter weiß...
Ich habe eine Platine erstellt mit einem ATmega32U4. Bin gerade am
Testen und hab dazu das Standard Blink Beispiel (leicht abgeänderte
Zeiten) von der Arduino IDE mit einem Programmer aufgespielt. Das hat
auch funktioniert. Also programmieren sollte kein Problem sein. Blinken
tut das ganze auch aber leider 8mal langsamer als es sollte. Ich finde
den Fehler einfach nicht.
Drum die Bitte mir zu helfen.
1
voidsetup(){
2
// initialize digital pin 13 as an output.
3
pinMode(7,OUTPUT);// Schaltplan Signal T1 (Ausgangsstufe LED)
4
}
5
6
// the loop function runs over and over again forever
7
voidloop(){
8
digitalWrite(7,HIGH);// turn the LED on (HIGH is the voltage level)
9
delay(50);// wait for a second
10
digitalWrite(7,LOW);// turn the LED off by making the voltage LOW
Der atmega32u4 hat einen usb bootloader und benötigt zwingend einen
externen 16MHz quarz.
Mann stellt hier also , im vergl. zu einigen anderen keinen 1/8 Teiler
aus.
Hallo,
Karl M. schrieb:> Der atmega32u4 hat einen usb bootloader und benötigt zwingend einen> externen 16MHz quarz.
auch in diesem Fall?
Martin B. schrieb:> Ich habe eine Platine erstellt mit einem ATmega32U4.
Im Lieferzustand CKDIV8 aktiv, die 48MHz für USB werden ohnehin per
interner PLL erzeugt. Clock-Fuse stehen auf ext. Low-Frequenz 8MHz laut
Datenblatt, das dürfte auch mit seinen 16MHz noch klappen und intern
würde der Core dann mit 2MHz laufen.
Wie die ATmega32U4 aus der ArduinoIDE programmiert werden habe ich jetzt
nicht nachgeschaut, welchen Bootloader der TO benutzt muß er wissen.
Gruß aus Berlin
Michael
Danke euch drei für die schnelle Antwort!
Ich hab versucht dieses Bit zu setzen, in dem ich die Bords.txt
abgeändert hab auf "leonardo.bootloader.low_fuses=0x5e" und dann den
Bootloader aufgespielt hab.
hatte aber keinen Effect, wenn ich dann wieder das Blink Programm über
den Programmer aufgespielt habe.
Wie unnütz ist das denn, dass delay() nicht auf die eingestellte
Taktrate achtet? Dann finde ich diese Funktion irgendwie sinnlos...
Auch wenn dich das nicht mit deinem Problem weiter bringt interessiert
mich, warum du PIN PE6 genommen hast? Im Datenblatt steht dazu, dass der
PIN der Eingang vom Comperator oder für externe Interrupts ist...
Das hat geholfen! jetzt stimmen die Zeiten und nicht nur das Blink
Programm ist korrekt sondern auch LCD und Max31855 gibt Daten her.
Andre R. schrieb:> Wie unnütz ist das denn, dass delay() nicht auf die eingestellte> Taktrate achtet? Dann finde ich diese Funktion irgendwie sinnlos...>> Auch wenn dich das nicht mit deinem Problem weiter bringt interessiert> mich, warum du PIN PE6 genommen hast? Im Datenblatt steht dazu, dass der> PIN der Eingang vom Comperator oder für externe Interrupts ist...
Ja ich finde das auch sehr unnütz! aber im Normalfall ist die Funktion
auch sehr praktisch wenns um keine kritischen Anwendungen geht...
Ich kann dir die Frage leider nicht beantworten, ich hab die Schaltung
zu großen Teilen übernommen aus einem Projekt aus den Internet und dann
Komponenten getauscht die ich bekommen kann.
@all: Danke für eure Hilfe allein wäre ich nicht auf den "Fehler"
gekommen!
Andre R. schrieb:> Wie unnütz ist das denn, dass delay() nicht auf die eingestellte> Taktrate achtet? Dann finde ich diese Funktion irgendwie sinnlos...
Du Schlaumeier, dann verrate mal, wie delay() die Taktrate bestimmen
soll?
Solange das Zielsystem nicht über entspechende Software und eine
(richtig laufende) RTC verfügt, ist der Compiler beim Übersetzten von
delay() auf die im Programm vorhandenen Angaben (in Form von FCPU o.ä.)
angewiesen.
Wolfgang schrieb:> Du Schlaumeier, dann verrate mal, wie delay() die Taktrate bestimmen> soll?
Indem es die gesetzten Fuses ausliest? Oder geht das nicht?
Ansonsten muss eigentlich bei der delay Funktion stehen, dass diese nur
mit der und der Taktrate richtig zu benutzen ist und diese Bemerkung hab
ich bis jetzt noch nicht bewusst wahrgenommen.
Andre R. schrieb:> Ansonsten muss eigentlich bei der delay Funktion stehen, dass diese nur> mit der und der Taktrate richtig zu benutzen ist und diese Bemerkung hab> ich bis jetzt noch nicht bewusst wahrgenommen.
Nein, muss es nicht, die Funktion wertet die zur Compilezeit gesetzte
Definition von F_CPU aus.
Wenn die nicht zu dem passt, was beim µC eingestellt ist, ist's halt
einfach nur falsch, aber leicht zu beheben.
Rufus Τ. F. schrieb:> Nein, muss es nicht, die Funktion wertet die zur Compilezeit gesetzte> Definition von F_CPU aus.
Entschuldige, falls das eine dumem Frage ist: die Funktione wertet die
gesetzte Definition der F_CPU aus, die sich wo befindet? Also wo steht
die Definition? F_CPU ist die nackte Taktrate oohne irgendwelche Teiler,
auch wenn welche eingestellt sind?
Andre R. schrieb:> die Funktione wertet die> gesetzte Definition der F_CPU aus, die sich wo befindet?
Nein, nicht die Funktion wertet F_CPU aus, sondern der Compiler, mit dem
du den Code für den µC generierst.
Der Wert wird entweder über die IDE festgelegt oder ist im Quellcode
definiert.
Karl M. schrieb:> Der atmega32u4 hat einen usb bootloader und benötigt zwingend einen> externen 16MHz quarz.
Erzähle das mal dem AVR mit einem 8MHz Quarz!
Die können beide!
Hallo,
Andre R. schrieb:> Entschuldige, falls das eine dumem Frage ist: die Funktione wertet die> gesetzte Definition der F_CPU aus, die sich wo befindet? Also wo steht> die Definition? F_CPU ist die nackte Taktrate oohne irgendwelche Teiler,> auch wenn welche eingestellt sind?
Nein. F_CPU muß die tatsächliche Taktfrequenz bekommen, mit der der Core
läuft. Der Compiler liest keine Fuase-Bits aus, er schaut auch nicht
nach, welchen Quarz mit welcher Frequenz Du außen angebaut hast usw.
Für all das bist Du zuständig.
Hätte der TO z.B. F_CPU mit 2 MHz angeben (16MHz Quarz und CKDIV8
programmiert) hätten die delay-Werte gestimmt.
Gruß aus Berlin
Michael
Andre R. schrieb:> Wie unnütz ist das denn, dass delay() nicht auf die eingestellte> Taktrate achtet? Dann finde ich diese Funktion irgendwie sinnlos...
Viele Leute benutzen lange delay_ms() um nachzuschauen ob F_CPU richtig
gesetzt wurde. Einfach Blinkfrequenz messen. ;-)
Für nicht-triviale Programme sind delays im ms Bereich verpönt - dort
nimmt man besser Interrupts und Statemachines. Bei Delays im us Bereich
würde die Berechnung jedesmal zu lange dauern. Beim Macro macht das
schon der Compiler.
Ja, dass delays für zeitkritischebn Geschichten murks sind hab ich schon
gelernt und kann ich bestätigen :D
Michael U. schrieb:> Nein. F_CPU muß die tatsächliche Taktfrequenz bekommen, mit der der Core> läuft. Der Compiler liest keine Fuase-Bits aus, er schaut auch nicht> nach, welchen Quarz mit welcher Frequenz Du außen angebaut hast usw.> Für all das bist Du zuständig.
Das heißt, wenn ich nicht selber im Quellcode F_CPU modifiziere geht der
Compiler von einer Taktfrequenz der Werkseinstellung aus, egal welche
Fuses ich gesetzt habe oder nicht. Demzufolge wird ein delay(100) bei
F_CPU = 8MHz ein anderes Ergebnis liefern als F_CPU = 2 MHz? Unabhängig
davon, ob ich die Fuses nun gesetzt habe oder nicht?
Andre R. schrieb:> Das heißt, wenn ich nicht selber im Quellcode F_CPU modifiziere geht der> Compiler von einer Taktfrequenz der Werkseinstellung aus, egal welche> Fuses ich gesetzt habe oder nicht. Demzufolge wird ein delay(100) bei> F_CPU = 8MHz ein anderes Ergebnis liefern als F_CPU = 2 MHz? Unabhängig> davon, ob ich die Fuses nun gesetzt habe oder nicht?
Ja. Schau dir doch die delay_ms Funktion einfach mal an. Für normale
Menschen ist das aber keine Einschränkung weil die F_CPU von vornherein
auf den korrenten Wert gesetzt haben. Nur Spongos die das nicht haben,
müssen hier eine Welle wegen _delay_ms machen.
Aber F_CPU gehört nicht in den Quellcode sondern in die Linker-Parameter
des Projekts.
Und btw: Niemand hält dich ab eine entsprechende Delay Funktion zu
schreiben welche die Frequenz anhand der Fuses bestimmt.
Nun gut, geht bei ext. Quarzen usw. natürlich auch wieder nicht und
somit muss man wieder F_CPU bemühen aber hey, irgendwas ja immer und es
würde dich ein wenig beschäftigen und du wärst weg von der Straße und
vom Forum....
Hallo,
Andre R. schrieb:> Das heißt, wenn ich nicht selber im Quellcode F_CPU modifiziere geht der> Compiler von einer Taktfrequenz der Werkseinstellung aus, egal welche> Fuses ich gesetzt habe oder nicht. Demzufolge wird ein delay(100) bei> F_CPU = 8MHz ein anderes Ergebnis liefern als F_CPU = 2 MHz? Unabhängig> davon, ob ich die Fuses nun gesetzt habe oder nicht?
der Compiler geht von garkeiner konkreten Taktfrequenz aus, dem ist
völlig egal wie schnell das Programm hinterher abgearbeiet wird.
Funktionen, die Zeitabhängigkeit fordern wie z.B. _delay() warnen
einfach, wenn F_CPU nicht gesetzt wurde. Wenn Du z.B. einen timer
programmierst muß Du die nötigen Register und Teilerwerte selber
bestimmen.
Die ArduinoIDE als Beispiel geht von einem Arduino aus, den Du in der
Boardauswahl eingestellt hast. Der kommt im Lieferzustand auch mit
Bootloader, passendem Quarz und passend gesetzten Fuses.
Nur deshalb gehen da die internen Rechnereien von feststehenden Werte
aus.
Baust Du selber was, mußt Du entweder alle Randbedingungen (Quarz, Fuses
usw) des "Arduinos" einhalten oder dir einen passenden boards.txt
Eintrag für Deinen "Arduino" anlegen.
Gruß aus Berlin
Michael
Andre R. schrieb:> Das heißt, wenn ich nicht selber im Quellcode F_CPU modifiziere geht der> Compiler von einer Taktfrequenz der Werkseinstellung aus, egal welche> Fuses ich gesetzt habe oder nicht. Demzufolge wird ein delay(100) bei> F_CPU = 8MHz ein anderes Ergebnis liefern als F_CPU = 2 MHz?
Nein, der Compiler kann alleine schon deshalb nicht von irgendeiner
Werkseinstellung ausgehen, weil kein Compiler dieser Welt weiss, was du
auf deinem Board für einen Taktgeber aufgelötet hast. Der Compiler
verwendet den in der IDE festgelegten Wert oder meckert (hoffenlich),
dass der Wert gar nicht definiert ist.
Für die Arduino Board steht der Wert, den die Arduino IDE benutzt z.B.
in der Board-Datei.
Cyblord -. schrieb:> Aber F_CPU gehört nicht in den Quellcode sondern in die Linker-Parameter> des Projekts.
Das ist Blödsinn, der Linker kann mit dem Wert absulut nichts anfangen.
Der einzige, der ihn benutzt ist der Präprozessor. Und ob der ihn im
Quellcode findet oder in seinen Parametern ist im Endeffekt auch egal.
Wolfgang schrieb:> Nein, der Compiler kann alleine schon deshalb nicht von irgendeiner> Werkseinstellung ausgehen, weil kein Compiler dieser Welt weiss, was du> auf deinem Board für einen Taktgeber aufgelötet hast. Der Compiler> verwendet den in der IDE festgelegten Wert oder meckert (hoffenlich),> dass der Wert gar nicht definiert ist.
Der Compiler nicht direkt, aber die Entwickler der avr-libc (gekürzt):
1
#ifndef F_CPU
2
# warning "F_CPU not defined for <util/delay.h>"
3
# define F_CPU 1000000UL
4
#endif
Die gehen halt von dem wohldefinierten Zustand aus, in dem die Dinger
von Atmel/Microchip produziert werden. Sie schreiben in der Doku aber
auch dazu:
1
The value 1 MHz here is only provided as a "vanilla" fallback if no such user-provided definition could be found.