Hallo zusammen, mein erster Beitrag hier :) Ich bin Maren, "Schlosserin" mit Diplom (Fahrzeugtechnik) und daraus lässt sich vermutlich auch schon die wirkliche Ursache des folgenden Problems ableiten...vor dem Bildschirm! Vielleicht mögt ihr mir dennoch helfen, wäre sehr nett! Vorweg: von einigen Übungen im Rahmen des Studiums mit C, C++, Pascal und was weiß ich noch abgesehen, habe ich die längste Zeit meines Lebens in Basic programmiert, auch wenn's doch schon einige Jahre her ist (C64). Daher fiel mir der praktische Einstieg in die uC-Materie mit BASCOM am einfachsten, ich hoffe, die Kritiker mögen es mir verzeihen. Nun aber zum Problem: Ich habe hier ein Olimex headerboard mit einem AT90CAN128 liegen, das die Basis für ein Prototypen-Ersatz-Steuergerät im Kfz werden soll. Dies auch nur zur allerersten Erprobung einer Idee, daher sollte Basic auch reichen, denke ich, denn OBD-Features, Autosar-Kram, etc. brauche ich derzeit nicht... Quarz und Fuses stimmen, wenn ich nur Code für eine im Sekunden-Takt blinkende LED flashe, sehe ich am Ossi auch 1Hz. Sobald ich aber die CAN-Features mit dem Beispiel-Code nutze, der hier irgendwo auch schon gepostet wurde und zum Teil von Sam Berglund stammt, wird er extrem langsam. Die Hauptschleife wird mit nur 3,4 Hz durchlaufen, ich habe eine LED pro Durchlauf 1x toggeln lassen. Es irritiert mich dabei, dass im Code der CAN-Interrupt zwar aktiviert wird, aber nirgendwo gesagt wird, wo er denn im Falle eines IRQ hinspringen soll?! Der Code holt sich die Botschaften im Rahmen der Hauptschleife ab, das war's. Es gibt Beispielcode von Bascom, den ich allerdings gründlich umschreiben müsste, damit er zu meine Hardware-Peripherie passt - würde ich gerne umgehen, zumal der derzeit benutzte Code ja generell funktioniert. Nur eben sehr, sehr langsam... So kann ich das in den finalen Code jedenfalls nicht einbauen. Ich schicke meine Nachrichten vom PC mit 250k extended, nur ein Identifier, Zykluszeit 40ms. Das LCD zeigt diese auch korrekt an. Höre ich mit dem Senden auf, "blinkt die LED" mit 1kHz, Schleifendurchlauf also mit 2kHz. Es muss ein dummer Anfängerfehler sein, aber ich finde ihn nicht, leider :( Ich wäre euch sehr dankbar, wenn da jemand mal drüberschauen könnte! Viele Grüße und einen schönen Maifeiertag, Maren
>Es muss ein dummer Anfängerfehler sein, aber ich finde ihn nicht, leider >:( Versuch mal rauszufinden wie lange deine LCD Ausgaben dauern.
Hi, kommentier doch mal die LCD Sachen aus und schau was passiert. Wenns dann tut wie Du erwartest, dann solltest Du nicht in jeder loop was aufs LCD schreiben, denn das kannst Du sowieso nicht sehen, wenn 20 mal in der Sekunde ein Wert geändert wird. Mach doch jede 10 loop(oder alle 100 loops) eine Ausgabe aufs Display. In der Regel sind max. 3 Ausgaben pro Sekunde noch sinnvoll und ohne Ermüdung anzusehen. Gruß
Guten Abend! Ich danke euch beiden für eure Antworten, daran hatte ich noch gar nicht gedacht. Dabei hab ich schon öfter gelesen, dass LCDs nicht die schnellsten sind...ich werd's auf jeden Fall einpflegen! Mein Gefühl sagt mir aber, dass das noch nicht der einzige Hund war, der dort begraben ist ;) VG, Maren
So, ich wollte mich noch mal kurz melden und die bzw. meine Lösung posten, kann ja sein, dass das auch andere interessiert. Vorweg: Das LCD war's nicht! Stattdessen waren die Interrupts schuld - soweit ich das beurteilen kann :) Jedenfalls hat es geholfen, diese abzuschalten und stattdessen in der Hauptschleife das CANGIT-Register abzufragen, ob eine Botschaft vorliegt. Falls ja, springt der Conroller jetzt in die Sub und holt die ab. Die benötigte Info liegt auf einer ID, die im Broadcast alle 40ms "vorbeikommt". Das hat den uC wohl in seinem Ablauf zu sehr gestört. VG, Maren
Maren B. schrieb: > Die benötigte Info liegt auf einer ID, die im Broadcast alle 40ms > "vorbeikommt". Das hat den uC wohl in seinem Ablauf zu sehr gestört. So grundsätzlich erst einmal eigentlich nicht. Wenn Dein Interrupt für die Verarbeitung einer Botschaft mehr als ein paar µs beschäftigt ist, läuft da was falsch. In C könnte sowas so ähnlich wie das hier aussehen: ISR (CANIT_vect) { uint8_t canpage; canpage = CANPAGE; // save canpage if(CANSIT2 & 0x01) // Mailbox 0 { CANPAGE = (0<<4); // select MOB0 CANSTMOB &= ~(1<<RXOK); // clear interrupt flag buffer_mob0[0] = CANMSG; buffer_mob0[1] = CANMSG; buffer_mob0[2] = CANMSG; buffer_mob0[3] = CANMSG; buffer_mob0[4] = CANMSG; buffer_mob0[5] = CANMSG; buffer_mob0[6] = CANMSG; buffer_mob0[7] = CANMSG; botschaft_mob0_eingegangen = 42; CANCDMOB = (1<<CONMOB1) | (1<<DLC3); } CANPAGE = canpage; // restore canpage } Und auf 250k (komischer Wert) liegt eine 8-Byte Botschaft so um die 400µs auf dem Bus wenn ich mich da nicht verrechne. Also 39,5ms von 40ms passiert da garnichts. Ich kann Dir nur im Detail nicht helfen, weil ich nicht mit Bascom programmiere. :-)
Danke Ich :) Prinzipiell hole ich meine Botschaften derzeit auf diese Weise ab, aber eben dann wenn das Hauptprogramm an einer entsprechenden Anweisung ankommt, die es zur Subroutine schickt, falls das Bit 4 des CANGIT-Registers gesetzt ist. Ist nicht die schöne Lösung, funktioniert aber erstmal. Irgendwo muss da was in den Codeschnipseln faul sein, die ich verwendet habe. Es stand nämlich, trotz aktiviertem Interrupt nirgendwo, welche ISR denn im Falle des Falles angesprungen werden soll. Ein Irrgarten? Obwohl ich dann testweise eine explizite Sprunganweisung hinzugefügt hatte, wurd's nicht besser. Sei's drum, es wird ja so kein Serienprodukt, sondern soll nur als Vor-A-Muster dienen. VG, Maren P.S.: 250k sind übrigens bei LKWs üblich...
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.