Forum: Mikrocontroller und Digitale Elektronik zyklischer Reset beim Empfang von USART-Daten


von H. F. (hafisch)


Lesenswert?

Hallo zusammen

Ich habe bei einem kleinen Projekt mit einem Atmega 8515 auf einem 
STK500 eine Usart Library geschrieben, mit welcher ich Traces an ein 
Terminal ausgeben kann.

Beim Versuch nun Steuerzeichen vom Terminal zu Empfangen, trat nun 
folgendes Problem auf, welches ich mir nicht erklären kann.

Um mittels des Usart-Interrupts Daten empfangen zu können, habe ich als 
erstes die entsprechenden Register gesetzt:
1
 UCSRB |= (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);

Danach die Interrupt-Routine mit dem entsprechenden Vektor 
implementiert.

1
ISR(USART_RXC_vect)
2
{
3
// TODO
4
}

Wenn ich nun von meinem Terminal (CuteCom) ein Zeichen absetzt, dann 
startet der Controller zyklisch neu. Dies ist feststellbar weil ich bei 
jedem Start der Steuerung die Grundkonfiguration über die 
usart-Schnittstelle ausgebe. Das heisst das zyklisch diese Daten 
gesendet werden

Sobald ich den Controller über den Reset-Pin zurücksetze, läuft alles 
wieder normal bis zum ersten Empfang eines Zeichens.
Wenn ich das Bit RXCIE lösche, läuft alles, ausser dass ich natürlich 
nichts empfangen kann.

Hat jemand eine Idee an was das liegen könnte.

Danke für die Hilfe und Gruss
hafisch

von Karl H. (kbuchegg)


Lesenswert?

H. Fisch schrieb:

> ISR(USART_RXC_vect)

Kriegst du irgendwelche Warnungen, dass der Name USART_RXC_vect falsch 
wäre?
Je nach konkretem µC heissen die ein wenig anders.

von Georg G. (df2au)


Lesenswert?

Denkbar wäre auch, dass der Compiler die leere Routine wegoptimiert. 
Oder war es doch nicht der aktuelle Code, den du hier präsentiert hast?

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:
> H. Fisch schrieb:
>
>> ISR(USART_RXC_vect)
>
> Kriegst du irgendwelche Warnungen, dass der Name USART_RXC_vect falsch
> wäre?
> Je nach konkretem µC heissen die ein wenig anders.


Jep.
Bei einem M8515 heißt der Vektor
USART_RX_vect

Du musst derartige Warnungen ernst nehmen. Wenn der Name nicht stimmt, 
dann hast du KEINEN Interrupt Vektor. Ein freigegebener Interrupt OHNE 
entsprechenden Interrupt Vektor wird aber mit einem Reset bestraft.

Wenn du wissen willst, wie dir Vektoren wirklich heißen (bzw. alles 
andere in deinem konkreten µC) dann schau ins File iom8515.h (müsste in 
deinen Projektfiles unter 'external Dependencies' auftauchen. Dort sind 
alle diese Angaben drinnen.

von Karl H. (kbuchegg)


Lesenswert?

Georg G. schrieb:
> Denkbar wäre auch, dass der Compiler die leere Routine wegoptimiert.

Nein. Ist nicht denkbar.

Der Compiler kann derartige Funktionen, genausowenig wie leere 
Endlosschleifen nicht einfach wegoptimieren. Das wäre ein schwerer 
Compilerfehler, der lange vor Auslieferung des Compilers bemerkt werden 
würde.

von H. F. (hafisch)


Lesenswert?

Hallo

Ja eine solche habe ich Anfangs bekommen, habe den Vektor jedoch so 
angepasst dass keine Meldung mehr kommt.

Spanned ist zudem, dass der zyklische Reset auch dann auftritt, wenn ich 
nur das Bit RXCIE im Register setze und die Interrupt-Funktion lösche.

Gruss und Danke
hafisch

von Karl H. (kbuchegg)


Lesenswert?

H. Fisch schrieb:

> Spanned ist zudem

Das ist überhaupt nicht spannend.

Das ist der Default im gcc.
Ein auftretender Interrupt, für den es keinen Handler gibt, FÜHRT zu 
einem Reset. Das ist per Design so.

: Bearbeitet durch User
von Bastler (Gast)


Lesenswert?

Man kann allerdings per
1
 ISR(BADISR_vect) {
2
....
3
}
diesen Reset abfangen und noch ein letztes Lebenszeichen ausgeben. Z.B. 
per INT-freier UART-Routine.

von H. F. (hafisch)


Lesenswert?

Hallo zusammen

Vielen Dank für die Hilfe. Habe weder gewusst, dass automatisch neu 
gestartet wird wenn die entsprechende Interrupt-Funktion fehlt, noch 
dass der Empfangs-Puffer erst geleert wird wenn auf das Register UDR 
zugegriffen wird, und nicht wenn der Interrupt aufgerufen wird.

Habe nun die Funktion mit dem im io8515.h File den korrekten Vektor 
ausgelesen. Nun funktioniert alles wir gewünscht.

Danke und einen schönen Abend wünscht
hafisch

von c-hater (Gast)


Lesenswert?

H. Fisch schrieb:

>
1
 UCSRB |= (1<<RXEN)|(1<<TXEN)|(1<<RXCIE);
>
> Danach die Interrupt-Routine mit dem entsprechenden Vektor
> implementiert.
>
>
>
1
ISR(USART_RXC_vect)
2
> {
3
> // TODO
4
> }
>
> Wenn ich nun von meinem Terminal (CuteCom) ein Zeichen absetzt, dann
> startet der Controller zyklisch neu.

Ist das der einzige Code im Controller oder ist da noch mehr? 
Höchstwahrscheinlich ist da noch mehr.

Der Code oben hat eigentlich nicht das Potential für einen Reboot (dazu 
müßte ein Fehler in der Implementierung von ISRs an sich vorliegen, was 
ich mir kaum vorstellen kann, das wäre bestimmt schon früher mal 
aufgefallen.

Was der Code aber machen wird: Er wird dafür sorgen, daß main() 
praktisch nicht mehr abgearbeitet wird, weil er nach dem ersten 
empfangenen Zeichen praktisch ständig in der ISR hängt.

Im Unterschied zu den meisten anderen Interrupts im AVR reicht es bei 
den UART-Interrupts nämlich nicht, den Vektor zu durchlaufen, um das 
Interruptflag zurückzusetzen. Im Falle des RXC-Int muß von UDR gelesen 
werden, um das Interruptflag zurückzusetzen.

von Thomas E. (thomase)


Lesenswert?

c-hater schrieb:
> Der Code oben hat eigentlich nicht das Potential für einen Reboot (dazu
> müßte ein Fehler in der Implementierung von ISRs an sich vorliegen, was
> ich mir kaum vorstellen kann, das wäre bestimmt schon früher mal
> aufgefallen.

Schwachsinn.
Eine nicht vorhandene ISR führt zu einem Sprung auf den Resetvektor. Ob 
du dir das nun vorstellen kannst oder nicht.

mfg.

von c-hater (Gast)


Lesenswert?

Thomas Eckmann schrieb:

> Eine nicht vorhandene ISR führt zu einem Sprung auf den Resetvektor.

Das ist zwar richtig, geht aber völlig am Thema vorbei.

Zitat:

> ISR(USART_RXC_vect)
> {
> // TODO
> }

Es ist also eine vorhanden, diese ist nur leer. Das wird zu einem 
schlichten RETI übersetzt und damit wird natürlich kein Reboot 
ausgelöst.

Sag' mal, hast du überhaupt von IRGENDETWAS eine Ahnung?! Wenn man so 
blaß aussieht wie du, sollte man sich mit Begriffen wie "Schwachsinn" 
vielleicht etwas zurückhalten. Nicht daß mir das etwas ausmachen würde, 
aber du machst dich damit ziemlich lächerlich. Aber wenn dir das auch 
nix ausmacht, OK, weiter so.

von Karl H. (kbuchegg)


Lesenswert?

c-hater schrieb:
> Thomas Eckmann schrieb:
>
>> Eine nicht vorhandene ISR führt zu einem Sprung auf den Resetvektor.
>
> Das ist zwar richtig, geht aber völlig am Thema vorbei.
>
> Zitat:
>
>> ISR(USART_RXC_vect)
>> {
>> // TODO
>> }
>
> Es ist also eine vorhanden, diese ist nur leer. Das wird zu einem
> schlichten RETI übersetzt und damit wird natürlich kein Reboot
> ausgelöst.

Nö.
Das wird zu einer normalen Funktion übersetzt.

Der Name der ISR ist falsch. Es müsste

ISR( USART_RX_vect )

heissen. Dann wäre es eine korrekte ISR.
Wird aber auch vom Compiler mit einer Wanung bedacht. Man sollte die nur 
halt nicht ignorieren oder einen zu alten Compiler benutzen (Ich hab mir 
sagen lassen, dass ältere avr-gcc dieses nicht angewarnt hat)

: Bearbeitet durch User
von Thomas E. (thomase)


Lesenswert?

c-hater schrieb:
>> ISR(USART_RXC_vect)
>> {
>> // TODO
>> }
>
> Es ist also eine vorhanden, diese ist nur leer. Das wird zu einem
> schlichten RETI übersetzt und damit wird natürlich kein Reboot
> ausgelöst.
>
Da RXC_vect kein gültiger Vektor ist, ist keine ISR vorhanden.
Also Schwachsinn.

mfg.

von Karl H. (kbuchegg)


Lesenswert?

Karl Heinz schrieb:

> Der Name der ISR ist falsch. Es müsste
>
> ISR( USART_RX_vect )
>
> heissen. Dann wäre es eine korrekte ISR.

Also jetzt im Sinne des Namens. Das das Nichtauslesen des UDR noch 
falsch ist, ist eine andere Geschichte. Aber die ist nicht für den 
Dauerreset verantwortlich.

von Thomas E. (thomase)


Lesenswert?

c-hater schrieb:
> Sag' mal, hast du überhaupt von IRGENDETWAS eine Ahnung?! Wenn man so
> blaß aussieht wie du, sollte man sich mit Begriffen wie "Schwachsinn"
> vielleicht etwas zurückhalten. Nicht daß mir das etwas ausmachen würde,
> aber du machst dich damit ziemlich lächerlich. Aber wenn dir das auch
> nix ausmacht, OK, weiter so.

Das beantworte ich mal musikalisch.

http://www.youtube.com/watch?v=4ubBw3dE8Wc

mfg

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.