Forum: Mikrocontroller und Digitale Elektronik UART-Interrupt wird nicht ausgelöst


von Sam (Gast)


Lesenswert?

Hallo alle zusammen,

ich sitze hier gerade an einem kleinen Problem, das ich so noch nie 
hatte. Ich will von meinem PC per UART Befehle an den Atmega328P senden. 
Der soll diese mithilfe des RXC-Interrupts entgegennehmen.
Allerdings löst dieser Interrupt nicht aus. Das erkenne ich daran, dass 
keine Antwort kommt, die ich als erste im Interrupt senden lasse.
Die Daten kommen an, ich kann sie per Polling empfangen, allerdings ist 
das nicht praktikabel. Auch senden geht einwandfrei.

Ich habe die USART folgendermaßen konfiguriert:
1
void uart_init(void){
2
  #undef BAUD
3
  #define BAUD 38400
4
  #include <util/setbaud.h>
5
  
6
  UBRR0H = UBRRH_VALUE;
7
  UBRR0L = UBRRL_VALUE;
8
  #if USE_2X
9
    UCSR0A |= (1 << U2X0);
10
  #else
11
    UCSR0A &= ~(1 << U2X0);
12
  #endif
13
14
  //UCSR0A |= (1<<RXC0);
15
  UCSR0B |= (1<<TXEN0)|(1<<RXEN0)|(1<<RXCIE0);  // UART TX/RX einschalten, RX-Interrupt aktivieren
16
  UCSR0C = (1<<UCSZ01)|(1<<UCSZ00);        // Asynchron 8N1
17
}

Meine ISR sieht bisher so aus:
1
ISR(USART_RX_vect){
2
  uart_rx();
3
  uart_putc('1');
4
}

Die Funktion uart_rx() ruft unter anderem UDR0 ab.


Vielen Dank
Sam

von holger (Gast)


Lesenswert?

sei() vergessen?

von Bitflüsterer (Gast)


Lesenswert?

Ich meine mich auf eine ganze Reihe von Vermutungen über Deinen Code und 
Deine Schaltung stützen zu müssen, so daß ich Dir nur raten kann, die 
Rücksendung der empfangenen Daten nicht im RX-Interrupt zu erledigen, 
sondern in der der Hauptschleife. Falls nämlich das senden auch im 
Interrupt erfolgt, kann das nicht erfolgen, solange die Interrupts noch 
gesperrt sind, weil gerade die RX-ISR abgearbeitet wird.

Falls das Problem nicht klarer geworden ist oder mein Vorschlag nicht 
funktioniert, poste bitte mal einen kompletten Code, der das Problem 
aufweist und compilierbar ist.

von Sam (Gast)


Lesenswert?

sei() wird vor der Endlosschleife der main() ausgelöst.

In der ISR passiert eigentlich nur das Schreiben des empfangenen Bytes 
in den Puffer. Ich schreibe nur ein einziges Zeichen in die USART um zu 
testen, ob die ISR überhaupt aufgerufen wird, was bisher nicht der Fall 
ist. Auch sonst wird die USART bisher nicht genutzt.

von Bitflüsterer (Gast)


Lesenswert?

Sam schrieb:
> sei() wird vor der Endlosschleife der main() ausgelöst.
>
> In der ISR passiert eigentlich nur das Schreiben des empfangenen Bytes
> in den Puffer. Ich schreibe nur ein einziges Zeichen in die USART um zu
> testen, ob die ISR überhaupt aufgerufen wird, was bisher nicht der Fall
> ist. Auch sonst wird die USART bisher nicht genutzt.

Nun gut. Wie ich schon schrieb: Poste bitte kompletten, fehler- und 
warnungsfreien kompilierbaren Code, der das Problem aufweist. An dem 
Code-Teil, den Du gepostet hast, ist nichts Auffälliges zu erkennen.

von Amateur (Gast)


Lesenswert?

Immer wieder dieselbe Leier.

Da geht etwas nicht und der Poster schickt, nach eigenem Gusto, ein 
wenig aussagekräftiges Codesegment.
Ich möchte nicht wissen, wie oft Du Dir dies schon angesehen hast, 
keinen Fehler gefunden hast und deshalb uns an Deinem Kummer teilhaben 
lässt.

Das Ratespiel kann also beginnen und das aus der Nase ziehen fängt an.

Warum kommen die Initiatoren eigentlich, von nicht selbst auf die Idee 
ihre super geheimen und patenten Routinen aus einer Zwischenversion 
rauszuwerfen und diese, so sie immer noch nicht geht, zu 
veröffentlichen?

Es interessiert keinen Menschen, was Du mit eventuell empfangenen Daten 
machst, wenn sie sowieso nicht ankommen.

von Sam (Gast)


Angehängte Dateien:

Lesenswert?

Leider kann ich den Code nicht reduzieren. Sobald ich alles, was nicht 
mit der UART zu tun hat herausnehme funktioniert es.

von holger (Gast)


Lesenswert?

ISR(TIMER1_COMPA_vect) {
....

 // Mach das weg
 if(UDR0) uart_putc(UDR0);
}

von Sam (Gast)


Lesenswert?

Das bringt mir nichts, das ist nur die Rückmeldung für mich, dass die 
Daten überhaupt ankommen. Wenn ich es entferne wird der Interrupt 
trotzdem nciht ausgelöst.

von Bitflüsterer (Gast)


Lesenswert?

OK. Lass mich mal raten.
Sobald Du aus diesem Code:
1
ISR(USART_RX_vect){
2
  uart_rx();
3
  
4
  uart_putc('1');
5
  mode = DIRECT;
6
  if(farbe_H == 120) {
7
    farbe_H = 240;
8
        }else if(farbe_H == 0) {
9
    farbe_H = 120;
10
    }else{
11
    farbe_H = 0;
12
  }
13
  farbe_S = 100;
14
  farbe_V = 100;
15
  showHSV();
16
}

den Aufruf von showHSV() herausnimmst geht es. Oder?

von Amateur (Gast)


Lesenswert?

>Leider kann ich den Code nicht reduzieren. Sobald ich alles, was nicht
>mit der UART zu tun hat herausnehme funktioniert es.

Da drängt sich aber der Gedanke auf, dass es sich um einen 
Kollateralschaden handelt oder der Fehler an anderer Stelle zu suchen 
ist.

Übrigens ist das systematische Herausnehmen bzw. Ausklammern von 
Funktionen, ein beliebtes Verfahren bei der Fehlersuche.

von Sam (Gast)


Lesenswert?

Nein, das ändert nichts, ich kann ab mode = DIRECT alles 
auskommentieren, der Fehler bleibt.
In der ISR ist alles außer uart_rx() nur dazu da, eine Reaktion sichtbar 
zu machen. Das war vorher nicht drin und kommt nachher auch wieder raus.

von Bitflüsterer (Gast)


Lesenswert?

Irgendwie ist das alles auch ein wenig sehr verwickelt; wenn Du erlaubst 
das ich das so ausdrücke. Wo hast Du den UART Code her, wenn ich fragen 
darf?

Wenn nämlich Dein Timer-Interrupt nicht läuft, dann werden keine Zeichen 
ausgegeben. Ausserdem sehe ich in den UART-Codeteilen überhaupt kein 
volatile, oder habe ich was übersehen?

Guck Dir mal den UART Code von Perter Danegger hier an.

von Bitflüsterer (Gast)


Lesenswert?

>Das war vorher nicht drin und kommt nachher auch wieder raus.

Das erzeugt Dir mehr Probleme als es löst. Nimm es gleich 'raus und 
lass' es 'raus.

Der ganze Code muss erstmal gründlich aufgeräumt werden. Den UART-Kram 
schmeiss raus und ersetze ihn durch was Vernünftiges; wöfüer Peters Code 
ein Beispiel ist.

Offen gesagt, motiviert mich Dein Code immer mehr zu Vorträgen, die Du 
nicht hören willst. Ich spare mir das und rate Dir folgendes.

Setze den Code völlig neu auf. Es sollte keine unnötige Verknüpfung 
zwischen UART und Licht-Codes geben. Peters Code ist gut.
Das muss erstmal gehen. Dann gehst Du an den LED-Code.

Es ist nämlich so: zum Testen brauchst Du am dringendsten eine 
funktionierende Kommunikation und nicht den LED-Code. Es scheint Du hast 
da mal einen UART-Code gehabt ohne IST, dann den LED-Code hinzugefügt 
und dann nochmal UART auf ISR umgestellt und dabei so einiges 
verwurschtelt ( :-)).

von Sam (Gast)


Lesenswert?

Du darfst mir gerne Vorträge halten^^

Ich benutze auch vorhandene Libs, auch die von Peter Fleury und Peter 
Danegger. Nur will ich hier einen Code schreiben, der komplett aus 
meiner Feder stammt.

Ich habe das Problem inzwischen lokalisiert. Es ist der PWM-Timer. Der 
ist einfach zu schnell. Mit diesem Problem habe ich anfangs gerechnet 
doch dann hat er keine Probleme gemacht und ich habe es verdrängt.
Ich werde nun also die Soft-PWM langsamer machen und dafür die Auflösung 
reduzieren.

von Bitflüsterer (Gast)


Lesenswert?

Sam schrieb:
> Du darfst mir gerne Vorträge halten^^
>
> Ich benutze auch vorhandene Libs, auch die von Peter Fleury und Peter
> Danegger. Nur will ich hier einen Code schreiben, der komplett aus
> meiner Feder stammt.

Ja schon. Aber dann muss man so einen Code auch schreiben können! :-) 
Was nützt der schönste selbstgeschriebene Code der nur bei Vollmond und 
an Dienstag-Nachmittagen geht?

> Ich habe das Problem inzwischen lokalisiert. Es ist der PWM-Timer. Der
> ist einfach zu schnell. Mit diesem Problem habe ich anfangs gerechnet
> doch dann hat er keine Probleme gemacht und ich habe es verdrängt.
> Ich werde nun also die Soft-PWM langsamer machen und dafür die Auflösung
> reduzieren.

Zu schnell für welchen Zweck genau?

Es ist ein ganz schlechtes Zeichen - eines für ein kaputtes Design -, 
dass Du da an der PWM-Frequenz drehen musst um Kommunikation zu 
gewährleisten.

Aber gut. Leider, neigt man dazu, das Problem für gelöst zu halten, wenn 
es verschwindet. Kann ich schon verstehen - das ist menschlich.

Also dann, alles Gute und viel Erfolg.

von Sam (Gast)


Lesenswert?

Bitflüsterer schrieb:
> Ja schon. Aber dann muss man so einen Code auch schreiben können! :-)
> Was nützt der schönste selbstgeschriebene Code der nur bei Vollmond und
> an Dienstag-Nachmittagen geht?

Aus diesem Grund werden Fehler entfernt ;)


> Zu schnell für welchen Zweck genau?

Zu schnell um noch Rechenzeit für alles andere übrig zu lassen. Der 
Timer war auf CTC bis 100 eingestellt. Jetzt läuft er bis 200. Ich muss 
den Timer nur möglichst schnell laufen lassen um eine möglichst hohe 
Auflösung zu erreichen.
Mit kaputtem Design hat das meiner Meinung nach weniger zu tun. Es ist 
vielmehr so, das ich versuche, aus vorhandener Hardware das maximal 
Mögliche herauszuholen. Natürlich könnte ich mich auch mit 8-Bit-PWM 
zufrieden geben. Aber wozu, wenn noch mehr geht? Bringt ja niemanden um.


> Also dann, alles Gute und viel Erfolg.

Vielen Dank

von Bitflüsterer (Gast)


Lesenswert?

OK. Ich schreibe jetzt noch einmal was antworten und dann erspare ich 
Dir weitere "Weisheiten".

Sam schrieb:
> Bitflüsterer schrieb:
>> Ja schon. Aber dann muss man so einen Code auch schreiben können! :-)
>> Was nützt der schönste selbstgeschriebene Code der nur bei Vollmond und
>> an Dienstag-Nachmittagen geht?
>
> Aus diesem Grund werden Fehler entfernt ;)

Schon. Aber welchen Fehler entfernst Du auf dem offenen Meer, als 
Schiffbrüchiger an einem Hammer, weil er nicht schwimmen will. :-) Soll 
heissen: Das Design muss an sich geeignet sein. Ein ungeeignetes Design 
hat keine Fehler; es ist schlicht und einfach nur ungeeignet!

>> Zu schnell für welchen Zweck genau?
>
> Zu schnell um noch Rechenzeit für alles andere übrig zu lassen.
Ja. Schon. Aber die Frage war konkret gemeint und nicht allgemein.

> Der
> Timer war auf CTC bis 100 eingestellt. Jetzt läuft er bis 200. Ich muss
> den Timer nur möglichst schnell laufen lassen um eine möglichst hohe
> Auflösung zu erreichen.
"Möglichst hoch" ist ein typisches Anfängerverhalten. So hoch wie nötig, 
machen es die Amateure und die Profis.

> Mit kaputtem Design hat das meiner Meinung nach weniger zu tun. Es ist
> vielmehr so, das ich versuche, aus vorhandener Hardware das maximal
> Mögliche herauszuholen.
Nein. Da bin ich definitiv anderer Meinung. Ad eins: Die Kommunikation 
darf davon nicht betroffen sein. Wenn das so ist, dann liegt ein 
Designfehler vor oder der uC ist prinzipiell nicht geeignet. Ad zwei: 
Man geht weder bei Bauteilen noch bei der Datenverarbeitung an die 
Grenze des maximal möglichen. Typisches Anfängerverhalten.

> Natürlich könnte ich mich auch mit 8-Bit-PWM
> zufrieden geben. Aber wozu, wenn noch mehr geht? Bringt ja niemanden um.

Schön. Aber was bringt es? Das ist die erste Frage und nicht die letzte.

>> Also dann, alles Gute und viel Erfolg.
>
> Vielen Dank

Bitte, gerne.

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.