> #define F_CPU 20E6;
Da ist der erste Fehler. Und von der Sorte hat es in Deinem Code ein
knappes Dutzend. Präprozessor-Anweisungen werden nicht mit einem
Semikolon abgeschlossen!
> DDRA = 0b10000000;
Und das ist der eigentliche Fehler, der zu der Fehlermeldung führt.
Ausführbarer Code (also jedwede Anweisung, ausgenommen Initialisierung
globaler Variablen) darf in C nur innerhalb von Funktionen stehen.
Diese Anweisung steht aber im Niemandsland.
Schnapp Dir bitte ein C-Grundlagenbuch und fange Schritt für Schritt mit
den Basics an, bevor Du mit irgendwelchen wilden Großprojekten anfängst.
Und das AVR-GCC-Tutorial ist auch empfehlenswerter Lesestoff. Die
Zeile
> #include <AVR\iom644.h>
ist z.B. auch falsch, die Device-spezifischen Header werden nie direkt
eingebunden. Das müsste eigentlich auch zumindest eine Warnmeldung
geben. Es wird nur die avr/io.h eingebunden. Der verwendete
Controllertyp wird im Makefile bzw. in den
Projekt-Konfigurations-Einstellungen angegeben.
> DDRA = 0b10000000;
Die Schreibweise der Konstanten 0b10000000 ist hier das Problem; in C
gibt es diese Schreibweise nicht.
Manche Compiler lassen das als Erweiterung des Sprachumfanges zu, aber
eben nur manche.
Du musst schon Oktal-, Dezimal- oder Hexadezimalzahlen verwenden:
DDRA = 0200;
DDRA = 128;
DDRA = 0x80;
Das kann dann auch jeder C-Compiler.
Rufus t. Firefly wrote:
>> DDRA = 0b10000000;>> Die Schreibweise der Konstanten 0b10000000 ist hier das Problem; in C> gibt es diese Schreibweise nicht.
Der AVR-GCC kennt diese Schreibweise mittlerweile aber auch! Der Fehler
ist die falsche Platzierung der Anweisung außerhalb von main().
Wo lernt man eigentlich heutzutage, dass man alles koennen kann indem
man einfach ein paar Beispiele aus dem Web zusammenklatscht? Anders kann
ich mir die hilflosen Versuche hier im Forum, mal schnell C-Programme
ohne jede Grundlagenarbeit (z.B: Buch kaufen + lesen) zu entwickeln,
kaum erklaeren :-(
> Der AVR-GCC kennt diese Schreibweise mittlerweile aber auch!
Auch wenn er das können sollte, angewöhnen sollte man sich derartiges
nicht.
Ja, das Codefragment strotzt nur so vor weiteren Fehlern.
Hätte der Threadersteller statt [\c] korrekt [/c] geschrieben, wäre sein
Code auch etwas lesbarer geworden.
1
[c]
2
#ifndef F_CPU
3
#define F_CPU 20000000;
4
#endif
5
6
#include<AVR/interrupt.h>
7
#include<stdint.h>
8
#include<stdio.h>
9
#include<stdlib.h>
10
#include<math.h>
11
#include<AVR/iom644.h>
12
//#include <AVR/io.h>
13
14
//#include "subroutines.c"
15
//#include "interrupt_table.c"
16
17
// Define data types
18
typedefuint8_tBYTE;
19
typedefuint16_tWORD;
20
typedefuint32_tDWORD;
21
typedefuint64_tQWORD;
22
23
24
25
// define switch Positions fopr various Antenna testing
Die eigenen Datentypen sollte man sich gar nicht erst angewöhnen; wofür
bitte sind denn die "neuen" definierten uint8_t etc. eingeführt worden?
Desweiteteren wird die "Warteschleife" wegoptimiert; um das zu
vermeiden, sollte "temp" als volatile deklariert werden.
Und was macht "return 1" am Ende von main()? Wohin springt das Programm
dort?
Vielen Dank für die Antworten. Ich hatte bisher immer nur in Assembler
programmiert, deshalb hatte ich die initialisierung vor der
main-Funktion angesetzt. Die Warteschleife habe ich nur programmiert um
zu sehen ob der compiler die main-Funktion akzeptiert. War wohl einfach
zu nah am Assemblercode...
Zu den eigenen Datentypen: Diese Definitionen hatte ich aus einem
Tutorial für AVR-GCC programmierung übernommen. Aber ihr habt wohl Recht
damit, dass das ganze überflüssig ist. Ich hatte sie mir halt wegen der
(für mich) besseren Lesbarkeit definiert.
Hab die Initialisierung jetzt in eine eigene Funktion gepackt und jetzt
läuft auch das ganze Programm. Vielen Dank für die Hilfe.
Rufus t. Firefly wrote:
> Die eigenen Datentypen sollte man sich gar nicht erst angewöhnen; wofür> bitte sind denn die "neuen" definierten uint8_t etc. eingeführt worden?
Wohl wahr. Aber wer kein C-Buch bzw. C-Tutorial liest, der weiß sowas
eben nicht.
> Desweiteteren wird die "Warteschleife" wegoptimiert;
Nein, die wird nicht wegoptimiert. Wenn leere while(1)-Schleifen am Ende
von main() wegoptimiert würden, gäbe es bei anderen Programmen auch
Probleme.
> Und was macht "return 1" am Ende von main()? Wohin springt das Programm> dort?
Solange 1 kleiner als 10 ist, wird gar nicht gesprungen. Und zu einer
Funktion vom Typ int gehört nunmal genau genommen ein Rückgabewert
(auch wenn man ihn hier tatsächlich weglassen könnte).
EDIT:
Gerade mal getestet:
Ohne while-Schleife am Ende von main steht da im Output ein einfaches
ret, das natürlich nirgends hinführen kann. Mit
....Auch wenn er das können sollte, angewöhnen sollte man sich
derartiges
nicht.....
Warum dat denn nicht, was?
Wenn die Binärzahlen als Schreibweise jetzt mit drin sind.
Programmierst wohl erst seit gestern , was?
Solche Leute wie dich erschweren das Wirtschaftswunder.
mfg
Johannes M. wrote:
>> Die eigenen Datentypen sollte man sich gar nicht erst angewöhnen; wofür>> bitte sind denn die "neuen" definierten uint8_t etc. eingeführt worden?> Wohl wahr. Aber wer kein C-Buch bzw. C-Tutorial liest, der weiß sowas> eben nicht.
Eigene Datentypen sind an sich keine schlechte Idee. Wenn man
beispielsweise Module schreibt, die sowohl auf AVR als auch auf ARM
funktionieren sollen, dann kann das sinnvoll sein. Für Daten, die in 8
Bits passen und als Parameter oder skalare Variablen verwendet werden,
ist bei AVR ein 8 Bit Typ effizienter, bei ARM jedoch ein 32 Bit Typ.
Nur sollten solche Typen dann als eigene Typen erkennbar sein und nicht
mit Standarddatentypen aus stdint.h kollidieren.
> Und was macht "return 1" am Ende von main()? Wohin springt das Programm> dort?
Kurz und knapp, eine nervende und unnötige Warnung eliminieren!
>> Die eigenen Datentypen sollte man sich gar nicht erst angewöhnen; wofür>> bitte sind denn die "neuen" definierten uint8_t etc. eingeführt worden?> Wohl wahr. Aber wer kein C-Buch bzw. C-Tutorial liest, der weiß sowas> eben nicht.
In den meisten C-Büchern steht nichts von uint8_t und Co. drin.
Ein Blick in das µC-Tutorial sollte für die meisten Anfangsprobleme
die passendste Lösung darstellen.
Nur so nebenbei:
Johannes M. wrote:
> Wenn leere while(1)-Schleifen am Ende> von main() wegoptimiert würden, gäbe es bei anderen Programmen auch> Probleme.
Nein. (siehe unten)
> Ohne while-Schleife am Ende von main steht da im Output ein einfaches> ret, das natürlich nirgends hinführen kann.
Klar führt das irgendwo hin, nämlich zu dem Punkt im Startup-Code, wo
main aufgerufen wurde. Dort wird nach main standardkonform zur Funktion
_exit gesprungen. Und das Default-_exit aus der AVR-Libc enthält dann
ein cli und eine Endlosschleife, hält den µC also sozusagen an.
@Stefan Ernst:
Das ist mir soweit klar, aber mir ging es um die Feststellung, dass die
while-Schleife keinesfalls, wie behauptet, wegoptimiert wird, sondern
sehr wohl an der entsprechenden Stelle im Output auftaucht.
> Und das Default-_exit aus der AVR-Libc enthält dann> ein cli und eine Endlosschleife, hält den µC also sozusagen an.
Und das führt zu einem komplett anderen Verhalten als mit
while-Schleife.
Johannes M. wrote:
> Das ist mir soweit klar, ...
Warum schreibst du dann "das natürlich nirgends hinführen kann.", das
ist schlicht falsch.
> Und das führt zu einem komplett anderen Verhalten als /mit/> while-Schleife.
Ach ja? Und was genau ist der Unterschied in diesem konkreten Fall (also
mit auskommentiertem sei)?
Stefan Ernst wrote:
> Ach ja? Und was genau ist der Unterschied in diesem konkreten Fall (also> mit auskommentiertem sei)?
Mit auskommentiertem sei() natürlich keiner.