Hallo,
Ich versuche interrupt gesteuert zeichen ueber
den usart zu empfangen. als basis dient mir
largedemo.c aus den avr-libc examples.
in vmlab funktioiert der empfang einwandfrei.
in real aber kein bischen. hier die relevanten
codefragmente:
hat jemand eine idee was ich verkehrt mache?
danke
eletrofux
---------------
....
..
volatile struct
{
uint8_t rx_int: 1;
}
intflags;
void InitUsart(void)
{
UCSRA = _BV(U2X);
UCSRB = _BV(TXEN)|_BV(RXEN)|_BV(RXCIE);
UBRRL = (F_CPU / (8 * 9600UL)) - 1;
}
ISR(USART_RXC_vect)
{
uint8_t c;
c = UDR;
if (bit_is_clear(UCSRA, FE))
{
rxbuff = c;
intflags.rx_int = 1;
}
}
int
main(void)
{
InitUsart();
sei();
while (1)
{
if (intflags.rx_int)
{
intflags.rx_int = 0;
switch (rxbuff)
{
case 'h':
printstr_p(PSTR("\nHelp Please help me Please"));
break;
}
}
}
}
Den Code hab ich mir jetzt (noch) nicht genauer angesehen.
- Welche Frequenz hat der benutzte Quarz?
- Ist dem Compiler diese Frequenz auch bekannt?
- Läuft der AVR auch wirklich mit dem externen Quarz, oder
arbeitet er evtl. noch mit dem internen RC-Oszillator?
Gruß,
Magnetus
hallo, magnetus,
der avr (ein atmega16) laeuft mit einem externen 16Mhz quarz.
die konfiguration des quarzes habe ich mithilfe peter dannegers
genauer sekunden routine getestet (bilke licht im sekunden takt).
sehr kniffliges problem.
mfg
eletrofux
Hi,
welchen Prozessor setzt Du ein? Bitte nenne uns die gewünschte Baudrate
und F_CPU. Warum ist U2X gesetzt? Bitte stelle auch die Deklaration
Deiner globalen Variablen ein.
Gruß
Fred
hi fred,
ich setze den atmega16 @ 16 mhz ein. die baudrate betraegt
9600 Baud. denkst du es koennte am u2x liegen?
volatile char rxbuff;
mehr is ja nich.
mfg
eletrofux
Hallo eletrofux,
> ich setze den atmega16 @ 16 mhz ein. die baudrate betraegt> 9600 Baud. denkst du es koennte am u2x liegen?
Dann stimmt Deine Berechnung für UBRR(L/H)! Schreibe aber besser
UBRR=...; obwohl der Wert in ein Byte passt und UBRRH bei RESET 0 ist.
Weshalb hast Du auch TXEN gesetzt? (Ich nehme mal an, Deine Ausgabe
geschieht über den UART?)
Ich schaue mir Deinen Code gleich noch einmal im Detail an.
Gruß
Fred
hi fred,
ohne TXEN kein senden via USARt möglich.
die usart routinen habe ich unterschlagen.
sind aber defaultkram. TX funktioniert mit
den USART settings im übrigen sehr gut.
also die ausgabe von zeichen klappt problemlos.
allein mit dem receive interrupt hat es was.
bin leider im moment nicht in hardwarenaehe und kann
daher nichts ueberpruefen.
u2x werde ich aufjedenfall mal rausnehmen. wenn dir
sonst noch etwas auffaellt. bidde einfach losposten :)
danke
eletrofux
UBRRL = (16000000/(8*9600))-1) = 207
Bei gesetztem U2X ergibt das tatsächlich die gewünschten 9600 Baud.
Mir fällt gerade auf, dass du UCSRC nicht initialisierst. Durch das
Nichtinitialisieren läuft dein USART schon mal mit nur 5 Bits an Stelle
der (vermutlich) gewünschen 8 Bits.
Gruß,
Magnetus
Hallo,
im Code sehe ich nur einen echten Fehler: FE ist nur bis zum Lesen von
UDR gültig -- Du solltest den Code also so ändern, dass zuerst der
Status, dann UDR gelesen werden.
Kann Dein Terminal (oder was immer Du zur Kommunikation einsetzt) denn
die Strings vom ATmega lesen?
Gruß
Fred
Magnus Müller wrote:
> Mir fällt gerade auf, dass du UCSRC nicht initialisierst. Durch das> Nichtinitialisieren läuft dein USART schon mal mit nur 5 Bits an Stelle> der (vermutlich) gewünschen 8 Bits.
Ups... Quatsch mit Soße...!
Hab gerade gesehen, dass die Wortlänge nach Reset standardmäßig auf 8
Bit gesetzt ist (schäm)
Gruß,
Magnetus
Hallo Magnetus,
> Mir fällt gerade auf, dass du UCSRC nicht initialisierst. Durch das> Nichtinitialisieren läuft dein USART schon mal mit nur 5 Bits an Stelle
Das sehe ich anders, denn nach einem RESET gilt: UCSZ0=UCSZ1=1, also 8
Bit!
Viele Grüße
Fred
Hi eletrofux,
> u2x werde ich aufjedenfall mal rausnehmen. wenn dir> sonst noch etwas auffaellt. bidde einfach losposten :)
Nein, lass es drin (siehe Posts von Magnetus und mir)!
Gruß
Fred
magnetus: jomei! mich hätest beinahe ueberzeugt ;)
hallo fred,
udr und status auslesen werd ich dann mal verdrehen.
mein terminal ist ein stinknormaler pc mit uart und
minicom als terminalsoftware.
mein terminal zeigt mir gesendete ascii zeichen wie
erwartet an.
mfg
eletrofux
Hi eletrofux,
> mein terminal ist ein stinknormaler pc mit uart und> minicom als terminalsoftware. ...> mein terminal zeigt mir gesendete ascii zeichen wie> erwartet an.
Das beweist zwar noch nicht, dass das Problem nicht an einer kleinen
Abweichung der Baudate hängt, macht das aber sehr unwahrscheinlich. Nimm
doch die Fehlererkennung erst einmal ganz aus der ISR heraus (DOR
überprüfst Du ja auch nicht).
Viel Erfolg,
Fred
Hallo,
Danke mal an alle beiteiligten. Werde Freds Rat folgen und
mal den FE check entfernen.
sollte das nciht funktionieren werde ich mal mit den
baudrate settings herumspielen... mal hoeher, mal niedriger.
mal mit mal ohne u2x.
wenn das alles nicht fruchtet werde ich mich montags nochmal
melden. dann aber mit dem kompletten code.
schoenes wochenende mitnand'
eletrofux
eletrofux wrote:
> Hallo,>> Danke mal an alle beiteiligten. Werde Freds Rat folgen und> mal den FE check entfernen.
Du kannst ja auch mal testen ob die ISR überhaupt aufgerufen
wird. Led an einen Portpin und in der ISR einschalten.
Hallo Karl heinz,
> Du kannst ja auch mal testen ob die ISR überhaupt aufgerufen> wird. Led an einen Portpin und in der ISR einschalten.
Danke, dass Du hier eine so effektive wie einfache Debugging-Hilfe
erwähnst. Das mit der LED hätte ich selbst auch so gemacht, aber eben
nicht vorgeschlagen. Viele Fragen würden sich von selbst erledigen, wenn
jeder so simple Methoden einsetzte. Ich glaube immer noch, dass der
undefinierte Status von FE das Hauptproblem oben ist.
Gruß
Fred
Hi eletrofux,
> Es ist nicht leicht zu blinke leds zurueck zu kehren> wenn man bereits dabei zeichenketten durch den UART> zu jagen :)
Doch -- aber wenn die UART-Kommunikation erst einmal klappt, dann machst
Du die Fehlersuche, indem Du den uC Zeichenketten via UART ausgeben
lässt. Damit ist dann das "Blinke-LED-Stadium" überwunden. Aber ab und
zu muss man doch wieder dahin zurück...
Viele Grüße
Fred