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
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.
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.
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.
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
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.
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
>> 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.
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.
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.
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)
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.
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.
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