Hallo,
ihr seid meine letzte Hoffnung.
Und zwar benützte ich wie oben angegeben einen Atmel AT90CAN128. Es
werden 3 CAN Nachrichten über einen interrupt eingelesen.
So weit so gut.
Mein Problem: Alles funktioniert so lange die Nachrichten nur sporadisch
kommen. Sobald die Daten aber mit einer Zykluszeit von ca. 30ms gesendet
bzw. empfangen werden bleibt der yC hängen. Heißt es werden keine Daten
mehr empfangen.
Beim debugen kommt der Fehler nicht vor, heißt, Programm läuft, Daten
werden empfangen und verarbeitet.
Erste Hilfe meinerseits war über den Watchdog den yC immer wieder zurück
zu setzen wenn keine Daten mehr empfangen werden, dies funktioniert nur
zum Teil!
Wenn der yC sich resetet oder ich die Platine von Hand neustartet tritt
zum teil der exakt selbe Fehler direkt wieder auf! Was ich allerdings
beobachtet habe, häufig nur wenn auch zum selben Zeitpunkt (beim start)
auch Daten auf dem CAN-Bus versendet werden.
Komisch ist auch noch, dass eine Nachricht noch eingelesen wird und zwei
nicht mehr.
Nun meine Frage:
Woran kann das liegen? :-(
Besitzt der Atmel einen internen Buffer welcher direkt voll ist bevor
die Daten verarbeitet werden können? Kann ich diesen löschen?
Kann ich auch nur jeden zweiten Interrupt auslösen?
Achso, während meinen Berechnungen deaktiviere ich den Interrupt.
Hoffe Ihr könnt mir helfen. Bin echt am verzweifeln da mit dem yC am
Donnerstag Tests geplannt sind und wenn ich das Problem bis dahin nicht
gefunden bzw. gelöst hab alles ins Wasser fällt :-(
Hoffe meine Erklärung war nicht ganz verwirrend :-)
Vielen Dank schon mal.
Gruß Timo
>Achso, während meinen Berechnungen deaktiviere ich den Interrupt.
Dann sind deine Berechnungen bzw. möglicherweise Ausgaben zu den
Berechnungen zu lang. Sendest du irgendwas über UART und wartest
bis das weg ist? Oder gibst du was auf LCD aus?
Ja Ausgabe auf LCD und das Ergebnis der Berechnung als Nachricht über
den CAN
Heißt wenn ich das richtig verstehe meinst du das meine Berechnung so
lang braucht bis der Buffer voll ist!?
Was wäre eine Abhilfe wenn ich die Ausgabe auf dem LCD behalten wollen
würde, bzw. wenn meine Berechnung zu lang dauern würde!?
Wenn ich mit CANoe mitlog habe ich eine durchschnittliche
Berechnungszeit von ca. 2ms also weit weg von den 30ms ! :-(
Danke für deine Antwort!
Hallo!
Ich denke, Du machst da einen strukturellen Fehler.
Für jede einkommende CAN Message bekommst Du einen CANIT Interrupt
(Vektor 19 an Adresse 0x0024). Wenn der kommt, mußt Du alle Message
Objekte abklappern, ob und wo eine neue Message eingetrudelt ist,
eingegangene Messages aus dem Controller abholen, bearbeiten und das
jeweilige Message Object wieder freigeben.
Das sieht dann ungefähr so aus:
if(mob_irq)// Interrupt durch eine Message verursacht?
21
{
22
for(mob=0;mob<NB_MOB;mob++)// alle Messages durchgehen
23
{
24
if(mob_irq&&1)
25
{
26
CANPAGE=mob<<4;// Message Object auswählen
27
cd=CANCDMOB;
28
st=CANSTMOB;
29
if(st&BIT(5))
30
{
31
//!!! hier Message aus dem Controller abholen,
32
//!!! auswerten und bearbeiten
33
}
34
CANCDMOB=0;
35
CANSTMOB=0;// Status zurücksetzen
36
}
37
mob_irq>>=1;
38
}
39
}
40
}
41
}
Ich habe den Code ziemlich zusammengestrichen. Mag sein, daß ich da zu
viel gestrichen habe, aber so im Prinzip geht das.
Also: Du mußt JEDEN CANIT-Interrupt SOFORT behandeln.
Ich denke, Du bekommst darüber irgendwelche Werte. Die mußt Du dann in
der Interruptroutine in einen Zwischenspeicher schreiben und wenn ein
neuer Auswertezyklus beginnt dort herausholen.
fchk
Okay, würde bedeuten das ich nicht den Interrupt einfach deaktivieren
kann.
Und das heißt bei jeder CAN-Nachricht kommt ein Interrupt, egal ob meine
gesuchte ID oder nicht. (Dies war mir klar)
Aber so wie oben gezeigt mach ich es auch, ich speicher in meiner isr
die Daten zwischen und dann kommt die Berechnung und danach die Ausgabe.
Allerdings deaktiviere ich die Interrupts während der Berechnung.
Dies ist falsch wenn ich dein SOFORT richtig deute!?
Gehen denn die Daten sonst in einen Puffer?
Danke für deine Antwort.
Gruß Timo
Timo schrieb:> Okay, würde bedeuten das ich nicht den Interrupt einfach deaktivieren> kann.
Genau.
> Und das heißt bei jeder CAN-Nachricht kommt ein Interrupt, egal ob meine> gesuchte ID oder nicht. (Dies war mir klar)
Eigentlich kommt nur ein Interrupt, wenn die Nachricht zu einer der
definierten Akzeptanzmasken paßt, die Du natürlich vorher passend setzen
mußt.
Interrupts können aber auch aus anderen Gründen auftreten (z.B. Bus
Errors, die speziell am Anfang auftreten können, oder wenn der Bus mal
aufgetrennt wird oder ein Gerät dazugeschaltet wird). Siehe Beschreibung
von CANSTMOB im Datenblatt. Und die mußt Du natürlich auch alle
behandeln. Wenn nicht, dann hängt es irgendwann. Mein Beispiel ist in
der Hinsicht ziemlich gekürzt.
> Aber so wie oben gezeigt mach ich es auch, ich speicher in meiner isr> die Daten zwischen und dann kommt die Berechnung und danach die Ausgabe.> Allerdings deaktiviere ich die Interrupts während der Berechnung.>> Dies ist falsch wenn ich dein SOFORT richtig deute!?
Richtig. In der Interruptroutine würde ich aber keine Berechnungen
machen.
> Gehen denn die Daten sonst in einen Puffer?
Du hast 16 Message Objekte (MOB). Zu jedem MOB gibt es einen Speicher
für eine Nachricht, es gibt eine Akzeptanzmaske und einen Satz
Status/Control-Register. Wenn Du bei einem MOB eine Akzeptanzmaske setzt
und dieses MOB scharf schaltest, kann es eine Nachricht empfangen. EINE.
Danach ist es voll und will geleert und zurückgesetzt werden. Niemand
hindert Dich aber daran, mehrere MOBs gleichzeitig zu initialisieren und
zum Empfang zu benutzen. Dafür hast Du ja so viele.
Zum Senden brauchst Du auch MOBs.
Die MOBs liegen alle auf einem gemeinsamen Adressraum. Durch Schreiben
in CANPAGE schaltest Du auf ein bestimmtes MOB (Stichwort
Bankswitching).
Mehr Pufferung gibts nicht. Also lautet die Strategie, Interrupts
möglichst zeitnah zu behandeln und möglichst wenig in den Interrupts zu
machen bzw die Interrupts möglichst kurz gesperrt zu lassen.
fchk
Okay, danke für deine Ausführliche Antwort. Dann hab ich ja morgen was
zu tun :-)
Sollten noch Fragen auftauchen melde ich mich noch mal! Aber war schon
mal super für die Hilfe!!
Danke Gruß