Hi, ich habe mir ein kleines Programm geschrieben, mit dem ich Tasten
(PortB1-4) auswerten möchte und als Resultat eine LED aufleuchten lassen
mag, die an einem anderen Port hängt (PortC1-4).
Ich habe in die jeweilige Schalterfunktion ein _delay gesetzt, weil ich
ja einen Moment sehen will, wie die Lampe aufleuchtet und dann wieder
ausgehen soll. Gleichzeitig müsste so auch durch die Verzögerung die
Taste "entprellt" werden. Ich möchte die Wartezeit 2,5 Sekunden (2500
ms) aufleuchten lassen. Nun kommt beim Compilieren ein Warning:
"warning "F_CPU not defined for <util/delay.h>" [-Wcpp]"
Kann man die Warnung einfach "übergehen"?
1
#include<stdlib.h>
2
#include<avr/io.h>
3
#include<avr/interrupt.h>
4
#include<avr/pgmspace.h>
5
#include<util/delay.h>
6
7
#include"uart.h"
8
// #include "uart.c"
9
#include<stdio.h>
10
11
/* define CPU frequency in Mhz here if not defined in Makefile */
>Kann man die Warnung einfach "übergehen"?
Nein.
/* define CPU frequency in Mhz here if not defined in Makefile */
#ifndef F_CPU
#define F_CPU 1000000UL
#endif
#include <util/delay.h>
Diese Warnung sollte man nicht so einfach übergehen. Denn der delay
errechnet aus F_CPU die anzahl an takte, die gewartet werden muss.
Verschiebe einfach die Definition von F_CPU vor die includes. Dann ist
dem Präprozessor bekannt, wie groß F_CPU ist und es kommt auf keinen
Fall zu Fehlern.
Neuling schrieb:> Kann man die Warnung einfach "übergehen"?
Nur wenn es dir völlig egal ist, ob die Delays stimmen oder
grottenfalsch sind. Andernfalls wärs nützlich, F_CPU vor delay.h zu
definieren.
Hallo,
definiere F_CPU einfach BEVOR Du delay.h einbindest. Hier machts die
Reihenfolge. Ignorieren ist schlecht, weil sonst durchaus Timings nicht
stimmen könnten, die in delay.h hinterlegt sind.
Gruß Uli
> "warning "F_CPU not defined for <util/delay.h>" [-Wcpp]"> Kann man die Warnung einfach "übergehen"?
Nur, wenn man delay() nicht benutzt - dann braucht man util/delay.h aber
auch nicht zu includen.
Du musst in Deinem Makefile in den CFLAGS das F_CPU Symbol definieren.
Lucas K. schrieb:> Verschiebe einfach die Definition von F_CPU vor die includes. Dann ist> dem Präprozessor bekannt, wie groß F_CPU ist und es kommt auf keinen> Fall zu Fehlern.
cool, danke für die schnellen Antworten, jetzt klappts auch fehlerfrei
mit dem Compilieren.
Das Verschieben der #define Anweisung ist nur bedingt eine gute Idee.
Mit nur einer Quelltextdatei ist das kein Problem. Bei größeren
Projekten können sich hier schnell Fehler einschleichen.
Besser ist es, solche #defines in einen separaten Header zu legen. Und
wenn es sich um Bibliotheksfunktionen handelt und diese keine
projektspezifischen Includes vorsehen, sollten solche Definitionen per
Makefile und Compiler-Switch vorgenommen werden. Ich glaube mich daran
zu erinnern, daß gerade beim avrgcc der Weg über das Makefile gerne
genommen wird.
Fehler die darauf resultieren, daß zwei unterschiedliche Definitionen
wirksam werden, sind außerordentlich undankbar und kosten viel Zeit.
fragt sich warum... schrieb:> Und wenn es sich um Bibliotheksfunktionen handelt und diese keine> projektspezifischen Includes vorsehen, sollten solche Definitionen per> Makefile und Compiler-Switch vorgenommen werden.
Makros wirken nicht auf Bibliotheken, es sei denn sie werden mit
gesetztem Makro neu generiert.
Johann L. schrieb:> fragt sich warum... schrieb:>> Und wenn es sich um Bibliotheksfunktionen handelt und diese keine>> projektspezifischen Includes vorsehen, sollten solche Definitionen per>> Makefile und Compiler-Switch vorgenommen werden.>> Makros wirken nicht auf Bibliotheken, es sei denn sie werden mit> gesetztem Makro neu generiert.
Hab' mich schlampig ausgedrückt - keine Bibliotheken selbst, sondern
beliebiger externer Code, der eigentlich nicht modifiziert werden
sollte, um die Verwendbarkeit in unterschiedlichen Projekten/Plattformen
und die problemlose Aktualisierung zu gewährleisten. Dabei kann es sich
um komplette Quelltexte handeln oder um Bibliotheken, welche Header
Dateien mitbringen die in Abhängigkeit der Makrodefinitionen die
Erzeugung unterschiedlichen Codes bewirken können. Ich denke letzteres
ist in dem konkreten Fall gegeben.
eine andere Frage hab ich nochmal - wenn ich die Stepfunktion im
Debugger mache, hällt dann der Computer auch bei der Delay-Funktion an
und macht die Pause durch? Weil mein Problem - an der Stelle
delay(2500ms) hält der Computer einfach für eine Weile an und zwar
mehrere Minuten. Vielleicht hab ich mich aber auch verreichet. Laut
Angabe im Tutorial ist bei der Funktion _delay_ms die Zeit in
Millisekunden anzugeben, also 2500ms = 2,5 Sekunden. Vielelicht hab ich
mich aber auch verreichnet? Oder macht der Debugger "blödsinn"?
Neuling schrieb:> Vielelicht hab ich> mich aber auch verreichnet? Oder macht der Debugger "blödsinn"?
Debuggen mit der Ziel-Hardware oder dem Simulator?
Vermutlich letzteres, denn der Simulator läuft nicht in Echtzeit,
sondern ist erheblich langsamer.
Neuling schrieb:> Weil mein Problem - an der Stelle> delay(2500ms) hält der Computer einfach für eine Weile an und zwar> mehrere Minuten.
Ja, das hängt damit zusammen, dass der Debugger intern einzelne
CPU-Schritte machen muss, bis er feststellt, dass der aktuelle
program counter schließlich mal einen Wert hat, der hinter der
delay-Zeile liegt. Das delay selbst wird nämlich vom Compiler
inline aufgelöst, um möglichst wenig zusätzlichen Overhead zu
haben, das ist also keine Funktion, die tatsächlich gerufen wird.
Du solltest also besser einen breakpoint dahinter setzen und dann
bis dahin arbeiten lassen. (Für eine Simulation wiederum kommt
man am besten, wenn man die Delays gleich durch eigene Funktionen
ersetzt, die sofort weitermachen.)
Ich danke Euch für Eure Antworten. Ich hab erst etwas gerätselt, ob ich
einen Umrechnungsfehler gemacht hab und 2500ms nicht 2,5 Sekunden sind.
Aber so liegt es dann doch am Compiler/Simulator :-)
Neuling schrieb:> Ich danke Euch für Eure Antworten. Ich hab erst etwas gerätselt, ob ich> einen Umrechnungsfehler gemacht hab und 2500ms nicht 2,5 Sekunden sind.> Aber so liegt es dann doch am Compiler/Simulator :-)
Du darfst nicht den Fehler machen, dein Zeitempfinden in der Simulation
als Referenz zu benutzen.
Der Simulator führt über die Simulationszeit Buch und zeigt sie dir an.
D.h. auch wenn der Simulator 5 Minuten laut deiner Armbanduhr rumrödelt,
für dich relevant ist die Zeitangabe, die der Simulator als
Simulationszeit ausgibt.
Neuling schrieb:> /* define CPU frequency in Mhz here if not defined in Makefile */> #ifndef F_CPU> #define F_CPU 1000000UL> #endif
Ich krieg die Krise wenn ich sowas lese! Das Thema hatten wir doch
letztens erst.
Die Definition von F_CPU hat in keiner .c/.h Datei etwas zu suchen,
sondern wird GLOBAL an EINER Stelle in den Projektoptionen festgelegt,
damit dies beim Aufruf des Compilers mitübergeben wird und in allen
Compilation Units eine konsistente F_CPU definiert ist.
Wenn sich die F_CPU ändert, klapper ich doch nicht jede .c/.h Datei ab
und ändere das dort. Totaler Humbug. Sowas sollte verboten und aus
Gegenwart und Historie des Internets gelöscht werden.
Das hat bisher nur einer hier richtig erwähnt:
Jim Meba schrieb:>> "warning "F_CPU not defined for <util/delay.h>" [-Wcpp]">> Kann man die Warnung einfach "übergehen"?>> Nur, wenn man delay() nicht benutzt - dann braucht man util/delay.h aber> auch nicht zu includen.>> Du musst in Deinem Makefile in den CFLAGS das F_CPU Symbol definieren.
Übrigens ist es grundsätzlich keine gute Idee, Warnungen des Compilers
zu ignorieren. Hierfür gibt es sogar beim GCC Einstellungen, um mehr
Warnungen bezüglich potentiell fehlerträchtiger Konstrukte zu generieren
und diese sogar gleich als Fehler(!) zu behandeln.
Gerade beim Casten von verschiedenen Datentypen oder
Gültigkeitsbereichen von Variablen kann einem das viel Zeit und Nerven
bei der Fehlersuche ersparen.
Simon K. schrieb:> Neuling schrieb:>> /* define CPU frequency in Mhz here if not defined in Makefile */>> #ifndef F_CPU>> #define F_CPU 1000000UL>> #endif>> Ich krieg die Krise wenn ich sowas lese! Das Thema hatten wir doch> letztens erst.
Sowas in geerbtem Code hat mir mal einen Modellbauservo getoastet...
Tom K. schrieb:> Simon K. schrieb:>> Neuling schrieb:>>> /* define CPU frequency in Mhz here if not defined in Makefile */>>> #ifndef F_CPU>>> #define F_CPU 1000000UL>>> #endif>>>> Ich krieg die Krise wenn ich sowas lese! Das Thema hatten wir doch>> letztens erst.>> Sowas in geerbtem Code hat mir mal einen Modellbauservo getoastet...
Selbst schuld. Dafür benutzt man keine Delays.
delay schrieb:> Tom K. schrieb:>> Simon K. schrieb:>>> Neuling schrieb:>>>> /* define CPU frequency in Mhz here if not defined in Makefile */>>>> #ifndef F_CPU>>>> #define F_CPU 1000000UL>>>> #endif>>>>>> Ich krieg die Krise wenn ich sowas lese! Das Thema hatten wir doch>>> letztens erst.>>>> Sowas in geerbtem Code hat mir mal einen Modellbauservo getoastet...>> Selbst schuld. Dafür benutzt man keine Delays.
F_CPU hat ja nichts mit Delays zu tun, sondern kann man ja auch selbst
benutzen um Timer zu konfigurieren.