Hallo,
ich bin ein blutiger Anfänger (habe gerade mal das Anfängertutorial auf
der Seite durchgemacht) auf diesem Gebiet und bin gerade dabei eine
Atxmega64a3u so zu programmieren dass eine kommunikation über einen
seriellen Port am PC stattfinden kann.
Ich habe um auf die <util/setbaud.h> die BAUD definiert, allerdings gibt
er mir bei der Zeile #define BAUD 9600 immer den Fehler "expected
identifier or '(' before numeric constant" aus. Ich habe das define vor
dem include gemacht weil er sonst sagt dass die BAUD definiert werden
muss.
Ich verwende AtmelStudio 6.2.
Ich wäre über jede Hilfe sehr dankbar.
es gibt einen anderen Namen 'BAUD'. Dann ist natürlich alles klar. Da
kommt jetzt alles durcheinander.
Du musst das #define für BAUD unmittelbar vor den #include für setbaud.h
ziehen.
Ji Luo schrieb:> Atxmega64a3u> #define F_CPU 64000000UL
Laut Datenblatt kann der nur 32 Mhz.
Karl Heinz schrieb:> es gibt einen anderen Namen 'BAUD'. Dann ist natürlich alles klar. Da> kommt jetzt alles durcheinander.
Da sieht man übrigens auch prima, warum es eine gute Idee ist, komplett
großgeschriebene Namen ausschließlich für Makros zu reservieren.
Karl Heinz schrieb:> Also so
Nein, das ist auch keine gute Idee. Das zerstört in der Umkehrung wieder
die TWI_MASTER_t.
Da haben die Jungs bei Atmel aber ordentlich geschlafen!
Fritz Ganter schrieb:> Das setbaud.h wird anscheinend ganz komisch eingebaut. Es soll so> aussehen:
Und selbst das ist nur die halbe Miete.
Nach der Verwendung muss das Makro wieder entfernt werden
Karl Heinz schrieb:> Fritz Ganter schrieb:>> Das setbaud.h wird anscheinend ganz komisch eingebaut. Es soll so>> aussehen:>> Und selbst das ist nur die halbe Miete.> Nach der Verwendung muss das Makro wieder entfernt werden
Eh. Klingt nach Gemurkse. Das muss besser gehen ;-)
Mark Brandis schrieb:> Karl Heinz schrieb:>> Fritz Ganter schrieb:>>> Das setbaud.h wird anscheinend ganz komisch eingebaut. Es soll so>>> aussehen:>>>> Und selbst das ist nur die halbe Miete.>> Nach der Verwendung muss das Makro wieder entfernt werden>> Eh. Klingt nach Gemurkse. Das muss besser gehen ;-)
Würde es. Wenn entweder
* Atmel besser aufgepasst hätte und nicht 2 mal denselben Identifier
benutzt hätte
oder
* In diesen Strukturen nicht einfach alles gross schreiben würde. Hab
nachgesehen: ein register8_t ist nichts anderes als ein
1
typedefvolatileuint8_tregister8_t;
es gibt daher überhaupt keinen Grund, hier
1
typedefstructTWI_MASTER_struct
2
{
3
register8_tCTRLA;/* Control Register A */
4
register8_tCTRLB;/* Control Register B */
5
register8_tCTRLC;/* Control Register C */
6
register8_tSTATUS;/* Status Register */
7
register8_tBAUD;/* Baurd Rate Control Register */
8
register8_tADDR;/* Address Register */
9
register8_tDATA;/* Data Register */
10
}TWI_MASTER_t;
alle 'Register'-Namen in Grossbuchstaben zu schreiben. Ist ja nicht so,
dass diese Grossschreibungskonvention eine der wenigen Konventionen
wäre, auf die man sich weltweit verlassen könnte. Atmel muss da wieder
sein eigenes Süppchen kochen und alles ignorieren, was sich seit 50
Jahren bewährt hat.
(Wird Zeit dass der Komet kommt)
Mein Tip für Anfänger: Ganz auf Defines und Macros verzichten und sich
auf die Sprache konzentrieren.
So kann man ein Konstante deklarieren mit
static const int Baudrate=9600;
die dann ganz normal verwendet werden kann ohne irgendwelche
Seiteneffekte durch Textersetzungen. Das macht das Leben einfacher.
PittyJ schrieb:> Mein Tip für Anfänger: Ganz auf Defines und Macros verzichten und sich> auf die Sprache konzentrieren.>> So kann man ein Konstante deklarieren mit> static const int Baudrate=9600;> die dann ganz normal verwendet werden kann ohne irgendwelche> Seiteneffekte durch Textersetzungen. Das macht das Leben einfacher.
Das ist aber nur in C++ eine echte Konstante. In C sind die einzigen
Konstanten die Zahlenwerte, die man direkt hinschreibt. Deshalb werden
dafür ja immer Makros verwendet.
Außerdem braucht deine Variable zusätzliches RAM.
Makros sind auch kein Voodoo. Wenn man sich an ein paar einfache Regeln
hält, funktionieren sie sehr gut. Ärgerlich ist es natürlich, wenn der
Lieferant einer Bibliothek sich nicht an diese Regeln gehalten hat.
Rolf Magnus schrieb:> Außerdem braucht deine Variable zusätzliches RAM.
Nur auf Harvard-Systemen. Außerhalb des AVR-Tellers liegt so etwas nur
da, wo es hingehört: Im ROM.
Ich glaube nicht, dass der To Interesse an theoretischen
Grundsatzdiskussionen hat.
Ihm gehts wohl eher darum, sein konkretes Problem zu lösen. Da er
konkret auf nem AVR unterwegs ist ist die Aussage
> Außerdem braucht deine Variable zusätzliches RAM.
zu 100% (in diesem Kontext) richtig.
Karl Heinz schrieb:> Und selbst das ist nur die halbe Miete.> Nach der Verwendung muss das Makro wieder entfernt werden>> [c]> static void> uart_38400(void)> {> #undef BAUD // avoid compiler warning
wobei dieses erste #undef wiederrum keine gute Idee ist
Wenn ausserhalb, zb auf der Command Line zum Aufruf des Compilers eine
Baudrate vorgegeben wird (jetzt mal von dem Problem mit der struct
abgesehen), dann will man die auch übernommen wissen. Wenn es eine
Warnung gibt, dass durch einen weiteren #define diese Vorgabe nichts
gilt, dann ist das ok und es soll auch so sein, dass ich als
Programmierer darauf hingewiesen werde, dass sich da was beisst.
Was aber auf keinen Fall sein darf, dass ist, dass der Compiler
angewiesen wird, eine derartige Vorgabe einfach sang und klanglos zu
ignorieren, in dem man sie ganz einfach löscht.
Das ist ganz grosser Murks. Ich weiss nicht, was sich die Atmel Leute
dabei gedacht haben. Das Beste wär wirklich, wenn sie in den sauren
Apfel beissen, und die Identifier in der Struktur umbenennen. Das gibt
jetzt ein Jahr lang Gemaule, aber dann wird wohl ein Grossteil des
bereits existierenden Codes entsprechend geändert sein und dann ist
wieder Ruhe. 'Augen zu und durch'. Je früher sie das wieder bereinigen,
desto besser. 'Abwarten und Tee trinken' ist die falsche Strategie; das
Problem regelt sich nicht von selbst.
>> #define BAUD 38400> #include <util/setbaud.h>> UBRRH = UBRRH_VALUE;> UBRRL = UBRRL_VALUE;> #undef BAUD // und: tschuess <----------
Karl Heinz schrieb:> Das Beste wär wirklich, wenn sie in den sauren Apfel beissen, und die> Identifier in der Struktur umbenennen.
Alternative: Den Namen "BAUD" für die Baudrate in "BAUDRATE" umbenennen
...
Vielen Dank euch allem, das hat mir sehr viel weitergebracht!!
Allerdings hab ich ein weiteres Problem im Moment, und zwar ist der
nächste Schritt für mich eine Kommunikation mit dem Serialport
aufzubauen. Durch ein Paar Versuche hab ich nun die In und Outputs
gesetzt. Allerdings liefert das printf keinerlei Ergebnisse, könnt ihr
mir vielleicht nochmal helfen?
Karl Heinz schrieb:> * Atmel besser aufgepasst hätte und nicht 2 mal denselben Identifier> benutzt hätte
Naja, der aus <util/setbaud.h> stammt nicht von Atmel, sondern von
der avr-libc. Der ist dort seit Oktober 2007 vorhanden. Die erste
Version der Datenblätter vom ATxmegaA / ATxmegaA1 (der ATxmega128A1
war der erste Xmega) datiert auf 02/2008. Das ist die erste
öffentliche Version, zuvor wurde innerhalb von Atmel da schon eine
ganze Weile an den Xmegas gearbeitet. Insofern ist es sehr
wahrscheinlich, dass sich die beiden Implementierungen des Makros
BAUD „überkreuzt“ haben.