Hallo bei'nand, ich habe seinerzeit(am Anfang) sowas gesucht, und nicht gefunden. Ein Programm/Projekt in C, das in der AVR-Simulation (CAN-plugin) funktioniert hatte ich schon reingestellt: Beitrag "AT90CAN128 einfaches Beispiel" Hier ist nun ein AVRStudio komplett-Projekt in C, das in Hardware getestet ist. Es können (bestimmte) Nachrichten empfangen werden, mit der Funktion can_tx können Nachrichten gesendet werden. Ein LCDisplay ist angeschlossen auf dem Informationen ausgegeben werden können. Die dazugehörige Datei mit LCD-definitionen und LCD-funktionen ist auch dabei. LCD-Ansteuerung ist im 8bit mode. Das Programm ist getestet und funktioniert in einer Testumgebung mit der CANalyzer-software (http://www.canalyzer.de/) Eine kurze Info-Datei ist auch enthalten. Die meisten Kommentare sind auf englisch, einige auf deutsch. Registereinstellungen müssen an die verwendete HW angepasst werden. Vielen Dank an: mikrocontroller.net (Forum und AVR-GCC-Tutorial) und an Klaus C. für die vielen telefonischen Auskünfte/Hilfen bei der Entwicklung des kleinen Projektes. Inspiriert habe ich mich auch aus dem AVRfreaks.net -Forum. Es ist sicher nicht der beste ProfiCode, man kann sicher einiges an diesem Projekt verbessern. Ich denke aber, daß er für Einsteiger am AT90CAN128 ganz hilfreich sein kann. Anregungen sind willkommen. viel Spaß damit. mg, Johannes
Hallo Johannes, ich wollte mich schon lange mal an den CAN Bus ran wagen. Deine Bibliothek finde ich auf den ersten Blick sehr gut. Ich werde mir die Tage gleich mal den ATMEGA128CAN zulegen. Kannst Du auch gleich mal Deine externe Beschaltung des Bausteins posten, dann könnte man das als Basis CAN Entwicklerboard verwenden und müßte für erste Versuche am Code nix ändern (Zitat: "Registereinstellungen müssen an die verwendete HW angepasst werden.") Würde mir viel Helfen. Danke Florian
Hallo Florian, danke danke für die Komplimente. Anbei der Schaltplan zu meiner Platine. Die LEDs an den TXCAN und RXCAN Leitungen sind zwecklos, sowas bringt nix (wie früher bei der RS232) denn der CAN hört auf RXCAN mit was er auf TXCAN sendet, deswegen blinkt die LED RXCAN wenn gesendet wird... bringt also nix. Denkfehler meinerseits. Als CAN-Treiber verwende ich den AMIS42700, der ist etwas speziell weil er 2 verschiedene CAN-Busse beschreiben/lesen kann (nicht gleichzeitig, aber man kann umswitchen. Das mache ich mit den Pins PD7 und PD4 - Alles was mit PD7 und PD4 zu tun hat kannste im Code also rauswerfen...). Du wirst vermutlich einen SJAxxxx, MCP2515, ATAxxxx oder sonstwas als CAN-Treiber verwenden (gleich mitbestellen). Die schliesst man dann an die RXCAN und TXCAN vom uC an und basta. Alles andere sollte richtig sein. Profi bin ich aber noch nicht, Anregungen/Fragen gerne willkommen. mg, Johannes
Hallo Johannes, vielen Dank. Ich hab gestern den Atmel und genau eben den Treiber MCP2515 und und und bestellt. Dein Layout scheint recht standard und einfach zu sein. Wunderbar :-) Mal sehen wann die ersten Bytes den Controller wechseln. Spannung steigt. Grüße und Danke
Freut mich, dass das kleine Projektchen so viel Anklang findet. Weiterhin viel Spaß beim entwickeln. mg, Johnnes
Wahrscheinlich überflüssiger Hinweis und nur ein Zahlendreher: der MCP2515 ist kein CAN-"Treiber" sondern ein SPI<->CAN-Interface. Falls keine zwei CAN-Busse (ohne Umschaltung) angesteuert werden sollen, reicht der AT90CAN128 aus, denn das CAN-Interface ist schon "drin". Benötigt wird wohl eher ein CAN-Transceiver wie z.B. PCA82C250 u.v.a.m. oder (daher Zahlendreher) MCP2551. Zum Code: display-Routinen sollten in eine header-Datei und ein C-Datei getrennt werden. Das funktioniert so zwar, aber spätestens wenn eine weitere Quellcodedatei die Header-Datei "includiert" gibt's Stress. Die Kontrollmeldung zum LCD im CAN-ISR sollte zumindest mit einem #ifdef DEBUG/#endif ausschaltbar sein, sonst werden jedes Mal viele Register gesichert und die delays in der Ausgaben bremsen erheblich). Solle man deutlich merken, wenn man mit vielen Nachrichten schnell an den Controller sendet. Besser: globale Flags setzen und Display-Ausgabe in der Hauptschleife wenn Flags gesetzt und dann Flags löschen.
Hallo Martin, danke für die Tipps. An die Geschichte mit den LCD-Ausgaben in der ISR hab ich auch schon gedacht gehabt... sowas macht sich in der ISR tatsächlich nicht gut. Beim nächstenmal mach ichs dann besser :) Johannes
Hallo Mir ist nicht klar, was die Zeile CAN_messageType recMsg; bewirkt. CAN_messageType ist eine Variable vom Typ Struct. Aber was ist recMsg? Danke
Um die Sache nochmal deutlicher zu machen, im Quelltext steht: typedef struct { uint32_t id; uint32_t msk ... }CAN_messageType; CAN_messageType recMsg; Mir ist nicht ganz klar, was das bewirkt. Ist das evtl identisch mit: struct CAN_messageType { uint32_t id; uint32_t msk ... }recMsg; Danke!
Nachbauer wrote: > Hallo > > Mir ist nicht klar, was die Zeile > > CAN_messageType recMsg; > > bewirkt. > CAN_messageType ist eine Variable vom Typ Struct. Aber was ist recMsg? > Falsch: CAN_messageType ist der Datentyp rcMsg ist der Name der Variable. Genauso wie bei int var; int ist der Datentyp var ist der Name der Variablen.
Nachbauer wrote: > Um die Sache nochmal deutlicher zu machen, im Quelltext steht: > > typedef struct > { > uint32_t id; > uint32_t msk > ... > }CAN_messageType; > > CAN_messageType recMsg; > > Mir ist nicht ganz klar, was das bewirkt. > Ist das evtl identisch mit: > > struct CAN_messageType > { > uint32_t id; > uint32_t msk > ... > }recMsg; > fast. Wenn du es wie letzteres machst, dann must du jedesmal das Schluesselwort 'struct' wiederholen, wenn du irgendwas mit der struct machst. Also zb. 5 Variablen vom Typ struct CAN_messageType definieren: struct CAN_messageType Var1; struct CAN_messageType Var2; struct CAN_messageType Var3, Var 4, Var5; oder eine derartige struct an eine Funktion übergeben: void foo( struct CAN_messageType Param1 ) { ... } und jetzt kommt der typedef ins Spiel: mittels typedef definiert man sich einen neuen Namen für einen bereits bestehenden Datentyp. typedef struct MyStruct { .... } CAN_messageType; definiert für die struct MyStruct einen neuen Namen, nämlich CAN_messageType. Damit kann man dann die Schreibweise abkürzen, da der Datentyp CAN_messageType ja jetzt als solcher bekannt ist: CAN_messageType Var1; CAN_messageType Var2; CAN_messageType Var3, Var4, Var5; oder auch void foo( CAN_messageType Param1 ) { ... } Damit braucht aber niemand mehr den originalen Namen der struct (der da war 'MyStruct'). Damit kann man die struct dann aber auch als anonyme struct ausführen und landet bei typedef struct { .... } CAN_messageType; und hat damit eine struct, die anonym ist und gleichzeitig definiert man sich für diesen Datentyp einen Namen, nämlich CAN_messageType, der wie jeder andere Datentyp verwendet werden kann. Schlag einfach mal in deinem Lieblingsbuch über C das Kapitel auf, indem der typedef besprochen wird. Du hast doch (mindestens) ein Buch über C? Wenn nicht, solltest du dir eines besorgen.
Danke für die ausführliche Hilfe. Habe natürlich ein C-Buch (Helmut Erlenkötter), war aber gestern nicht zuhause.
Hallo, vielen Dank kbuchegg für die infos zu meinem Code (stimmt alles :) ). Hab selbst seit längerem nicht mehr reingesehen... mg, Johannes
Tag Johannes! Ich habe noch Fragen zu deiner Hardware. Du hast als Abschluß zwischen CANL und CANH jeweils 60 Ohm. Sollten das nicht beim Highspeed CAN jeweils 120 Ohm sein? Zudem hast du auf den 3er Steckern CAN1 und CAN2 jeweils noch die Masse geführt. Die wird aber nicht mit dem Bus verbunden, oder? Also auch nicht über einen Kondensator oder ähnliches?
Hallo, das mit den 120 Ohm stimmt. man kann oft auch 60 Ohm verwenden, funktioniert in unkritischen Fällen auch (zB bei mir :) ). Hatte das irgendwo gelesen... und dann mal probiert. Auf unseren CAN-Kabeln sind immer drei Leitungen, CANL,CANH und GND. deswegen hab ich meine GND dort auch verbunden. Theoretisch braucht man aber tatsächlich nur zwei Leitungen. Die Masse sollte aber an allen Terminals die Gleiche sein... sonst pasiert vielleicht was Ungutes... ich denke, das ist schon richtig so. Mg, Johannes
Wow, super Erklärung für Anfänger und anschaulich dargestellt! Vielen Dank für Deinen Beitrag und Eure Anmerkungen! Vielleicht findet sich ja jemand der daraus ein Tutorial basteln kann. Denn davon gibts z.Zt. noch keins...
Danke für eure Infos, das merke ich mir, Vajk
a) Die Schaltung von Johannes hat einige Maengel: 1) Das ISP ist falsch angeschlossen: ATmega128 und AT90CAN128 verwenden zur seriellen Speicherprogrammierung nicht wie bei den uebrigen AVRs ueblich die SPI-Pins, sondern PDI, PDO, SCK und /RESET (siehe doc7679.pdf Seite 349). 2) Der MAX705 ist, so wie er hier verwendet wird, voellig ueberfluessig, da seine Funktionalitaet bereits im AT90CAN128 implementiert ist. 3) Der A/D-Wandler wird nicht die maximale Genauigkeit erreichen, da er nicht ausreichend entstoert ist (siehe doc7679.pdf Seite 282). 4) Am Spannungsstabilisator fehlt die Freilaufdiode. b) Fuer die, die auch sonst keine Datenblaetter und Standards lesen, hier noch mal etwas Nachhilfe: 1) Der CAN bus verwendet drei Leitungen: CAN high, CAN low und CAN ground. Die Daten werden differentiell uebertragen, daher kann unter guenstigen auesseren Umstaenden auch CAN ground entfallen. Es kann auch (entsprechende Hardware vorausgesetzt) entweder CAN high oder CAN low entfallen, denn die Daten werden ja differentiell, also redundant uebertragen. 2) Zur Terminierung des CAN-Datenkabels: Es ist voellig egal, ob irgendwo im Internet jemand schreibt, dass es x Ohm sein muessen. Das Problem ist, dass anscheinend niemand verstanden hat, wofuer die Terminierung gut ist: Die Dimensionierung der Abschlusswiderstaende richtet sich nach dem Wellenwiderstand des verwendeten Kabels. Gruss Rik
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.