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
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
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.
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...
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