Hi
ich versuche momentan mit dem Rechner und meinem Atmega32 eine Uart
Kommunikation aufzubauen. Nun kann ich Zeichen zum Terminalprogramm
schicken, aber ich bekomm nichts empfangen, obwohl der Interrupt
ausgelöst wird.
Kann mal jemand über den Code schauen. Achja, der Uart-Code kommt von
Fleurys HP, den Interruptcode habe ich hier aus dem Tutorial und den
uart_gets code nutze ich momentan nicht.
Vielen Dank
Nochmal genauer:
Wenn ich Zeichen vom Terminal bekomme, wird der Interrupt ausgelöst,
aber der empfangene String wird nicht zurückgesendet und auch nicht auf
dem LCD gezeigt. Es entsteht nur eine leere Zeile
das uart_str_complete=1; habe ich oben nur eingefügt, um zu wissen, ob
der interrupt funktioniert
was ist mit ISR(SIG_USART_RECV) los? der interrupt geht doch...
Bastler07 schrieb:> was ist mit ISR(SIG_USART_RECV) los? der interrupt geht doch...
Ja aber nur bei wenigen alten AVRs. Bei den neueren gibt es die alten
Namen schon nicht mehr. Korrekter wäre:
1
ISR(USART_RXC_vect)
Die alten "SIG_*" Namen stammen aus einer Zeit, als es noch kein "ISR"
Makro gab und man statt dessen "INTERRUPT" und "SIGNAL" benutzt hat und
jeder Neuling damit erstmal fürchterlich auf die Nase gefallen ist, weil
er beide verwechselt hat.
okay, danke
das hilft mri schonmal weiter
habe gerade mal ISR(USART_RXC_vect) eingefügt, nun fällt mir ein, dass
hatte ich vorher drin, aber ich bekomme immer die Meldung
../MultiPong.c:51: warning: 'UART_RXC_vect' appears to be a misspelled
signal handler
klar, mit dem uart_str_complete=1; wird die if anweisung ja umgangen
vollkommen übersehen
kannst du mir auch noch den Fehler für das nicht empfangen des strings
nennen?
danke nochmal
Bastler07 schrieb:> okay, danke> das hilft mri schonmal weiter>> habe gerade mal ISR(USART_RXC_vect) eingefügt, nun fällt mir ein, dass> hatte ich vorher drin, aber ich bekomme immer die Meldung>> ../MultiPong.c:51: warning: 'UART_RXC_vect' appears to be a misspelled> signal handler
Der heisst auch
USART_RXC_vect
und nicht
UART_RXC_vect
Wenn du dir nicht sicher bist, wie der Interrupt auf deinem µC heisst,
dann sieh in der iom32.h nach. AVR Studio müsste diese Datei unter
"External Dependencies" führen. Dort finden sich neben vielen anderen
Sachen, auch die Namen der INterrupt Vektoren.
Eines würde mich noch interessieren.
Wie hast du das
nextChar = UDR0;
durch den Compiler gekriegt? Der Mega32 hat nur eine UART und bei dem
heisst das USART Data Register UDR und nicht UDR0.
> klar, mit dem uart_str_complete=1; wird die if anweisung ja umgangen> vollkommen übersehen>> kannst du mir auch noch den Fehler für das nicht empfangen des strings> nennen?
Das
uart_str_complete=1;
IST der Fehler der dafür verantwortlich ist. Deine Empfangsroutine
meldet viel zu früh, dass die Zeile komplett empfangen wurde. Nämlich zu
einem Zeitpunkt, an dem noch gar kein String zusammengebaut wurde.
Karl Heinz Buchegger schrieb:
> Der heisst auch> USART_RXC_vect> und nicht> UART_RXC_vect
ich habe beides probiert, die Warnung bleibt
../MultiPong.c:51: warning: 'UART_RXC_vect' appears to be a misspelled
signal handler
und nach dem löschen von uart_str_complete=1; gehts trotzdem noch nicht
so hatte ich es ja auch in meiner ersten Version, da dachte ich dann, er
kommt nicht zum interrupt und habe es daher nochmal davor eingefügt
irgendwie ist da noch was falsch
Bastler07 schrieb:> Karl Heinz Buchegger schrieb:>> Der heisst auch>> USART_RXC_vect>> und nicht>> UART_RXC_vect>> ich habe beides probiert, die Warnung bleibt> ../MultiPong.c:51: warning: 'UART_RXC_vect' appears to be a misspelled> signal handler
Wenn in der Fehlermeldung steht, dass UART_RXC_vect ein nicht bekannter
Interrupt Vektor ist, dann kannst du nicht USART_RXC_vect (mit einem S
nach U und vor A) geschrieben haben, denn dann würde die Fehlermeldung
sagen, dass USART_RXC_vect ein unbekannter signal handler ist. Tut es
aber nicht. Die Fehlermeldung spricht von UART_RXC_vect, ohne das S
zwischen U und A.
Aber da du offenbar UDR0 durch den Compiler kriegst, gehe ich mal davon
aus, dass du entweder deinen Compiler oder uns angelogen hast und
entweder hast du im AVR-STudio keinen Mega32 eingestellt oder du hast
keinen Mega32. Auf jeden Fall stimmt da aber was nicht.
Alle UART Register und sonstige Dinge, die mit UART zu tun haben, haben
nur dann eine Zahl dahinter (wie bei UDR0), wenn es mehr als 1 UART
gibt. Das ist immer so und gilt auch für alles. Wenn du also 2 USART im
µC hast, dann hast du ein UDR0 und ein UDR1. Du hast dann aber auch
logischerweise ein USART_RXC0_vect und einen USART_RXC1_vect.
Ein Mega32 hat aber keine 2 UART, sondern nur eine.
Daher heisst das Empfangsregister dort UDR und der Interrupt Vektor
heißt USART_RXC_vect.
> und nach dem löschen von uart_str_complete=1; gehts trotzdem noch nicht
Dann zeig dein Programm wie es jetzt aussieht.
Aber in compilierbarer Form (keine Fehlermeldungen oder Warnungen mehr)!
oh, da gibt es wohl ein missverständnis
ich habe den Atmega324p und dachte das ist ein Atmega32
jedenfalls habe ich bei meinem 324p 2 USARTs und möchte USART0 verwenden
Bastler07 schrieb:> oh, da gibt es wohl ein missverständnis> ich habe den Atmega324p und dachte das ist ein Atmega32
Was eine falsche Zahl alles ausmachen kann :-)
> Warning:> warning: 'USART_RXC0_vect' appears to be a misspelled signal handler
Ok.
In deinem Projekt Baum im AVR Studio sind alle Files aufgeführt. Da gibt
es unter "External Dependencies" eine iom324.h
Wenn man da reinschaut sieht man, dass da die Definitionen nicht drinnen
sind. Aber es gibt noch eine zweite iom Datei: die IOMXX4.H
Und wenn man in der nach USART sucht, dann findet sich der Interrupt
Vektor
USART0_RX_vect
zusammen mit dem Kommentar
/* USART0, Rx Complete */
Bingo. Der ist es.
So sucht man Namen, die man nicht kennt, wenn man nicht sowieso im
Datenblatt nachsieht. Alle prozessorspezifischen Dinge sind immer in
einem Header File, das den Namen IOM und einen prozessorspezifischen
Postfix trägt. Dort kann man nachsehen und mit den richtigen
Suchbegriffen wird man meistens auch recht schnell fündig.
Bastler07 schrieb:> liegt das vielleicht an einem falschen Cast?
Oder an einer falsch übersetzten Library?
Haste die Fleury Lib für den m324 compiliert?
Bastler07 schrieb:> die Warnung ist nun weg, allerdings kommen die Zeichen noch nicht an
Erstmal ein paar Bemerkungen zu Deinem Source:
volatile uint8_t uart_str_count = 0;
Diese Variable benutzt Du nur in der ISR, Du kannst sie also in der ISR
lokal definieren, nämlich als:
static uint8_t uart_str_count;
Die Funktion uart_gets() kann komplett weg, sie wird nicht benutzt und
verwirrt hier nur.
Woher weisst Du, dass die ISR überhaupt aufgerufen wird? Ich sehe
nämlich nirgendwo die Freigabe für USART0_RX_vect.
Gruß,
Frank
Helfer schrieb:> Oder an einer falsch übersetzten Library?> Haste die Fleury Lib für den m324 compiliert?
Wie ist das gemeint? Habe da nichts kompiliert, habe einfach die header
und die c datei eingebunden
Frank M. schrieb
> Woher weisst Du, dass die ISR überhaupt aufgerufen wird? Ich sehe> nämlich nirgendwo die Freigabe für USART0_RX_vect.
Die Freigabe passiert doch über
1
if(uart_str_complete==1)
in meiner main funktion. Diese wurde vorher mal passiert, da ich Erfolg
auf meinem Display bekam.
in
> meiner main funktion.
Du hast mich falsch verstanden: Es reicht nicht, global die Interrupts
über sei() freizuschalten, Du musst auch noch Deine ISR gezielt
"enablen", siehe
http://www.mikrocontroller.net/articles/AVR-GCC-Tutorial/Der_UART#Empfangen_.28RX.29
(RXCIE spielt hier die Rolle)
Oder macht das bei Dir das uart_init()? Ich kann mir nicht vorstellen,
dass die LIB, die Du benutzt, standardmäßig auf Interrupt-Betrieb
ausgerichtet ist.
gute idee, aber das wird eigentlich über die uart_init() erledigt. Mein
Compiler definiert doch den Atmega, so werden die defines freigeschaltet
und somit die if-Bedinung in der Funktion uart_init() ausgeführt.
Oder muss ich nochmal extra meinen Atmega definieren?
aus Fleury`s uart lib:
Und was hast du mit der Receive-Interrupt-ISR vom Fleury-Code gemacht?
Gelöscht, auskommentiert, oder was? Dass es nicht 2 ISRs zum gleichen
Interrupt geben kann, ist dir doch klar, oder?
Bastler07 schrieb:> gute idee, aber das wird eigentlich über die uart_init() erledigt.
Hast Du das _BV(RXCIE) dort reingebastelt oder war das schon drin? Wenn
letzterers, muss es doch dort auch schon eine ISR dafür geben? Wenn ja,
welche wird dann benutzt? die aus der Lib oder Deine eigene?
Eigentlich ist das Unsinn, dass Du eine LIB benutzt, die Du dann
"hintenrum" durchlöcherst wie ein Schweizer Käse (wie z.B. durch eigene
ISR bzw. durch eigenes uart_gets()).
Stimmt, ihr habt recht. Eigentlich wollte ich mir so eben was aufbauen,
aber damit habe ich mir wohl mehr Probleme gemacht als alles andere.
Ich bin gegen abend wieder zuhause und werde es dann mal vernünftig und
komplett neu aufbauen.
Ich melde mich dann heute abend wieder.
Danke für die Hilfe
Bastler07 schrieb:> der aufgräumte code, allerdings bleit das problem gleich> der atmega kann zum terminal senden, aber nicht empfangen
Wie testest du?
Druck auf Return vergessen?
Füg hier mal ein Echo ein
> ISR(USART0_RX_vect)> {> unsigned char nextChar;>> // Daten aus dem Puffer lesen> nextChar = UDR0;
uart_putc( nextChar );
> if( uart_str_complete == 0 ) { // wenn uart_string gerade in> Verwendung, neues Zeichen verwerfen>> // Daten werden erst in string geschrieben, wenn nicht> String-Ende/max Zeichenlänge erreicht ist/string gerade verarbeitet wird> if( nextChar != '\n' &&> nextChar != '\r' &&> uart_str_count < UART_MAXSTRLEN - 1 ) {> uart_string[uart_str_count] = nextChar;> uart_str_count++;> }> else {> uart_string[uart_str_count] = '\0';> uart_str_count = 0;> uart_str_complete = 1;> }> }> }
Jetzt schickt der µC gleich alles zurück, was über die UART reinkommt
und du tippst nicht mehr im Dunkeln.
hi
klasse, das war schonmal ein super hinweis, nun geht es fast komplett
ich schick test\n hin und er schickt mir test\n zurück (durch die neu
eingefügte ausgabe, aber nicht über den interrupt)
dann schicke ich nach kurzer zeit nochmal hallo hin
dann schickt er über interrupt folgendes:
hallotest\nhal
das erste hallo kommt noch von der neuen Ausgabe, der weitere Teil ist
dann der korrekte Teil, allerdings der vorige noch dabei und auf 10
Zeichen begrenzt
Er wartet also immer, bis die vollen 10 Zeichen empfangen wurde und gibt
dann erst das uart_str_complete=1 raus
Wieso nimmt er also die \n oder \r zum beenden meines Strings nicht
wahr? Kann das am Terminalprogramm liegen? Ich nutze HTerm und shcicke
ASC
Viele Dank
Wie genau schickst du \n ?
Das ist die C Schreibweise für Return (die große Taste mit dem Haken
drauf) und nicht für die beiden Tasten '\' und dann 'n'.
Karl Heinz Buchegger schrieb:> Wie genau schickst du \n ?>> Das ist die C Schreibweise für Return (die große Taste mit dem Haken> drauf) und nicht für die beiden Tasten '\' und dann 'n'.
Das ist nicht ganz korrekt. Standardmäßig schickt ein
Terminal-Emulationsprogramm beim Drücken der RETURN-Taste ein CR, was
einem '\r' entspricht. Dieses sollte man "echoen" mit "\r\n" (CRLF, also
Wagenrücklauf mit anschließendem Zeilenvorschub). Wenn man nur das '\r'
als Echo zurückschickt, dann hat man den hässlichen Effekt, dass der
Cursor lediglich an den Anfang der Zeile gestellt wird, aber keine neue
Zeile erzeugt wird.
Ein '\n' kann man in einer Terminal-Emulation nur mit STRG-J schicken,
das entspricht dem LF (Hex 0A) und damit dem '\n'.
Wie gesagt, das gilt für die Standard-Konfiguration einer
Terminal-Emulation. Einige kann man auch umstellen, dass beim Drücken
der RETURN-Taste ein CRLF ("\r\n") oder nur ein LF ('\n'= geschickt
wird. Würde ich aber nicht umstellen in der Konfiguration, denn beim
Wechsel auf ein anderes Programm oder PC hat man das Problem wieder.
Man muss sich einfach dran gewöhnen, dass der PC ein CR schickt und man
das als CRLF "echoen" sollte.
Gruß,
Frank
Bastler07 schrieb:> der aufgräumte code, allerdings bleit das problem gleich> der atmega kann zum terminal senden, aber nicht empfangen
Eins fällt mir direkt auf: Du schneidest beim Empfang \r und auch \n ab,
d.h. sie stehen nicht im Empfangspuffer uart_string. Beim Zurücksenden
von uart_string vergisst du aber, diese Zeichen wieder zurückzusenden.
Am einfachsten machst Du das in main durch:
1
uart_puts((char*)uart_string);
2
uart_puts("\r\n");// CRLF hinzufügen!
Und nochmal mein Hinweis, dass Du uart_str_count direkt als
static-Variable in der ISR definieren kannst, dann brauchst Du auch
keine volatile-Deklaration, was Dein Programm auf jeden Fall ein
Stückchen "effizienter" macht.
Also: