www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik AVR - USART RX via Interrupt, funktioniert nicht


Autor: eletrofux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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;
    }
  }
}
}

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: eletrofux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Fred S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: eletrofux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Fred S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: eletrofux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
void InitUsart(void)
{
UCSRA = _BV(U2X);
UCSRB = _BV(TXEN)|_BV(RXEN)|_BV(RXCIE);
UBRRL = (F_CPU / (8 * 9600UL)) - 1;
}

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

Autor: Fred S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Fred S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Magnus Müller (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Fred S.

Zu langsam  ;P

Trotzdem danke für den Hinweis ;)

Autor: Fred S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Magnetus,
> Zu langsam  ;P
12:15 = 12:15  :-)

Gruß

Fred

Autor: Fred S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: eletrofux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Fred S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: eletrofux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: eletrofux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
karl heinz: guter tip. werd ich probieren.

tschü
 eletrofux

Autor: Fred S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: eletrofux (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist nicht leicht zu blinke leds zurueck zu kehren
wenn man bereits dabei zeichenketten durch den UART
zu jagen :)

Autor: Fred S. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.