Hallo,
ich habe vor einiger Zeit mit der UART beschäftigt habe aber noch sehr
starke Defiziete an mir erkannt welche das Programmieren fast unmöglich
macht!
Im Anhang habe ich ein Programm welches auch aus diesem Forum stand, hab
aber Probleme es auf einem ATmega128 zum laufen zu bringen.
Wenn ich es kompiliere bekomme ich folgende Fehlermeldungen:
Compiling C: main.c
avr-gcc -c -mmcu=atmega128 -I. -gdwarf-2 -DF_CPU=8000000UL -Os
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall
-Wstrict-prototypes -Wundef -Wa,-adhlns=obj/main.lst -std=gnu99 -Wundef
-MD -MP -MF .dep/main.o.d main.c -o obj/main.o
main.c: In function `SendImmidate':
main.c:28: error: `UCSRA' undeclared (first use in this function)
main.c:28: error: (Each undeclared identifier is reported only once
main.c:28: error: for each function it appears in.)
main.c:31: error: `UDR' undeclared (first use in this function)
main.c: At top level:
main.c:35: warning: return type defaults to `int'
main.c:35: warning: function declaration isn't a prototype
main.c: In function `ISR':
main.c:35: warning: type of "USART_RXC_vect" defaults to "int"
main.c:36: error: `UDR' undeclared (first use in this function)
main.c: At top level:
main.c:49: warning: function declaration isn't a prototype
make.exe: *** [obj/main.o] Error 1
Es scheint als wäre meine UART Routine irgendwie nicht auf dieses
Programm abgestimmt. Meine uart.c sieht folgendermaßen aus:
1
#include<avr/io.h>
2
#include"uart.h"
3
4
voiduart_init(void){
5
UBRR0H=0x0;// UART auf 9600 baud
6
UBRR0L=0x5F;// UBRR= (fquarz/ (16* BAUD) ) -1
7
8
UCSR0B=0x18;// Transmitter und Receiver einschalten
9
UCSR0C=0x86;// 8 bit 1 Stop No Parity
10
11
}
12
charuart_data_available(void){
13
if(((UCSR0A>>RXC)&1)==0)return0;
14
elsereturn1;
15
}
16
17
charuart_read(void){// Achtung ist noch blockierend!!!!
18
19
while(((UCSR0A>>RXC)&1)==0){}// Warten bis RXC-Bit in UCSRA gesetzt
20
21
returnUDR0;// Zeichen abholen
22
}
23
24
voiduart_send(chardata){// Achtung ist noch blockierend!!!!
25
26
27
while(((UCSR0A>>UDRE)&1)==0){
28
29
}// warten bis UART sendebereit
30
31
32
UDR0=data;
33
}
Wer kann mir helfen meine Probleme zu lösen und mir dabei auch noch
einwenig zu erleutern. Bitte beachtet das ihr einen ich sag mal Anfänger
in AVR Programmierung vor euch habt. ;-)
P.S. Um unnötige Postings zu vermeiden: Ich habe mir die Turorials auf
dieser Seite schon angeschaut sind aber leider nicht sehr hilfreich
gewesen.
Vielen Dank schonmal im Vorraus!
Gruß Philipp
Die erste und zweite Fehlermeldung
main.c:28: error: `UCSRA' undeclared (first use in this function)
main.c:31: error: `UDR' undeclared (first use in this function)
sollte Dir zu Denken geben. Das bedeutet, daß die von Dir verwendeten
symbolischen Bezeichner für die I/O-Register Deines AVR nicht bekannt
sind.
Das kann daran liegen, daß
- Du nicht die korrekte Headerdatei einbindest
- Du zwar die korrekte Headerdatei einbindest, die interessanten Teile
darin aber per bedingter Compilierung ausgeblendet werden, weil Du dem
Buildsystem nicht mitgeteilt hast, daß Du einen AVR mit Hardware-UART
verwendest
Interessanterweise aber passen die von Dir geposteten Fehlermeldungen
nicht zum von Dir geposteten Quelltext, darin tauchen die betreffenden
Namen nämlich gar nicht auf - was auch gar kein Wunder ist, denn Du hast
den Quelltext der Funktion "SendImmidate" auch gar nicht gepostet, in
dem aber die Fehler gefunden werden, wie der Compiler auch mitteilt.
Im übrigen schreibt man es korrekt "SendImmediate". Wenn schon
englischsprachige Begriffe für Funktionsnamen verwendet werden müssen,
dann doch bitte auch korrekt geschriebene.
Die vielen Fehlermeldung kommen daher, dass das Programm im Anhang
vermutlich für einen anderen Controllertyp geschrieben ist. Daher sind
die Namen der I/O-Register unterschiedlich.
Bsp.: Das UART-Datenregister heißt UDR bei Controllern mit nur 1 UART,
sonst UDR0, UDR1 usw.
Der Fehler in Zeile 35 (ISR ...) kommt wohl daher, dass
avr/interrupt.h nocht includiert wurde.
Was ist mit deinen eigenen Routinen, funktionieren die auch nicht? Da
scheinen zumindest die Registernamen richtig zu sein.
@yalu:
Danke für den Hinweis mit dem Interrupt! Somit sind die Fehler des ISR
weg.
Da mein ATmega also 2 UARTS hat muss ich die Bezeichnungen in meiner
Main.c der der Uart.c anpassen, oder?
Was meinst du mit eigenen Routinen? Eigentlich hab ich euch alles
zukommen lassen womit ich arbeitete (main.c, uart.c)
@rufus:
Die Fehlermeldungen beziehen sich auch auf meine Main.c und nicht auf
die uart.c
Und der Rechtschreibfehler war schon da als ich mir das Prog. hier aus
diesem Forum geholt hab. :-)
Vielen dank schonmal!!!
Philipp wrote:
> Die Fehlermeldungen beziehen sich auch auf meine Main.c und nicht auf> die uart.c
Ist natürlich auch eine Möglichkeit:
Wenn der Compiler dir sagt, dass in main.c ein paar Fehler
drinn sind, dann einfach die uart.c in den Posting-Text mit
aufzunehmen, in der keine Fehler drinn sind :-)
Die Tatsache, dass mitlerweile wahrscheinlich schon ein paar
...zig Leute deine uart.c studiert haben, während gerade
mal 3 dein main.c aus dem Anhang geholt haben sollte dir zu
denken geben.
Naja ich dachte halt da es sich um Uart Fehler handelt das ich euch auch
noch eben meine uart zeige!
Hab aber jetzt einige Problem behandeln können...finde nur nicht die
richtige Bezeichnung für den letzten Fehler.
Meine Aktuelle Fehlermeldung:
Compiling C: main.c
avr-gcc -c -mmcu=atmega128 -I. -gdwarf-2 -DF_CPU=8000000UL -Os
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall
-Wstrict-prototypes -Wundef -Wa,-adhlns=obj/main.lst -std=gnu99 -Wundef
-MD -MP -MF .dep/main.o.d main.c -o obj/main.o
main.c:35: warning: `USART_RXC_vect' appears to be a misspelled signal
handler
Linking: main.elf
avr-gcc -mmcu=atmega128 -I. -gdwarf-2 -DF_CPU=8000000UL -Os
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall
-Wstrict-prototypes -Wundef -Wa,-adhlns=obj/main.o -std=gnu99 -Wundef
-MD -MP -MF .dep/main.elf.d obj/main.o --output main.elf
-Wl,-Map=main.map,--cref -lm
C:/Programme/WinAVR/bin/../lib/gcc/avr/3.4.6/../../../../avr/lib/avr5/cr
tm128.o: In function `__vectors':
../../../../../avr-libc-1.4.4/crt1/gcrt1.S:51: undefined reference to
`main'
make.exe: *** [main.elf] Error 1
Philipp wrote:
> @yalu:> Da mein ATmega also 2 UARTS hat muss ich die Bezeichnungen in meiner> Main.c der der Uart.c anpassen, oder?
Ja.
Allerdings hast du die falsche Begründung.
Du sollst in main.c die Bezeichnungen nicht ändern, weil sie in uart.c
auch so sind. Du sollst sie ändern, weil auf deinem AVR die
Dinge nun mal so heissen.
Aber noch viel wichtiger: Eine Datei Namens uart.c impliziert
zumindest für mich, dass dort alle UART Routinen gesammelt sind.
D.h. aber auch, dass es in main.c gar keine UART Routinen geben
sollte. Insofern sollst du also in main.c gar nichts anpassen,
sondern die Routinen nach uart.c verschieben, bzw. mit den
dort vorhandenen verschmelzen.
Philipp wrote:
> ../../../../../avr-libc-1.4.4/crt1/gcrt1.S:51: undefined reference to
So wie es der Compiler sagt:
Es gibt keine Funktion namens main()
Die braucht er aber, da in dieser Funktion per C-Konvention
die Programmausführung beginnt.
Das hier
> main.c:35: warning: `USART_RXC_vect' appears to be a misspelled signal> handler
solltest du nicht auf die leichte Schulter nehmen.
Wenn der Compiler sagt, dass die Bezeichnung USART_RXC_vect
nicht mit den Interrupt Namen übereinstimmt, die er kennt,
dann kannst du ihm das auch glauben, dass das tatsächlich
so ist: Es gibt auf einem Mega128 keinen Interrupt, der
USART_RXC_vect heist. Teil des Problems wird wohl sein,
dass es auf einem Mega128 nicht 1 sondern 2 USART gibt.
Welche USART soll den nun den Interrupt auslösen?
Also ich glaube das beide UARTS empfangen und senden können also ist es
im Grunde genommen ja egal welchen ich nehme aber nur um die Frage zu
beantworten natürlich den 1.
Was genau mach ich eigentlich mit diesem Befehl? "USART_RXC_vect"
Philipp wrote:
> Also ich glaube das beide UARTS empfangen und senden können also ist es> im Grunde genommen ja egal welchen ich nehme aber nur um die Frage zu> beantworten natürlich den 1.
Und wie konfigurierst du dann, dass USART 1 bei einem Empfang
einen Interrupt auslösen soll und USART0 nicht?
>> Was genau mach ich eigentlich mit diesem Befehl? "USART_RXC_vect"
Das ist kein Befehl.
Das ist die Bezeichnung eines Interrupts. Konkret des Interrupts
der aufgerufen werden soll, wenn das Ereeignis 'USART hat
ein Byte empfangen' eintritt. Da du aber 2 USART hast, gibt
es logischerweise auch 2 Interruptbezeichnungen. Eine für
die USART 0 und eine für die USART 1.
Ich rate jetzt einfach mal
USART0_RXC_vect
Das war nicht wirklich schwer zu raten, oder?
Das Konfigurationsregister heist nicht UCSRA sondern USCR0A.
Das Datenregister des UART heist nicht UDR sonern UDR0.
Wie also wird der Receiver Interrupt der UART 0 heissen?
Ansonsten machst du in deinem AVR Studio einfach mal die
Datei iom128.h auf (die ist im Projekt dabei) und scrollst durch
bis du auf den richtigen Abschnitt stösst. (Oder aber du
benutzt die Suche und lässt nach USART suchen)
Vielen Dank! Hab mir die Lib angeschaut und auch die richtigen
Bezeichnungen gefunden. Aber wenn ich jetzt versuche zu kompilieren
meckert er wegen dem Vektor?
Compiling C: main.c
avr-gcc -c -mmcu=atmega128 -I. -gdwarf-2 -DF_CPU=8000000UL -Os
-funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall
-Wstrict-prototypes -Wundef -Wa,-adhlns=obj/main.lst -std=gnu99 -Wundef
-MD -MP -MF .dep/main.o.d main.c -o obj/main.o
main.c:38: warning: return type of 'main' is not `int'
main.c: In function `main':
main.c:40: warning: static declaration of '__vector_18' follows
non-static declaration
main.c:39: warning: previous declaration of '__vector_18' was here
Was ist das Überhaupt?
hallo,
der Compiler gibt dir die entsprechenden hinweise schon:
in zeile 39 deklarierst du etwas, was du eine zeile später noch einmal
deklarierst, aber leicht abgewandelt.
dekalrieren kannst du natürlich, wie du lustig bist, nur sollten die
qualifier auch übereinstimmen. ist letztendlich nur eine warnung, aber
ist ein hinweis darauf, dass da was nicht ganz iO ist.
bye kosmo
hallo,
ist alles bischen seltsam. vermutlich hast du wieder im code
rumgefrickelt, der hinweis vom compiler auf das main in zeile 38 deutet
darauf hin. entsprechend passt das von dir gepostete main.c nicht mehr,
und so kann nur geraten werden.
musst nochmal posten zur not,
bye kosmo
So jetzt läufts...hatte den Interrupt in die Main geschrieben.
Jetzt hät ich da noch ne Frage und zwar wie wird der Interrupt
ausgelößt? In der Beschreibung des Interrupts steht das er ihn auslößt
sobald er ein Zeichen empfängt. Muss ich diesen Interrupt jetzt in
meiner Main irgendwie aktivieren oder macht er das Automatisch wenn er
ein Zeichen empfängt?
Hab mein Programm mal im Anhang gepackt! Um kurz zu erleutern was ich
mit meinem Programm eigentlich machen will. Ich möchte im Hyperterminal
meines PC ein Zeichen an mein ATmega128 schicken bis er mir sagt "Voll"
(Möchte ich auch im Hyperterminal angezeigt bekommen) und sobald er dann
wieder "Leer" ist kann das Datenschicken weitergehen. u.s.w
Die Daten die ich an mein Modul schicke müssen "vorerst" nicht
gespeichert werden und dürfen so verfallen.
hallo,
du musst den mikrocontroller selbestverständlich dazu bringen,
interrupts zuzulassen.
steht alles in der doku.
ein kurzes "sei()" in der main wird's tun, schätze ich.
bye kosmo