Hallo zusammen, ich arbeite zur Zeit an einem Projekt, welches verschiedenste Messdaten auf einem LCD-Display grafisch darstellt. Die Daten werden über I2C, 1-wire und CAN übertragen. Soweit funktionieren auch alle einzel Komponenten fehlerfrei, nur habe ich jetzt im Zusammenspiel ein Konzeptionelles Problem. Die Hardware: - PIC18F458 @ 20MHz - 1-wire: DS18S20 für die Temperatur - I2C: DS1337 als Uhr, MCHP24FC1024 zur Datenspeicherung - CAN: im Moment noch ein CAN Entwicklungswerkzeug, später aber ein 2ter PIC der im ca. 10ms Raster Messdaten liefert (3 Botschaften) und zufälliger Steuerkomandos, CAM Routinen nach AN738 Das aktuelle Konzept: In meiner Hauptschleife werden der I2C Bus und der DS1820 ausgelesen und das LCD mit allen dargestellten Messwerten einmal aktualisiert! Ein Durchlauf dauert ca.90ms. Die CAN-Messdaten sind in globalen Variablen gespeichtert. Kommt eine neue Botschaft, so wird ein Interrupt ausgelöst und die Botschaft in die entschrechenden Variablen zerlegt! Das Display zeigt also immer den Inhalt der letzten Botschaft, egal viel Botschaften während der 90ms angekommen sind. Nun das Problem: Eine Unterbrechung des Programms durch den Interrut ist kritisch wenn zB das Software 1-Wire Protokoll(ca.10ms)läuft. Daher habe ich mir gedacht, ich verbiete die Interrupts wärend diesem Programmabschnitt, wohl wissend, dass mir später vielleicht 1-2 Botschaften verloren gehen! void low_isr (void){ if ((PIR3bits.RX0IF == 1) || (PIR3bits.RX1IF == 1)){ CAN_RX_Message(); } } . . . PIE3bits.RX0IE = 0; // Enable Interrupt CAN-RX0 (1 En, 0 Dis) PIE3bits.RX1IE = 0; // Enable Interrupt CAN-RX1 (1 En, 0 Dis) uintTAir = DS1820_GetTemp(); // Dauer 10ms PIE3bits.RX0IE = 1; // Enable Interrupt CAN-RX0 (1 En, 0 Dis) PIE3bits.RX1IE = 1; // Enable Interrupt CAN-RX1 (1 En, 0 Dis) (*) // Auslesen der Tasten ReadButtons(); . . . Soweit funktioniert es auch! Nur wenn ich den Abstand mit dem ich Botschaften sende unter 12ms senke, kommt kein weiterer Interrupt mehr zustande, auch wenn ich die Übertragung wieder verlangsame. Ich habe auch schon versucht, an der Stelle (*) die CAN-Overflow bitts zu löschen, aber kein erfolg. So langsam verzweifel ich an dieser Stelle... Hat jemand noch einen Tip, oder eine Idee, wie man es grundsätzlich anders angehen sollte... Danke Matthias
Es gibt keinen Grund, die Interrupts für die gesamte Dauer der 1-Wire Abfrage auszuschalten. Einzig innerhalb eines 1-Wire Bits gibt es kritische Zeitbedingungen. Zwischen den einzelnen Bits bleibt jedoch Zeit. Abhängig von der Laufzeit der Interrupt-Handler kann es auch möglich sein, während der Dauer des ~500µs langen 1-Wire Resets wichtige Interrupts freizugeben, nur muss man dann die obere Grenze beachten, sonst geht dem Device, wenn parasitär versorgt, irgendwann die Luft aus.
1. Könntest du nicht einen I²C Temperatursensor verwenden? Dann sparst du dir die 1-Wire-Schnittstelle. 2. > Nur wenn ich den Abstand mit dem ich > Botschaften sende unter 12ms senke, kommt kein weiterer Interrupt mehr > zustande, auch wenn ich die Übertragung wieder verlangsame. Könnte es sein, dass wenn dein CAN-Controller zu viele Nachrichten verliert, er in einen Bus-Off oder Sleep-Modus geht?
Hallo zusammen, danke für die alternativen Vorschläge zur Umschiffung der Problematik. Es ist schon möglich die Zeit für die Deaktivierung des CAN-Interrupt zu verringern, nur geht es mir bei dem Problem ums Prinzip. Wie gehe ich damit um, wenn ich für eine kurze Zeit keine Interrupt zulassen kann, und genau in diesem Zeitfenster einen Nachricht eintrifft? Ich habe nun den Sonntag noch einmal viel Zeit in dieses Problem investiert und bin etwas schlauer. Immer wenn der Bus stehen bleibt, hat COMSTAT den Wert 128 (RXB0_Overflow). Obwohl ich das Register COMSTAT und PIR3 lösche wird kein neuer Interrupt ausgelöst. Komisch... Das CAN-Modul selber deaktiviert sich nicht, da es weiterhin ACK sendet! Da muss ich wohl noch etwas Zeit investieren... Danke soweit schon mal Matthias
Matthias Werner wrote: > damit um, wenn ich für eine kurze Zeit keine Interrupt zulassen kann, > und genau in diesem Zeitfenster einen Nachricht eintrifft? Na und? Entscheidend ist doch nur, dass in der Zeit in der Interrupts abgeschaltet sind, nicht mehr Messages eintreffen als der Puffer / die beiden Puffer (je nach Modus) verdauen können. Aber du hast recht, dass diese Situation auftreten kann und das System damit klar kommen sollte. Wäre nicht der erste CAN Controller, der in solcher Situation Ärger macht (z.B. PIC18F2580, LPC2300).
Hallo Andreas, ich hoffe mal das mein Controller I.O. ist :) Leider habe ich in der Woche keine Zeit daran weiterzuarbeiten. Ich werde am Wochenende nochmal eingehend nach dem Fehler suchen und danach hier berichten. Gruß MAtthias
HAllo, also ich glaube ich habe es jetzt verstanden das Problem. -> Mein CAN-Modul im PIC ist wohl beschädigt. Ich hatte bei meinem ersten Treiber geraume Zeit vesehentlich den CAN-RX PIN als Ausgang deklariert. Der CAN Tranciever zog dann dank fehlendem Vorwiderstand das PIN auf 0 oder 1. Ich wunderte mich immer warum der PIC so heiß wird und bei zuvielen CAN Messages abstürtzt ;) NAchdem ich Treiber und Layout nun berichtigt habe, hatte ich oben beschriebenes Problem. Bei der Anlyse des PICs heute morgen musste ich aber feststellen, dass sich keine Filter und Filtermasken mehr setzen lassen, und immer alle Messages direkt an RX0 gehen. Jetzt habe ich den CAN auf Extended Messages umgestellt. Die Filterung funktioniert auch hier nicht mehr, aber der Bus stürzt unter gleichen bedingungen nicht mehr ab! Sehr komisch..., da ist wohl was kaputt gegangen innerlich! Danke nochmal für die Hilfe Gruß MAtthias
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.