Hallo, ich benutze einen Atmega 168P und versuche eine Information auf den CAN-Bus zu packen. Als CAN Treiber und Transceiver nehme ich den MCP2515 bzw. den MCP2551. Leider kommt am Ende nicht wirklich was bei raus und ich hoffe sehr, dass hier jemand einen Fehler entdecken kann. Hier erstmal eine Übersicht der Verbindungen: Atmega <=> MCP2515 MISO - MISO MOSI - MOSI SCK - SCK PB2(SS) - CS MCP2515: OSC1/2 an 16 Mhz OSC + 22nF zu gnd TXCAN und RXCAN zu TXD und RXD vom MCP2551 Reset mit Reset vom Atmel verbunden VDD = 5V Rest ist GND MCP2551: VDD = 5V VSS, RS, VREF = GND Ich hoffe das ist erstmal richtig. Im Anhang habe ich auch noch meine CAN.h, CAN.c und auch eine kleine main. Die main habe ich nur eben gebastelt, damit man sieht wie ich die Sachen initalisiere und Testweise in einer while Schleife etwas auf den CAN-Bus schreiben will. Die Main ist so gekürzt, damit eben keine unnötigen Sachen wie I2C, LCD etc. die Sache nur unübersichtlich machen. Es wäre also sehr nett wenn sich das mal jemand anschauen könnte und mir ggf. meinen Fehler verraten würde! Ich bedanke mich schon mal für die Hilfe. Ps. Bei unverständlichkeiten stehe ich natürlich sofort zur Verfügung. MfG FX
2 Sachen vorweg: MOSI -> SI MISO -> SO Und hast du noch einen weiteren funktionierenden Teilnehmer am CAN-Bus? Ohne Ack von irgendeinem anderen Teilnehmer verabschiedet sich der CAN-Controller ganz schnell in den bus-passive/bus-off-Modus.
Also an dem CANH/CANL vom MCP2551 hängt dann ein Can-Tester dran. Dieser hier: http://canusb.com/ Kann man diesen passiv bzw. off Modus nicht deaktivieren? Also zumindest jetzt beim testen um sicher zu gehen das er nicht in diesen Modus verfällt.
Hätte fast Lust gehabt zu helfen, aber die Rar im Anhang runterzuladen hatte ich dann doch keine Lust :-). Abschlusswiderstand 120 Ohm dran?
Dann eben die files nochmal einzeln :D Abschlusswiderstand sind 110 Ohm aber daran sollte es nicht scheitern oder?! Habe gerade nix besseres da (weder nochmal 10 Ohm oder sonst was um durch parallel auf 120 zu kommen)
Die Frage ist ja schonmal: An welchem Punkt stimmts denn nicht mehr? Hinter µC, hinter dem CAN-Controller, oder hinter dem CAN-Transceiver? Stimmt denn die SPI-Message der gewünschten? Ist schon ein bisschen die Suche nach der Nadel im Heuhaufen wenn man nichts eingrenzen kann.
Ich würde es gerne eingrenzen, die Sache ist nur wie? Also ich VERMUTE, dass aus dem µC alles korrekt raus geht und der CAN-Controller auch noch seine Arbeit erledigt aber dann... ich weiß es nicht. Wenn ich z.B. den init vom CAN-Controller auskommentiere, funktioniert rein garnix mehr... heißt also der (wird vermutlich) korrekt ablaufen. Wie kann ich den am Besten herausfinden wo es sich ggf. aufhängt? Eig. debugge ich ja gerne mit LED's aber ich denke der Signalimpuls ist bei CAN-Bus an sich zu kurz um überhaupt was sehen zu können.
>mcp2515_write_register(TXB0SIDH, (uint8_t) (0x0123>>3)); >mcp2515_write_register(TXB0SIDL, (uint8_t) (0x0123<<5)); Was genau möchtest du damit erreichen, dass du IDH 3 Bits nach rechts und IDL 5 Bits nach links schiebst?
FX schrieb: > Ich würde es gerne eingrenzen, die Sache ist nur wie? > Also ich VERMUTE, dass aus dem µC alles korrekt raus geht und der > CAN-Controller auch noch seine Arbeit erledigt aber dann... ich weiß es > nicht. Heißt also du hast kein Logic ANALlyzer oder Scope um dir die Nachrichten anzuschauen? > Wenn ich z.B. den init vom CAN-Controller auskommentiere, funktioniert > rein garnix mehr... heißt also der (wird vermutlich) korrekt ablaufen. Was heißt denn "rein gar nichts mehr". Ich dachte es funktioniert rein gar nichts? Also funktioniert doch irgendwas? > Wie kann ich den am Besten herausfinden wo es sich ggf. aufhängt? > Eig. debugge ich ja gerne mit LED's aber ich denke der Signalimpuls ist > bei CAN-Bus an sich zu kurz um überhaupt was sehen zu können. Hast du einen MAX232 oder so rumliegen? Dann könnstest du ja zumindest mal testen ob alles in die Register des Cancontroller geschrieben wird. Du könntest dann einfach mit RS232 debuggen über ein Terminal. Und zwar so: Register schreiben -> Register auslesen
Otto schrieb: >>mcp2515_write_register(TXB0SIDH, (uint8_t) (0x0123>>3)); >>mcp2515_write_register(TXB0SIDL, (uint8_t) (0x0123<<5)); > > Was genau möchtest du damit erreichen, dass du IDH 3 Bits nach rechts > und IDL 5 Bits nach links schiebst? Damit will er wahrscheinlich den 11Bit Identifier in die zwei dafür vorgesehenens Register schreiben. Bit 0-2 sind in TXB0SIDL an stelle 5,6,7 (von Bit 0-7) und Bit 3-11 halt in TXB0SIDH an Stelle 0-7
Man muss dazu sagen, dass ich mich an dieses Tutorial halte: http://www.kreatives-chaos.com/artikel/ansteuerung-eines-mcp2515 Ich habe zum debuggen leider nix da aber ich habe mal folgendes probiert: mcp2515_write_register(TXB0D0, 0x05); _delay_ms(100); x = mcp2515_read_register(TXB0D0); Also 5 in TXB0D0 schreiben, kurz warten (nur um sicher zu gehen) und dann auslesen. In x befindet sich aber nicht die 5 sondern eine 0. Der Wert kommt wohl also garnicht erst richtig an.
Sorry, dass ich gefragt hab. Du siehst, ich bin auch mit meinem Latein am Ende. Vielleicht solltest du doch mal das mit den LEDs ausprobieren. Gibt es denn kein Register im Controller, dass du schreiben und lesen kannst? Vlt passt dann irgendwas mit der Clock nicht? Wie sieht denn dein Schaltplan genau aus? Und was funktioniert denn überhaupt? Reset gepulluped?
> OSC1/2 an 16 Mhz OSC + 22nF zu gnd
Mal abgesehen von dem Tippfehler, passen 22pF normalerweise einfach
nicht zu dem Quarz.
Welcher Quarz ist das genau?
Und welche Baudrate ist überhaupt das Ziel?
Hi, Ich mache grade genau das gleiche, den MCP2515 mit nem Atmega verbinden, bei mir ist es ein Atmega88 und es läuft. Habe auch das Tutorial von kreatives-chaos.de benutzt. Poste dir mal meine Stolpersteine. Als erstes sind die Werte von CNF1, CNF3, und CNF3 wichtig. Die sind auch Abhängig von deiner Oszifreq und von deiner gewünschten Bautrate. Im Tutorial gibt es zwei links um sich die Werte Berechnen zu lassen. Der zweite ist ne Homepage als ziel musst du den MCP2510 auswählen. Der erste link ist ein Programm zum runterladen. Lief bei mir aber nicht. So damit hast du die Werte für CNF1, CNF2 und CNF3. Was mir sehr geholfen hat ist,
1 | char CAN_Init() |
2 | {
|
3 | CANReset(); |
4 | _delay_ms(10); |
5 | CANWriteReg(CNF1,CNF1_VAL); |
6 | CANWriteReg(CNF2,CNF2_VAL); |
7 | CANWriteReg(CNF3,CNF3_VAL); |
8 | CANWriteReg(CANINTE,(1<<RX1IE)|(1<<RX0IE)/*|(1<<ERRIE)|(1<<MERRE)*/); |
9 | //Testen on Chip reagiert
|
10 | if (CANReadReg(CNF1) != CNF1_VAL) |
11 | return 0; |
12 | ...
|
13 | ...
|
14 | Auszug aus meiner CAN_Init(); |
lasse, wenn mir die CAN_Init eine 0 zurückgibt eine LED einschalten. So kann ich Testen ob der mCP2515 überhaupt anläuft. Ein Stolperstein bei mir war der SS-Pin der muss als Ausgang gesetzt werden, sonst läuft die SPI nicht. Eine Sache dir mir aufgefallen ist. Du setzt den MCP2515 nicht in den NORMAL-MODE bzw. lässt ihn im CONFIG-MODE. Am Ende deiner CAN-Init() musst du das CANCTRL Register setzen. Werte stehen im Datenblatt. Noch ein Stolperstein sind die ERROR-Flags. Wenn du den MCP2515 initialisierst und dabei Daten auf dem CAN-Bus liegen, setzt der MCP2515 das RX0OVR oder RX1OVR Flag und nix geht mehr. Ganz wichtig beim MCP2515 und eigentlich bei allen Chips von MICROCHIP müssen die Interruptflags immer von Hand also per Software gelöscht werden. Mein Fehler war am Ende. Das ich vergessen habe die beiden Kondensatoren am Quarz des MCP2515 an GND anzuschliessen :). Ach so Vref am MCP2551 ist bei mir Offen.
Florian, magst Du deinen Code posten? Ich hab such win Canprojekt auf der todo-liste mit dem Mega88 und dem MCP. Danke
Klar kannst du meinen Code haben. Bin grade mobil im Netz. Poste den Morgen oder für die ganz genauen Heute wenn es wieder hell ist :).
Super danke Florian! :D Habe ich zumindest schon mal ganz paar Ansätze. Wäre aber super wenn du wirklich nochmal den Code posten könntest, so komplett kann man das wohl besser nachvollziehen :)
Hier ist mein Code. Wie gesagt der basiert auf dem Tutorial von kreatives-chaos.de hab den für meine Bedürfnisse angepasst. Der Code ist eigentlich Teil eines grösseren Projektes habe hier nur alle CAN-relevanten Sachen gepostet. Einige Variablen in tCAN sind nur für mich Wichtig, ins besondere deviceID und die bits. die Status LED liegt auf PB0 der Interrupt vom MCP2515 liegt auf INT0, also PD2. CS liegt auf dem SS Pin also PB2. Es fehlt die mcp2515_defs.h von creatives-chaos.de
Also ich bekomme schon gleich zu begin des Inits eine 0 zurück :(
1 | if (CANReadReg(CNF2) != 0x90) |
2 | return 0; |
Ich habe es auf CNF2 geändert, da ich in CNF1 eine 0 reinschreibe... da die Register aber standart (wohl) auf 0 sind sagt das nix aus. Ich betreibe den MCP2515 mit 16 Mhz und habe daher diese 3 Werte für CNF1-3 ermittelt:
1 | CANWriteReg(CNF1, 0x00); |
2 | CANWriteReg(CNF2, 0x90); |
3 | CANWriteReg(CNF3, 0x02); |
Aber danach geht schon nix mehr :( Es sind SCK, SI, SO, SS mit dem Atmel verbunden und sonst halt VDD, VSS, OSC1, OSC2... und natürlich noch die beiden Can Leitungen zum 2551. Was mir eben aufgefallen ist, im Datenblatt von meinen 168P scheint CS negiert zu sein, wohingegen CS beim 88 "normal" ist. Oder seh ich das falsch? Mir gehen so langsam echt die Ideen aus...
Ist alles richtig angeschlossen? Siehe: Beitrag "Re: Atmega und CAN" > Ich betreibe den MCP2515 mit 16 Mhz und habe daher diese 3 Werte für > CNF1-3 ermittelt: CANWriteReg(CNF1, 0x00); CANWriteReg(CNF2, 0x90); CANWriteReg(CNF3, 0x02); Welche Baudrate willst du denn haben? Und ist die Gegenstelle auf die gleiche Baudrate eingestellt? Was steht in den Fehlerregistern TEC und REC?
Du nutzt meinen Code. Bist du sicher das du die SPI Hardeware die CS Leitung und die INT0 Leitung auf deinen uC angepasst hast ?. Es sieht so aus, als ob deine SPI nicht läuft. Check den SS-PIN und kannst du CS messen ?. Muss halt auf 0 gehen. Kannst du mal deine SPI_Init() und den Teil deines Codes, wo du die DDRn und PORTn Register setzt, posten. Hast du einen Schaltplan ? Kannst du den auch posten?
Was hast du mit dem Resetpin vom MCP2515 gemacht. der sollte über einen Widerstand > 10KOhm an auf VDD gelegt werden.
Verdammt... habe mich nochmal vertan. Sind sogar nur 100 Ohm :/ Würden 500 Ohm auch reichen? Falls nicht müsst ich mal morgen (endlich) mal neue Widerstände besorgen.
Ja habs auch gerade im Datenblatt gesehen. Habe zum Glück noch einmal 10k Ohm gefunden. Werde morgen nochmal schauen obs was bringt... ich hoffe es jedenfalls.
Ich musste eben feststellen, dass beim Quarz die beiden Kondensatoren 22nF haben (ok das wusste ich schon vorher) nur es müssen ja scheinbar 22pF sein oder? Das könnte ja dann durchaus einen Fehler verursachen...
Habe zwar nur 27pF bekommen aber schon läuft der Init ohne weiteres durch und alles weitere geht auch! Danke für die Hilfe! :)
Hey, eine Frage hätte ich noch Florian (oder auch jemand anders wenn es wer weiß): Beim MCP2551 habe ich den RS Pin auf Ground gelegt, ist das so korrekt? Bin mir da nicht sicher, da ich da online unterschiedliche Dinge gefunden habe (z.B. mit 10k Ohm auf Ground).
Clemens E. schrieb: > Ich musste eben feststellen, dass beim Quarz die beiden Kondensatoren > 22nF haben (ok das wusste ich schon vorher) nur es müssen ja scheinbar > 22pF sein oder? Das könnte ja dann durchaus einen Fehler verursachen... Jetzt nicht Dein Ernst, oder? Siehe meinen Post vom 2.8. 09:07... Und 27pF sind wahrscheinlich auch nur geringfügig richtiger aber immer noch nicht korrekt.
> Beim MCP2551 habe ich den RS Pin auf Ground gelegt, ist das so korrekt?
Prinzipiell mal ja, alles weitere steht im Datenblatt Abschnitt 1.4.2:
Ein Widerstand an RS reduziert Störabstrahlung von deiner Schaltung und
sollte deshalb verwendet werden. 10k sind für den Anfang nicht schlecht,
hängt aber von deiner Baudrate ab.
Habe heute mal einen richtigen Praxistest gemacht. Mit 10k Ohm an RS läufts stabiler und sonst ist alles super! :) Also danke für die Hilfe :)
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.