Ich versuche mit einem MCP2515 CAN Controller und einem SN65HVD230 CAN
Tranceiver Nachrichten auf einem HighspeedBus zu lesen.
Zuerst zum Problem: Ich kann im Loopback Modus Nachrichten verschicken
und auch versenden. Sobald ich aber den Tranceiver an den Highspeedbus
hänge auf dem auch Traffic existiert, kann ich weder den Loopback- noch
den normalen Modus nutzen. In beiden Fällen erhalte ich nach dem
Auslesen des CANSTAT Registers des MCPs den Wert 0xff. Versuche ich eine
Nachricht zu empfangen erhalte ich auch nur 0xff Werte, sowohl für die
Daten, als auch für die ID.
Zum Aufbau:
Das Ganze ist momentan noch frei verkabelt. Zwischen CANH und CANL habe
ich einen Abschlusswiderstand eingebaut. Das Programm zur Ansteuerung
habe ich angefügt (basiert primär auf dem Tutorial von
kreatives-chaos.com). Kann sich jemand einen Reim darauf machen, wieso
der MCP überhaupt nicht mehr funktioniert, sobald ich den HighspeedBus
aktiviere?
Wenn ich das richtig überblicke, deaktivierst Du am Ende der
init-Funktion zwar den Configurationsmodus. Aber Du hast ihn am Anfang
zumindest in der Init nicht gesetzt.
Dann werden alle Zuweisungen von CNF1, CNF2, CNF3, TXRTSCTL, Filter und
Mask Register verworfen.
Siehe Dazu Datenblatt S55 unter 9.0 Mode of operation
Du müßtest noch CANCTRL.REQOP = 100 setzen.
Dann sollte es funktionieren. Ich habe stets die geschriebenen Bytes im
nachfolgen Schritt wieder ausgelesen und bei einer Abweichung die
Initialisierung nicht fortgesetzt.
Danke erstmal für deine Hilfe. Der Configuration Mode sollte eigentlich
gesetzt sein, da am Anfang ein reset erfolgt, das automatisch den
Configuration Mode auslöst.
Wenn ich Canstat auslese erhalte ich während der Init auf jeden Fall
auch 0x80 zurück.
Nimm es mir nicht persönlich, aber was machst Du, wenn Du während der
Laufzeit vielleicht die Register ändern willst. Dann muß Deine Init das
können. Also, warum nicht gleich einbauen.
Ich habe bei mir noch einmal nachgeschaut. Ich habe den "Receive Buffer
Operating Mode" auf 11b gesetzt. -> Dann sind definitiv alle Filter
deaktiviert und der Controler empfängt jede Nachricht.
Als kleiner Tip: Zum Auslesen benutze ich die Read RX Buffer Instruction
11.4 auf Seite 63 (SPI-Interface). Diese 1-Bytebefehle haben den Charme,
dass sie die Interruptleitungen nach erfolgreichem Auslesen automatisch
löschen. Dann entfällt diese lästige Bitmanipulation.
Ansonsten ist mir noch was aufgefallen. Siehe unten.
int main()
{
. . .
//set Loopback Mode
mcp2515_bit_modify(CANCTRL, (1<<REQOP2)|(1<<REQOP1)|(1<<REQOP0),
^ ^ ^
| | |
WAS SOLL DAS ??? alle drei Bits setzen im CANCTRL ist nicht
definiert.
(1<<REQOP1));
_delay_ms(10); < - Delay eigentlich überflüssig, weil der MCP2515
wirklich fix ist.
can_send_message(&message);
_delay_ms(10);
while(1)
{
if(can_get_message(&message2))
{
can_send_message(&message);
can_get_message(&message2);
}
}
WO WIRD HIER DER NORMALE MODUS EINGESCHALTET ???
return 0;
Vielleicht hilft es ja weiter. Übrigens, es ist zwar mühsam, aber ich
habe meinen Treiber selbst geschrieben. Dann schlägt man sich nur mit
seinen eigenen Fehlern herum.
Viel Erfolg
> Nimm es mir nicht persönlich, aber was machst Du, wenn Du während der> Laufzeit vielleicht die Register ändern willst. Dann muß Deine Init das> können. Also, warum nicht gleich einbauen.
Der Reset erfolgt ja jedes mal zu Beginn der Init, von daher sehe ich
das Problem nicht wirklich.
> int main()> {>> . . .> //set Loopback Mode> mcp2515_bit_modify(CANCTRL, (1<<REQOP2)|(1<<REQOP1)|(1<<REQOP0),> ^ ^ ^> | | |> WAS SOLL DAS ??? alle drei Bits setzen im CANCTRL ist nicht> definiert.>>> (1<<REQOP1));
Das ist die Maske für Modify. Anschließend wird nur ein Bit (REQ0P1)
gesetzt. Somit sollte der Controller im Loopback Modus sein.
> _delay_ms(10); < - Delay eigentlich überflüssig, weil der MCP2515> wirklich fix ist.
Wollte nur Fehler in die Richtung ausschließen, habe da auch nicht
wirklich dran geglaubt;)
> can_send_message(&message);> _delay_ms(10);>> while(1)> {> if(can_get_message(&message2))> {> can_send_message(&message);> can_get_message(&message2);> }> }>> WO WIRD HIER DER NORMALE MODUS EINGESCHALTET ???>> return 0;
Der normale Modus wird gar nicht eingeschaltet. Weiter oben habe ich den
Loopback Modus eingeschaltet. Mein Problem ist ja, dass selbst der
Loopback Modus nicht mehr funktioniert, sobald ich den Bus aktiviere.
> Vielleicht hilft es ja weiter. Übrigens, es ist zwar mühsam, aber ich> habe meinen Treiber selbst geschrieben. Dann schlägt man sich nur mit> seinen eigenen Fehlern herum.
Grundsätzlich richtig, aber der Code von kreatives-chaos.com ist
eigentlich recht zuverlässig und ich wollte eigentlich Software Probleme
ausschließen können und habe daher bewährten Code genommen.
Hi,
ja, ich habe die "Lösung" gefunden. Verlass Dich nicht auf andere lautet
die Lösung. Die genannte Lib wimmelt nur so vor Fehlern. Das gemeine
ist, dass sich das im Testbetrieb oft nicht äußert. Erst wenn der Bus
unter Dampf steht (ich bin am Kfz mit 500kBit/s und ordentlich Traffic)
dann geht nix mehr.
Da mit das C-Gelumpe eh auf den Senkel ging habe ich nun meine eigene
Lib in C++ erstellt. Damit läuft's dann wie geschmiert.
Gruß,
Jens
Hi,
wie gesagt bin ich am Kfz, dort sowohl auf dem Innenraum- als auch auf
dem Antriebs-CAN. Was genau ich da nachrüste möchte ich nicht nennen.
Meine Lib werde ich nicht online stellen.
Gruß,
Jens