PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : [At90]Zufälliger Reset bei UART Kommunikation



wEm
18.06.2008, 15:23
Hallo zusammen.

Ich bin rel. neu hier, und habe folgendes Problem mit meinem At90Can128

Ich verwende den Controller, um über UART1 zyklisch die Daten einer Motorsteuerung abzufragen. Sobald die Motorsteuerung Daten sendet,
werden diese über den UART1 Interrupt in einen ringpuffer geschrieben.

Auf der anderen Seite kommuniziert ein PC über UART0 mit meinem controller.
Sobal der PC das erste Byte sendet, wird diese Byte vom Controller in einen weiteren
ringpuffer geschrieben, und ein flag gesetzt, dass der PC Daten senden will.

Sobald der AT90 dazu bereit ist (also die Kommunikation mit der Motorsteuerung abgeschlossen ist),
signalisiert er dies dem PC und empfängt die restlichen Daten.

Jetzt tritt ab und zu das Problem auf, dass mein Controller sich nach einer gewissen Zeit resettet,
und ich hab nicht die geringste Ahnung, woher das kommen könnte. Für sämtliche auftretende Interrupts gibt es entsprechend eine Routine.

Laut AT90 Handbuch gibt es folgende Reset quellen:
- PowerOn reset: wird ja nur nach dem einschalten ausgeführt
- External reset: wird nur aktiviert, wenn ich nen taster drücke
- Watchdog Reset: mein WD ist deaktiviert
- Brown-out reset: ebenfalls deaktiviert
- JTAG reset: ich hab kein JTAG

Sprich: alle möglichen Resetquellen hab ich schonmal ausgeschlossen.

Und sobal der controller lediglich mit der Motorsteuerung über UART1 kommuniziert, und nicht mit dem PC über UART0, kommt auch kein Reset.

Sobald sich der PC aber auch einschaltet, kommt nach einer unbestimmten Zeit (10sec.....5min) allerdings ein reset.

Habt ihr nen Tip, woher dieser unbeabsichtigte Reset kommen könnte?
Danke schonmal.
Gruß

fluchtpunkt
18.06.2008, 17:06
checke am anfang deines Programms mal das MCUSR, da steht der Grund fuer den Reset drin. Wenn da 0 drin ist dann hast du womoeglich einen Stack Overflow.

wEm
18.06.2008, 22:39
jo danke, das ist mal ein sehr guter hinweis. ich werd das morgen mal machen, und mich dann wieder an euch wenden :)

python_rocks
18.06.2008, 22:53
alle möglichen Resetquellen hab ich schonmal ausgeschlossen
Hallo wEm!

Wie hast du den Reset-Pin angeschlossen?

mfg
Gerold
:-)

wEm
19.06.2008, 08:51
Also ich hätte vll noch erwähnen sollen, dass ich das DVK90can1 Developmentkit von Atmel habe.
Da ist der Resetpin über einen Taster mit RC Glied gegen VCC verschaltet. Sprich: Taster drücken, Potential wird low->reset.

python_rocks
19.06.2008, 09:16
Also ich hätte vll noch erwähnen sollen, dass ich das DVK90can1 Developmentkit von Atmel habe.
Da ist der Resetpin über einen Taster mit RC Glied gegen VCC verschaltet. Sprich: Taster drücken, Potential wird low->reset.
Hallo wEm!

Das ist auf diesem Board "nur" ein 47 k Widerstand. Das empfinde ich persönlich nicht unbedingt als 100 % störsicher. Ich würde es einfach mal ausprobieren und die Reset-Schaltung (falls das möglich ist) vom Controller trennen und stattdessen einfach nur einen 10 k Widerstand nach VCC schließen. Nur mal so zum Probieren.

Wenn du den Reset-Pin nicht trennen kannst, dann würde ich zumindest den Reset-Pin mit dem Oscilloskop beobachten. Und wenn du schon dabei bist, kannst du mit dem Osci auch VCC unter die Lupe nehmen. Nicht dass die Versorgungsspannung kurz zusammenbricht und du nichts davon bemerkst.

Ich bin kein Profi, aber ausprobieren kannst du es ja.

mfg
Gerold
:-)

wEm
19.06.2008, 09:50
hiho, also ich hab mir mal das MCUSR angeschaut, und nach dem unbeabsichtigten reset wird mir angezeigt, dass dieser reset durch den Brown-Out verursacht wurde (bit 3 ist gesetzt).

Ist das normel, dass dieser Reset verursacht wird, obwohl der Brown-Out durch das Fusebit deaktiviert ist?

Der 7805 wird nur handwarm, also sollte er nicht daran schuld sein, dass die Spannungsversorgung zusammenbricht.

Ich versorge jetzt mal den controller mit einem gescheiten Labornetzteil, und hoffe mal, dass dieser Reset nicht mehr auftritt. Wenn doch, dann hab ich noch die Mäöglichkeit, den 7805 zu umgehen, allerdings sollte ich dann halt aufpassen, dass das Board nur 5V bekommt :)

wenn es dann immer noch auftritt, dann bin ich mit meinem Latein leider am Ende...

edit:
also mit zugesschaltetem 7805 und Labornetzteil tritt der Fehler trotzdem auf :(

edit2: mit abgeschaltetem 7805 und konstant 5V spannungsversorgung dasselbe Problem

McJenso
19.06.2008, 10:35
Hallo,

in deinem Fall würde ich jetzt her gehen, das Programm zum Test abzuspecken. Was passiert, wenn du ein kleines Testprogramm schreibst, das nichts weiter macht als mit dem PC zu kommunizieren. Sprich Daten senden und empfangen. Die empfangenen Daten dann aber bitte verwerfen und nicht weiter verarbeiten.



Gruß

Jens

wEm
19.06.2008, 16:41
Ha, ich glaub, ich bin dem Problem etwas näher gekommen.
Denn ich hab mittlerweile festgestellt, dass der Wert in dem Register MCUSR nicht zwingend etwas mit den Resetflags zu tun hat, sondern mit dem Momentanen Status meines Controllers. (Ich habe das Programm ähnlich einer Statemachine aufgebaut.)
So, jetzt hat er mir nach einem unbeabsichtigten Reset scheinbar den letzten Status als MCUSR ausgegeben, was immer der Status GET_EPOS_DATA (Also Daten von der Motorsteuerung holen) war. Dieser Status hat den Wert 0x04. Ich hab ihn mal testweise auf 0x09 geändert, und siehe da, nach einem Reset hat er mir den Wert als MCUSR angegeben.

Zur kurzen Info, da ich kein JTAG hab, lass ich mir den Wert von MCUSR an einem Port mit LEDs anzeigen.


Also könnte das Ganze evtl doch das Problem eines Stack Overflows sein, allerdings kann ich mir nicht erlären, woher der kommt:

Ich hab insgesamt 4 ISRs:

ISR (SIG_UART0_RECV) { // USART0 RX interrupt
uart0_rb_write(UDR0); //fill buffer
BytesRecieved++;
if(ctrState.CurrentState != GET_UART0_DATA && UART0DataAvailable != 1)
{
UART0DataAvailable = 1;
}
}


ISR (SIG_UART1_RECV){ //USART1 RX interrupt
uart1_rb_write(UDR1); //fill buffer
uart1BytesRecieved++;
if(SendDataComplete == 1)
{
uart1BytesRecieved = 0;
SendDataComplete = 0;
}
}

ISR (SIG_OUTPUT_COMPARE1A) {
timers.bTimer1Elapsed = 1;
}


ISR (SIG_OUTPUT_COMPARE3A) {
if(ctrState.CurrentState != FAULT && ctrState.CurrentState != GET_UART0_DATA && ctrState.CurrentState != GET_EPOS_DATA)
{
EPOS_DataCheck = 1;
ctrState.PreviousState = ctrState.CurrentState;
ctrState.CurrentState = GET_EPOS_DATA;
}
}

Wie ihr seht, wird in diesen ISR entweder nur ein ringpuffer beschrieben, oder der Status des Controllers geändert, also sind da keine hochkomplexen Algorithmen drin, oder gar noch schlimmer, irgendwas Speicheraufwändiges, das den Stackoverflow erzeugen könnte.

Das war jetzt nur mal zu eurer Info, ich weiss jetzt schonmal wo ich nachgucken muss.
Falls Ihr noch irgendwelche Anregungen habt, nur her damit :)

Sascha

wEm
24.06.2008, 09:58
Also ich hab das problem so wies aussieht gelöst, auch wenn mir die Ursache des Problems noch nicht ganz klar ist.

Wie schon in meinem vorherigen Post geschrieben, bekomme ich einen Stack Overflow.
Dieser ist "scheinbar" nur aufgetreten, wenn die eine Kommunikationsroutine über den Interrupt der anderen unterbrochen wurde.
Ich spreche hier nicht von den Interrupts selber, die lediglich einen Puffer füllen, sondern von der Auswertung der Daten im Puffer.
Nachdem ich jetzt in der Kommunikationsroutine, die über UART1 mit der Motorsteuerung Daten austauscht, den UART0 Interrupt deaktiviert, und bei erfolgreicher Beendigung wieder aktiviert.
Und es scheint einwandfrei zu laufen. Zumindest seit 30min :)
Ich hoffe mal, der läuft auch noch länger.

Danke für eure Hilfe