hallo,
ich hab ein kleines problem mit den empfangen von cannachrichten.
ich will im 0,9 ms bereich(+- 0,2ms) nachrichten senden und empfangen.
senden alleine ist kein problem(da schaffe ich eine nachricht in ca 0,5ms oder sogar schneller) sobald ich aber nachrichten empfange sinkt die senderate und empfangsrate auf 10ms was mir ca 10x zu langsam ist. in meiner empfangsfunktion sind max 10 prozessortakte mehr arbeit als beim senden, das sollte aber bei 16mhz takt kaum ins gewicht fallen. und ich glaub auch nicht, das der interrupt der mir mitteilt, das eine neue cannachricht vorhanden ist so viel zeit in anspruch nimmt.
die ganzen beispiele was ich im internetgefunden habe(darunter auch das canecho beispeil von atmel selber) sind sogar noch langsamer als mein test.
atmel macht ja viel werbung das man das osek os nachbilden könnte(das setzt sehr schnelles senden und empfangen von can nachrichten vorraus) und der avg4000(ist ja ein at90can12 schafft auch problemlos diese nachrichtenrate.
gruss
markus
edit: das wichtigste hab ich fast vergessen, den quellcode poste ich heute noch, fals jemand aber schon ein tipp hat gleich her damit
beim kurzen überlesen des Codes ist mit die Baudrate von 100kBit aufgefallen.
Wenn Du, wie in Deinem Programm 5 Byte versendest, so dauert dies:
46Bitzeiten (Header,Footer) + (Datenbytes * 8Bitzeiten) = 86 Bitzeiten, was bei 100Kbit ca. 0,86ms macht. Da hast Du dann nur ein Telegramm versendet.
Aber noch nichts Empfangen!!
Besser ist folgender Ablauf, per IRQ Telegramm empfangen (hast Du ja schon eingebaut) und anschließend versenden.
CAN nutzt CSMA/CD, das heißt es wird auf Teufel komm raus gesendet. Dabei wird in kauf genommen, das sich Telegramme gegenseitig auslöschen (CD).
Um dies zu verhindern (da dann komplett wiederholt werden muß), immer nur senden nach einem Empfang, wenn dies möglich ist.
Ansonsten kann es sein, das Du nur die halbe Übertragungs-Bandbreite nutzen kannst, da der Rest alles Collisionen sind.
Setzt einmal die Baudrate hoch, mindestens 500kBit, dann hast Du wieder etwas Luft.
Ansonsten scheint das Prog soweit Okay, nichts auffallendes, werds mir später nochmal genauer ansehen.
naja 100kbit ist fix, da der bus auf den ich mich hängenwill mit 100kbit läuft(und da kann ich auch nix ändern) in minimalen ausbau sind da 4 teilnehmer drann und je nach ausbaustufe noch mehr(bis 20stück) im augenblick habe ich da meinen pc per USB adapter drann, der schafft es ja auch problemlos mit 100kbit.
mir würde es ja reichen dein ausgerechneten 0,86ms zu erreichen, wenn da jede 2. oder 3. nachricht hops geh ist es auch kein weltuntergang
ABER:
so wie programm braucht um auf cannachrichten zu antworten viel zu lange. da wäre dann leider schon ein timeout restlciehn steuergeräten(diese sind nicht von mir sondern von einen vorhandenen system).
in den codebeispiele die ich hochgeladen habe werden in der mainschleife einfach zwei testnachrichten so schnell gesende wie möglich(die werd ich in der praxis nicht brauchen aber zum testen und messen wars sehr hilfreich)
bei 100kBit wird das mit dem Timing aber nichts werden. Da wie gesagt minimale Telegrammlaufzeit 0,86ms sind (da sind evtl. eingefügte Stffbits nicht mitgerechnet).
Bei optimaler Verteilung könnte alle 0,86ms ein Telegramm auf den Bus gelegt werden, d.h. Du kannst nur alle 1,72ms was senden,
wenn noch jemand anderes auch senden möchte. Da es aber zu Kollisionen kommt, wird diese Zeit länger sein.
In Deinem Prog, reagiert der Mega nach max. 4Takten auf den IRQ. Dann bastelst Du die Nachricht zusammen und legst diese in den Sender, der kann dann wenn der Bus frei ist senden.
Du schreibst Dein PC kann es. Der kanns auch nicht, man kann zwar alle 0,1ms was neues in die Messagebox schreiben, aber das heißt nicht das das auch auf dem Bus ist.
Schau Dir das mal mit einem Busmonitor an, dann wirst Du es sehen.
ok das timingproblem hab ich jetzt in den griff bekommen(glaub ich)
aber ein anderes problem hab ich noch:
versende ich nacheinander mehrere nachrichten mit unerschiedlicher länge geht das nur wenn ich für jede nachricht einen eigenen mob verwende, sonst haben sie immer die länge des mob, der als erstes gesendet wurde.
hättest du da noch eine ahnung woran das liegen könnte?
in meinen beispiel oben bräute man nur ein can_txa durch ein can_txb ersetzten(oder umgekehrt) und dann siehst du das problem(ich verwende den canhacker dafür)
nachtrag:
ich hab jetzt noch zum test, bevor die länge in den register geschrieben wird noch ein
CANCDMOB = 0;
eingefügt, damit sollte die msg länge resetted werden, wirds sie aber leider nicht.
keiner eine ahnung? ich hab vor nicht ganz 3 wochen das erste mal ein c++ programm geschrieben. ich vermute das ich nur eine variable falsch definiert hab oder sowas
Lesezeichen