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


von eletrofux (Gast)


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;
    }
  }
}
}

von Magnus Müller (Gast)


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

von eletrofux (Gast)


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

von Fred S. (Gast)


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

von eletrofux (Gast)


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

von Fred S. (Gast)


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

von eletrofux (Gast)


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

von Magnus Müller (Gast)


Lesenswert?

1
void InitUsart(void)
2
{
3
UCSRA = _BV(U2X);
4
UCSRB = _BV(TXEN)|_BV(RXEN)|_BV(RXCIE);
5
UBRRL = (F_CPU / (8 * 9600UL)) - 1;
6
}

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

von Fred S. (Gast)


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

von Magnus Müller (Gast)


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

von Fred S. (Gast)


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

von Magnus Müller (Gast)


Lesenswert?

@Fred S.

Zu langsam  ;P

Trotzdem danke für den Hinweis ;)

von Fred S. (Gast)


Lesenswert?

Hi Magnetus,
> Zu langsam  ;P
12:15 = 12:15  :-)

Gruß

Fred

von Fred S. (Gast)


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

von eletrofux (Gast)


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

von Fred S. (Gast)


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

von eletrofux (Gast)


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

von Karl H. (kbuchegg)


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.

von eletrofux (Gast)


Lesenswert?

karl heinz: guter tip. werd ich probieren.

tschü
 eletrofux

von Fred S. (Gast)


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

von eletrofux (Gast)


Lesenswert?

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

von Fred S. (Gast)


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

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.