Guten Morgen, seit ein paar Tagen bin ich dabei eine CAN Kommunikation zwischen CAN Dongle (PEAKTECH) und Mikrocontroller XC886/888 zu realiseren. Dazu habe ich mir ein CAN Kabel selber gebastelt. Die eine Seite, die an den CAN Dongle angeschlossen wird, habe ich mit 120Ohm abgeschlossen. Auf der Seite des Mikrocontroller ist der 120Ohm widerstand schon vorhanden. Auf beiden Seiten habe ich zuerst mit 500kBit/s und dann mit 100kBit/s probiert. In einer while(1) Schleife sende ich dauernd die CAN Nachricht. Kann das sein, dass das zu schnell ist, so dass der CAN Dongle nicht mehr mitkommt?
Liegen die Signale auf der Leitung sauber an? Nutzt du den internen Oszillator? Für CAN wird ein externer empfohlen.
Ich verwende den externen Quarz, der auch auf den Starter-Kid Board drauf ist. Den CAN Dongle habe ich an der SUBD9 Stecker (CAN1=PIN1.3 und PIN1.4) vom Starter-Kid angeschlossen Hast du bei dir eine CAN Applikation am laufen? Wenn ja könntest du mir Screenshots von Tool DAVE machen? Ich brächte da nur die EInstellungen für CAN.
Hallo Carsten, weis meinst du mit "ob die Signale sauber auf der Leitung liegen"? Ich verwende den externen Quarz, der auch auf dem Starter-Kid Board drauf ist. Den CAN Dongle habe ich an dem SUBD9 Stecker (CAN1=PIN1.3 und PIN1.4) vom Starter-Kid angeschlossen Hast du bei dir eine CAN Applikation am laufen? Wenn ja könntest du mir Screenshots von Tool DAVE machen? Ich bräuchte da nur die Einstellungen für CAN. Ich vermute das ich das Bit-Timing falsch eingestellt habe.
Anbei eine Demo eines CAN-Programmes auf einem XC888. Das Programm macht folgendes: Nach einem Tastendruck sendet es eine Nachricht auf den CAN-BUS, dadurch beginnt ein anderer µC zu zählen und sendet die Zählerstände an den XC888. Diese werden dann an Port3 (LEDs) ausgegeben. Wichtig ist, dass die "short_shared_int" verwendet wird und nicht die "shared_int" von DAvE.
sorry, warum der anhang fehlt weiß ich jetzt auch nicht? Komm aber heute nicht mehr dran. Hoffe ich denke Morgen dran.
Guten Morgen Carsten, vielen Dank für deinen Quellcode. Gestern Abend habe ich es geschafft (ohne deinen Quellcode) eine CAN NAchricht vom Mikrocontroller an den CAN Dongle zu senden. Bis jetzt kann ich nur 4 Bytes senden. Mit 8Bytes da gibt es Probleme. Man müsste doch 8Bytes senden können oder? Die Funktion zum senden von CAN Nachrichten ist im Dateianhang.
Du musst auch das DATAH-Register beschreiben. Da stehen dann die oberen 4Bytes drin. Wie der Zugriff aber genau aussieht (mit Access-Mediator) weiß ich auch nicht, habs noch nicht selbst gemacht.
Ja genau der Zugriff weiss ich auch nicht wie der aussieht. Hab gestern Abend noch eine Weile da rumgemacht.
Hallo, habe gerade mit dem DAvE kurz ein Beispiel zusammen geklickt. Sendet jetzt 8 Datenbytes pro Nachricht.
Danke Carsten! Ich werde den Code erst heute Abend testen können. Was hast du da in DAVE verändert? Ich habe zuvor auch 8Daten Bytes in Dave ausgewählt. Funktioniert hat es bei mir nicht.
Ich habe einfach mal 8 Datenbytes eingestellt, diese gleich mit Werten von 1-8 gefüllt und dann in der while-Schleife sende ich regelmäßig das MO. Dafür verwende ich die DAvE-Funktion CAN_vTransmit(0*); * 0 wegen MessageObjekt0
Komisch das habe ich gestern auch genauso mit DAVE gemacht. Funktioniert hat es nicht. Ah mir fällt jetzt ein ich habe ja die obige sende Funktion verwendet. Du verwendest ja nur die Transmit Funktion.
Das mit der sende Funktion müsste doch auch gehen oder? Dort werden nur 4Bytes verarbeitet.
Keine Ahnung! Habe bisher immer die Transmit-Funktion genommen und bin mit ihr zufrieden.
Wenn ich meine Sendefunktion so ausbaue, auf 8Bytes dann erhalte ich vom Keil Compiler Fehlermeldungen siehe Dateianhang
1 | void komSendeDaten(char id,char datenByte1,char datenByte2,char datenByte3,char datenByte4) |
2 | {
|
3 | pdata un_32bit canDataObject; |
4 | pdata un_32bit canDataObject2; |
5 | pdata un_32bit canIDObject; |
6 | pdata stCAN_SWObj canTransmitObject; |
7 | |
8 | CAN_vGetMsgObj(TRANSMIT_OBJECT, &canTransmitObject); |
9 | |
10 | canIDObject.ulVal = id; |
11 | |
12 | canDataObject.ubDB[0] = datenByte4; |
13 | canDataObject.ubDB[1] = datenByte3; |
14 | canDataObject.ubDB[2] = datenByte2; |
15 | canDataObject.ubDB[3] = datenByte1; |
16 | |
17 | canTransmitObject.ulID = canIDObject; |
18 | canTransmitObject.ulDATAL = canDataObject; |
19 | |
20 | canDataObject.ubDB[0] = 0x21; |
21 | canDataObject.ubDB[1] = 0x22; |
22 | canDataObject.ubDB[2] = 0x23; |
23 | canDataObject.ubDB[3] = 0x24; |
24 | |
25 | canTransmitObject.ulDATAH = canDataObject2; |
26 | |
27 | CAN_vConfigMsgObj( TRANSMIT_OBJECT, &canTransmitObject ); |
28 | |
29 | CAN_vTransmit(TRANSMIT_OBJECT); // Sende-Prozess starten |
30 | }
|
Also ich vermute, dass es an der Keil Software liegen könnte. Ich habe eigentlich keine Lizens dafür. Hab die Software vom Internet
Ja, da hast du die max. Codegröße der Demo-Version überschritten.
Mit DAVE kann der Loop Back Mode aktiviert bzw. deaktiviert werden. Was bedeutet der Loop Back Mode eigentlich? Werde aus der DOKU nicht ganz schlau draus!
Loop Back Mode heißt, das der Controller einen "internen" CAN-BUS einschaltet anstatt auf die PINs zu gehen. Dieser ist für interne Testzwecke gedacht.
Achso, und den hatte ich zuvor aktiviert. Desshalb konnte ich auf dem CAN Dongle nix sehen. Hast du dich mal genauer mit dem Bit Timing beschäftigt? Im Manual gibt es dazu einige Formeln. Mit DAVE können dan TSEG1 und TSEG2 usw. eingestellt werden. Kommt man anhand der Formeln auch auf diese Werte?
Ne, hab da nie was verändert. Aber in der Regel rechnet sich DAvE die Sachen anhand der Formeln richtig aus. Blöd wird es nur, wenn es Zustände gibt, die nicht erlaubt sind, aber man rein mathematisch gesehen in die Formel einsetzen kann.
Guten Morgen Carsten,
am Wochenende habe ich mich mal mit den MultiCAN Interrupt beschäftigt.
Zuerst habe ich mir das Beispiel "MCAN_GettingStarted" von der Infineon
Seite
heruntergeladen.
Ausschnitt aus der Interrupt Routine "SHARED_INT.C":
>>Siehe Dateianhang INT.TXT
1 | CAN_vWriteCANAddress(CAN_MODATAL(ubTempMsgID)); // Add this line CAN_vReadEN(); // Add this line |
2 | IO_vWritePort(P3, CAN_DATA0); // Add this line |
Hier wird gezeigt wie man ein Datenbyte von der CAN Botschaft auf den Port3 ausgibt. WIe kann man die ID die Datenlänge usw. auslesen? Weiss nicht wie man dies in dem Interrupt macht.
Muss man das überhaupt? Viel Intelligenz im CAN-Netzwerk wird schon beim Design reingesteckt - will damit sagen, dass du ja "normalerweise" weißt, wie lange eine Nachricht mit einer bestimmten ID ist. Und eine bestimmte ID wird nur für ein Messageobjekt aktiviert, das heißt anhand vom MO kannst du dir denken welche Message-ID es war.
Ja ok, aber wenn ich jetzt z.B. 5 unterschiedliche CAN Botschaften empfangen möchte, dann sind die ID's (bzw. DLC) schon wichtig. Damit kann ich ja eine bestimmte ID abfragen.Wie kann man dies trotzdem in der Interruptroutine die ID und DLC abfragen bzw. auslesen? Was meinst du damit? >>Und eine bestimmte ID wird nur für ein Messageobjekt aktiviert, das heißt >>anhand vom MO kannst du dir denken welche Message-ID es war.
Wenn du 5 unterschiedliche Nachrichten empfangen willst, z.B. ID 1-5 dann machst du eine Zuordnung MO0 empfang nur ID 0x001, MO1 nur ID 0x002 etc. Dann weißt du automatisch wenn du eine Nachricht in MO1 hast, dass die ID 0x002 war.
Achso dann lege ich z.B. mit Dave 5 Message Objekte an, in denen soll die CAN Botschaften gespeichert werden. Jedes Message Objekt bekommt eine ID zugwiesen. Wie könnte ich dann die ID's von den MO's bestimmen? Ich habe bissher nur mit der ReadFifo Funktion experimentiert. Hier möchte ich aber das FIFO Prinzip nicht verwenden.
Ja und wenn ich die CAN_ubReadFIFO Funktion nicht verwende, wie könnte ich die ID's von den MO's dann auslesen? Ich habe bissher nur mit der CAN_ubReadFIFO Funktion gearbeitet um die Daten von den MO's auszulesen.
Schau dir mal das Beispiel XC800_CAN_DEMO an. In der short_shared_int.c werden die Daten des MO Nr.0 ausgelesen. Die von DAvE erzeugten Interrupt-Funktionen sind irgendwie nicht ganz fehlerfrei, sprich funktionieren unter manchen Bedingungen nicht sauber.
Das Beispiel habe ich mir mal angeschaut. Warum verwendest du da nicht die generierte "SHARED_INT.C" Datei? [c] void SHINT_viXINTR5Isr(void) interrupt XINTR5INT { CAN_pushAMRegs(); // Push the CAN Access Mediator Registers IRCON2 &= ~(ubyte)0x01; / Clear CANSRC0 CAN_vWriteCANAddress(CAN_MSPND0); Addressing CAN_MSPND0 CAN_DATA0 = ~(0x01); // clear message pending register CAN_vWriteEN(D0_VALID); // bitposition 0 ( message object 0 ) CAN_vWriteCANAddress(CAN_MOCTR0); / Addressing CAN_MOCTR0 CAN_DATA0 = 0x09; // Reset RxPND and NEWDAT flag for object 0 CAN_vWriteEN(D0_VALID); CAN_vWriteCANAddress(CAN_MODATAL0);//Show received ADC value on port 3 LED's CAN_vReadEN(); P3_DATA = CAN_DATA0; CAN_popAMRegs(); // restore the CAN Access Mediator Registers } // End of function SHINT_viXINTR5Isr Wie kann ich da nun die ID und die Datenlänge auslesen?
Ich verwende diese Datei so, weil die vom DAvE erzeugte manchmal an einer Bitabfrage hängen blieb. Wie schon erwähnt, die ID und die Datenlänge lese ich nicht aus, die weiß ich schon bei der Planung des CAN-Netzwerkes. In diesem Fall, alles was im MO Nr.0 steht hat 1Byte Daten. Die ID wird bei der Initialiserung (vom DAvE) festgelegt und danch nicht merh verändert. Ich weiß auch nicht, warum du die ID auswerten willst? Du hast eine "feste" Zuordnung ID-MessageObjekt.
Ja und wie würdest du alle 8Bytes auslesen? Vorausgesetzt das Message Objekt 0 hat auch 8Bytes.
Weiß nicht ob es funktioiert, aber in etwa so: CAN_vWriteCANAddress(CAN_MODATAL0); untere 4 DatenBytes CAN_vReadEN(); a = CAN_DATA0; b = CAN_DATA1; c = CAN_DATA2; d = CAN_DATA3; CAN_vWriteCANAddress(CAN_MODATAH0); obere 4 DatenBytes CAN_vReadEN(); e = CAN_DATA0; f = CAN_DATA1; g = CAN_DATA2; h = CAN_DATA3; Du kannst immer nur 4 Datenbytes zugreifen, danach muss die Adresse mittel AccessMediator geändert werden.
Mir fällt dabei auf, wenn ich zuvor in DAVE 5 Message Objekte für den Empfang angelegt habe, dann muss ich doch in der Interruptroutine diese auch unterscheiden können. MO1: ID=0x01,1 Datenbyte mit Inhalt 0x55 MO2: ID=0x02,1 Datenbyte mit Inhalt 0xAA MO3: ID=0x03,1 Datenbyte mit Inhalt 0xCC MO4: ID=0x04,1 Datenbyte mit Inhalt 0x11 MO5: ID=0x05,1 Datenbyte mit Inhalt 0x33 Wenn ich jetzt das MO1 auslesen möchte, wie müsste ich dies in der Interruptroutine abfragen?
Dann schreibt man bei CAN_MODATAH0 bzw. CAN_MODATAL0 anstatt eine 0 die Nr. des MOs. (z.B. CAN_MODATAL5 für MO5) Somit weiß der AccessMediator dass du jetzt auf die Daten des anderen MOs zugreifen willst.
Trotzdem müsste es doch möglich sein, im Programm die ID vom aktivierten Message Objekt auszulesen, oder? Wenn ich mit DAVE die ID von einem Message Objekt festlegen kannn, dann müsste man doch auch die ID auslesen können. Im Konfigurationsfenster von DAVE kann man die Aktzeptanz Maske, Priority Class (PRI) und die Single Transmission Trail einstellen bzw. aktivieren/deaktivieren. Bei Priority Class (PRI) kann man wählen zwischen list order oder CAN ID. Wo ist da der Unterschied? Wenn ich keine ID ilterung möchte, dann muss ich "Accept reception of standard and extended frames" auswählen?
Also ich muss sagen, das Datenblatt zu dem Mikrocontroller ist ganz schön verwirrent.
Vielen Dank nochmals Carsten. Es scheint so als, ob du momentan so der Einzige bist, der sich mit diesem Mikrocontroller gut auskennt.
Ich denke du kannst die ID des MOs auslesen (über AccessMediator), aber diese muss widerum nicht der ID der Nachricht entsprechen (Falls die Acceptance Mask sagt es müssen nur 2 bestimmte Bits übereinstimmen, z.B. 0x0F3 könnte bei MO-ID 0x003 akzeptiert werden bei enstprechender Maskierung 0x003) Aber wieso soll ich die ID eines MOs auslesen, wenn ich Sie schon kenne? Hab sie ja selbst programmiert. Damit man auf mehrere IDs reagieren kann hat man dem Teil ja die vielen MOs spendiert. Und ich glaube dass man auch wirklich nur an die Datenbytes ran kommt. Die restlichen Bits werden ja berücksichtigt bei der Auswahl ob eine Nachricht in einem MO gespeichert wird oder nicht. Wenn du eine Art Absender angeben willst, dann schreib die Adresse doch ins Datenbyte0.
>>Wenn du eine Art Absender angeben willst, dann schreib die Adresse doch >>ins Datenbyte0. Ja eigentlich ist das Auslesen der ID unnütz, da ich die ID von dem Message Obejkt ja schon kenne. Im Dateianhang befindet sich die Einstellungen zu dem Message Objekt 8. Hier habe ich doch die Filterung deaktiviert oder? Was bedeutet da CAN ID bei PRI? Wenn ich die Filterung aktiveren möchte, dann muss ich doch "only receive frames with matching ID bit" aktivieren und bei MASK 11-Bit einen Wert eingeben. Z.B. MO8: ID=0x002 --> MASK 11-Bit=0x002 --> nur ID 0x02 durchlassen
Bei deiner Einstellung werden sowohl die 11-bit als auch die 29-bit ID angenommen. Wenn du nur den ausgewählten ID-Bereich (11 oder 29 Bit) akzeptieren möchtest musst du "only receive frames with matching ID bit" aktivieren. Nun zur Maskierung: Wenn die Message ID 1 zu 1 mit der MO-ID übereinstimmen soll, dann muss die Maske überall 1en haben (z.B. bei 11Bit-ID 0x7FF) Bei deinem Beispiel Mask=0x002 wird nur Bit 1 zur entscheidung Betrachtet. Binär sieht das dann so aus: 000 0000 0010 Wenn nun aber eine Message mit ID 111 1111 1111 kommt wird diese mit der Mask verundet und übrig bleibt 000 0000 0010 und würde somit akzeptiert werden. Ist die Mask 0x7FF dann bleibt als "ID" 0x7FF über, was nicht akzeptiert wird. Dieser Mechanismus ist da, um gewisse IDs zu gruppieren (µC reagiert auf mehrer Message IDs gleich - z.B. mehrere Notauschalter an einer Maschine die die "Notausnachricht" jeweils mit eigener ID senden)
Habs jetzt herausgefunden, muss allerdings erst noch testen: CAN_vWriteCANAddress(CAN_MOAR0); // ID from Message Objekt 0 CAN_vReadEN(); uID = CAN_DATA0; Jetzt weiss ich nicht, ob dann die ID in der Variable Data0 steht.
Bei 11-Bit steht die ID in Byte0 und 1, bei 29Bit in allen 4 Datenbytes
Ich habe diesen C-Code:
1 | CAN_vWriteCANAddress(CAN_MOAR0); // ID from Message Objekt 0 |
2 | CAN_vReadEN(); |
3 | P3_DATA = CAN_DATA0; //P3_DATA = CAN_DATA1; |
in die Interruptroutine eingebaut. An Port4 (LED) sehe ich die ID nicht. Hast du eine Ahnung woran es liegen könnte?
Sorry, der folgende Beitrag sollte hier rein: Hallo, ich habe mir einen FIFO-Puffer mit 3 Message Objekten gebildet, um CAN-Pakete zu Empfangen und zu einem späteren Zeitpunkt zu bearbeiten. Objekt Liste von CAN Node 1 sieht folgendermassen aus: Message Object 0-1 => FIFO-Puffer Objekte Message Object 2 => FIFO Base Object Ich nutze die von Dave generierte Funktion CAN_ubReadFIFO um aktuelle Nachrichten aus dem FIFO-Puffer zu laden und dann zu bearbeiten. main(void) { ... while(1) { CAN_ubReadFIFO(2,&receive); wait(500); // Verzögerung P3_DATA = receive.datenByte1; } } Leider gibt die Funktion CAN_ubReadFIFO nur das erste CAN Paket (über den als Paramter übergebenen Zeiger) das ankommt zurück (Rückgabewert der Funktion ist 1, was dafür steht, dass ein neues CAN-Pakete über den Zeiger zurückgegeben wurde). Bei jedem weiteren gibt die Funktion den Wert 0 zurück, was laut Funktionsbeschreibung aussagt, dass keine neuen Pakete vorliegen. Nun weiss ich leider nicht ob das Problem an der Funktion liegt oder das angekommene Paket gar nicht erst in den FIFO-Puffer eingetragen wurde und deshalb die Funktion nichts zurück liefert. Muss ich noch etwas beachten, evtl. in DAVE ?
Also ich bin mir sicher, dass die Funktion korrekt ist. Wahrscheinlich liegt das Problem in der DAVE Einstellung. In dem Message Objekt 2 kann ich die Daten auslesen. Nur in den Message Objekten 0 und 1 sind keine Daten vorhanden.
Hier hab ich mal ein Beispiel mit FIFO, da habe ich die Sachen eigentlich schön empfangen können. MO0 ist Base-Objekt und FIFO geht bis MO6. Was machst du eigentlich mit dem XC88x, schreibst du ne Dipl.(oder Studien)Arbeit. Bekommst du von deinem Distributor (wo hast du die Teile her?) keine Unterstützung?
Hallo Carsten, erstmal recht herzlichen Danke für die Hilfe! Ich verwende diesen Mikrocontroller in der Firma. Ich soll den CAN zum Laufen bringen. So wie ich das jetzt feststellen konnte, verwendest du die Funktion "CAN_vGetMsgObj" in der Interruptroutine. Also ich habe die ganze Zeit die Funktion "CAN_ubReadFIFO" benutzt. Warum eigentlich die Funktion "CAN_vGetMsgObj" ? Muss allerdings das Projekt von dir mit DAVE anschauen.
Hallo Carsten, dein Projekt lässt sich mit DAVE nicht öffnen. Die Fehlermeldung habe ich mal an den Dateianhang gehängt. Wenn ich bei mir ein Projekt neu anlege, dann funktioniert das auch. Ich habe die DAVE Version 2.0 installiert. Laut Fehlermeldung müsste ich "XC888CLM" installieren. Aber das habe ich doch bereits getan.
Auf der Infineon Seite gibt es mehrere Versionen von "XC888CLM".
>>http://www.infineon.com/cgi-bin/ifx/portal/ep/programView.do?channelId=-81334&programId=48184&programPage=%2Fep%2Fprogram%2Fdocument.jsp&pageTypeId=17099
Da kann es sein, dass du eine andere Version Installiert hast.
Gestern hatte ich noch so meine Schwierigkeiten mit dem ID-Filter. Bei der ID-Filterung bin ich so vorgegangen: - "only receive frames with matching ID bit" -> aktiviert - ID = 0x001 - Maske = 0x001 Dann müsste doch nur die CAN Botschaft mit der ID = 0x001 durchkommen oder?
Nein, Die Maske besagt welche Bits von der MO-ID und der Nachrichten-ID übereinstimmen müssen. Wenn du nur eine Nachricht akzeptieren willst, dann muss die Maske 0x7FF (über all 1 en) sein. Bei Maske 0x001 würde z.B. auch 0x1F1 ankommen oder 0x00F.
DAVE stellt für die CAN Kommunikation so viele Funktionen zur Verfügung. - CAN-ubGetTxErrorCounter - CAN_ubGetRxErrorCounter - CAN_ubGetErrorTransferDirection - CAN_ubGetErrorIncrement - CAN_ubRequestMsgObj - CAN_ubWriteFIFO - CAN_ubMsgLost usw...für was sind diese Funktionen sinnvoll. Hab sie noch nie so verwendet. Es scheint so als ob man eigentlich gar nicht alle Funktionen überhaupt braucht, oder?
Richtig, ich glaube da hilft einfach nur probieren. Oft wird mit den DAvE-Funktionen der Code unnötig groß, da er immer die Bankwechsel etc. berücksichtigt (ob nötig oder nicht). Aber für den schnellen Erfolg, bzw. ein paar Ideen abzuschauen sind sie doch ganz nützlich.
Hast du mittlerweile herausgefunden, wie man zu jederzeit von einem vordefiniertem Message Objekt die ID dazu auslesen kann?
1 | CAN_vWriteCANAddress(CAN_MOAR0); |
2 | CAN_vReadEN(); |
3 | P3_DATA = CAN_DATA0; |
Funktionieren tut dies bei mir nicht so? Bin echt ratlos.
Hab da jetzt nichts weiter damit gemacht und werde auch in der nächsten Zeit nicht dazu kommen weitere Einstellungen auszuprobieren bzw. auszulesen. Sorry.
Also das Senden und Empfangen von CAN Nachrichten funktioniert ja erstaml sehr gut mit dem Mikrocontroller. Im Internet bin ich auf das Protokoll CANOPEN gestoßen. Dieses wird sehr häufig in der Automatisierungstechnik usw. eingesetzt. Ist es sehr schwierig das CANOPEN Protokoll auf dem Mikrocontroller zu implementieren? Ich möchte nur mal zwei Message Objekte verwenden, die jeweils 1 Datenbyte beinhalten. Um da näher ein zu steigen benötige ich zuerst eine deutsche Beschreibung. Die CAN ID soll dann so aussehen: Bit 10 bis Bit 7 = Baugruppenadresse Bit 6 bis Bit 0 = interne Adresse (Objekt)
Wie schon erwähnt habe ich mal was mit dem SJA1000 gemacht. Dieser besitzt für die CAN ID Filterung das ACR Register und AMR Register. Der XC888 hingegen hat nur ein AMR Register für die Filterung. Wenn ich das AMR Register auf 0x7FF einstelle und das Message Objekt besitzt die ID 0x005, dann wird doch nur die Nachricht mit der ID 0x005 durchgelassen. Wie kann man mit dem XC888 eine Filterung so gestallten, dass zuerst nur die oberen 4 Bits durchgelassen werden und die unteren 7 Bits überhaupt nicht in betracht gezogen werden sollen? Beispiel: CAN ID: 0004 xxxxxxx
Hallo, Wenn dich nur die 4 MSBs interssieren sieht der Filter bei 11-Bit ID so aus: 0x780 (Binär wäre das 111 1000 0000)
Ok danke Carsten, wenn ich dann anschließend die unteren 7 Bits in Betracht ziehen möchte, dann müsste ich das AMR Register auf 000 0111 1111 einstellen.
Hallo Carsten St, mit welchem Register kann überprüft werden, ob eine CAN Nachricht aktuell anliegt oder nicht? Wenn z. B. eine CAN Nachricht auf dem Bus anliegt, dann soll erst die CAN Nachricht in das vordefinierte Message Objekt gespeichert werden.
Hab im Datenblatt das Status Register entdeckt. Mit dem Register MOSTATn kann überprüft werden ob, aktuell eine CAN Nachricht anliegt oder nicht.
Guten Morgen, hab gestern Abend nur mal überprüfen wollen, ob eine CAN Nachricht vorliegt oder nicht. Leider hab ich dies nicht hin bekommen. Ich habe es bisher nicht geschafft, zu prüfen ob eine CAN Nachricht vorhanden ist oder nicht. Wenn eine NAchricht auf dem Bus liegt, soll die ID ermittelt werden und anschlißend das Message Objekt neu angelegt werden. Wie kann ich dies mit dem XC888 realisieren?
Hallo, habe mich leider geirrt, im MOARn Register steht die ID der im MessageObjekt empfangenen Nachricht. z.B. Arbitrierungs-ID: 0x001 (MOARn) Filtermaske 0x00F Nachrichten-ID 0x31 danach steht in MOARn 0x31, wird also überschrieben (macht aber nichts aus) n = 0..31 -> Wenn du also die Maske auf 0x000 einstellst empfängst du jede Nachricht und kannst so die ID auslesen. (auf MOAR musst du natürlich über den Access Mediator)
Die CAN ID kann ich folgendermaßen auslesen: //Message Objekt 0 CAN_vWriteCANAddress(CAN_MOAR0); CAN_vReadEN(); byte1 = (CAN_DATA2 & 0xFC) >> 2; // MOARn[23-16] byte2 = (CAN_DATA3 & 0x1f); // MOARn[31-24] Dies funktioniert nur beim Message Objekt 0. Wenn ich die CAN-ID vom Message Objekt 1 oder zwei auslesen möchte, dann bekomme ich keine CAN-ID ausgelesen. Zuvor habe ich natürlich mit DAVE drei Message Objekte MO0, MO1 und MO2 angelegt. Bei allen ist das AMR Register auf 0x000 eingestellt. Hiermit kann ich die ID auslesen. Ich hab schwierigkeiten mit folgendem Vorgehen: - alle CAN-ID's abfragen - wenn entsprechende CAN-ID eingetroffen ist, dann lege eine Message Objekt an (ID, DLC, DATEN)
Wie soll ich das verstehen? Du hast 3 MOs, die alle jede Nachricht akzeptieren (Maske 0x000)? Das kann nicht funktionieren. Wieso sollte einmal eine Nachricht in MO0 und das nächste mal in MO1 abgelegt werden. Also wie man eine MO anlegt, das kannst du dir vom DAvE abschauen. Wie man die ID aus einem MO ausliest, weißt du jetzt auch - wo ist also das Problem?
Was würdest du mir vorschlagen? Ziel ist ja zuerst will ich allgemein prüfen ob Nachricht da ist. Wenn ja ID lesen und dementsprechend ein Message Objekt anlegen und die empfangenen Daten in dem erzeugten Message Objekt speichern. Wahrscheinlich sollte ich mit DAVE nur MO0 anlegen. Mit diesem kann ich dann die ID ermitteln. Je nachdem möchte ich auch ein angelegtes Message Objekt wieder löschen. Bit 11 bis Bit 8 = Nummer vom BOARD Bit 7 bis Bit 0 = Message Objekt Nummer Ich kann ja Daten senden und empfangen, nur tue ich mich mit dem Handling etwas schwer.Für jeden Rat oder Tip bin ich sehr dankbar.
Was würdest du mir vorschlagen? Ziel ist ja zuerst will ich allgemein prüfen ob Nachricht da ist. Wenn ja ID lesen und dementsprechend ein Message Objekt anlegen und die empfangenen Daten in dem erzeugten Message Objekt speichern. Wahrscheinlich sollte ich mit DAVE nur MO0 anlegen. Mit diesem kann ich dann die ID ermitteln. Je nachdem möchte ich auch ein angelegtes Message Objekt wieder löschen. Bit 11 bis Bit 8 = Nummer vom BOARD Bit 7 bis Bit 0 = Message Objekt Nummer Ich kann ja Daten senden und empfangen, nur tue ich mich mit dem Handling etwas schwer.Für jeden Rat oder Tip bin ich sehr dankbar.
Also das mit dem AMR Register ist mir noch immer noch ganz klar. AMR Register = 0x000 --> alle Nachrichten werden empfangen AMR Register = 0x7FF , ID = 0x002 --> nur Nachricht mit ID 0x002 wird empfangen Was passiert da genau bei der Filterung? Wird das AMR Register mit der CAN-ID irgendwie logisch verknüpft ? Der XC888 besitzt ja kein Acceptance Code Register (ACR), im Gegensatz zu dem SJA1000. Hier handelt es sich um einen FULL CAN. Warum entfällt hier das ACR Register? Mit einem CAN Dongle, der am PC angeschlossen wird, möchte ich die Boards mit dem XC888 über CAN ansteuern. Der CAN Dongle soll der Master sein und die XC888 Boards die Slaves. Das scheint wohl nicht so das große Problem zu sein, wie wenn ich jetzt direkt vom Slave 1 an den Slave 2 Daten senden buw. empfangen möchte. Wie könnte ich dies umsetzen?
Also das mit dem AMR Register ist mir noch immer noch ganz klar. AMR Register = 0x000 --> alle Nachrichten werden empfangen AMR Register = 0x7FF , ID = 0x002 --> nur Nachricht mit ID 0x002 wird empfangen Was passiert da genau bei der Filterung? Wird das AMR Register mit der CAN-ID irgendwie logisch verknüpft ? Der XC888 besitzt ja kein Acceptance Code Register (ACR), im Gegensatz zu dem SJA1000. Hier handelt es sich um einen FULL CAN. Warum entfällt hier das ACR Register? Mit einem CAN Dongle, der am PC angeschlossen wird, möchte ich die Boards mit dem XC888 über CAN ansteuern. Der CAN Dongle soll der Master sein und die XC888 Boards die Slaves. Das scheint wohl nicht so das große Problem zu sein, wie wenn ich jetzt direkt vom Slave 1 an den Slave 2 Daten senden buw. empfangen möchte. Wie könnte ich dies umsetzen?
Ich habe noch folgendes Problem mit dem XC888. In einer Interruptroutone wird immer das Message Objekt 0 ausgelesen. Wenn ich jetzt keine CAN Nachricht vom CAN Dongle auf den CANBUS versende, enthält das Message Objekt 0 noch die letzten Daten. Wie kann man nun den XC888 dazu veranlassen, dass nachdem die Daten vom Message Objekt 0 abgeholt wurden, zu löschen? Es gibt zwar noch die Funktionen: ReleaseMsg RequestMsg DelMsg usw. Ich weiss nicht genau was diese Funktionen machen.
Hallo! Hier im Bericht ist mehrmals die Rede von der shared_int.c-Datei von DAVE. Wie bekomme ich diese Datei und wofür ist sie? Ich versuche gerade einen XC886 zu programmieren. In einem Beispielcode steht, dass ich etwas in die shared_int.c Datei schreiben soll, aber sie wird mir nicht von Dave erzeugt. Was mache ich falsch?! Vielen Dank schon einmal!
Die wird vom DAvE automatisch erzeugt wenn alle notwendigen Einstellungen für die Interruptfähigkeit der Peripherie eingestellt sind. Nicht alles Interrupts arbeiten mit diesem shared_int.
Ich habe das Forum zum XC888 und CAN verfolgt. Carsten hatte immer gleich Beispiele. Ich besitze auch die Evalboards zum XC888. Ich würde gern Daten austauschen über NODE1. Zum senden von 8byte würde ich die Transmitfunktion verwenden und zum Empfang das Interrupt. Der Austausch erfolgt über 2 Boards. Für die Hilfe wäre ich dankbar.
http://www.infineon.com/cms/en/product/channel.html?channel=ff80808112ab681d0112ab6b83b1086b&tab=2 hier gibts ein "getting started" zum MultiCAN. Wenn du 8Bytes übertragen willst, dann musst du nur dein MO auf 8Bytes definieren (und nicht wie im Beispiel 1 Byte) Carsten
Hallo, ich und ein freund machen eine Projektarbeit mit dem XC888CLM µC von Infenion. Natürlich mit dem Can bus. Leider kommen wir im moment nicht wirklich weiter. Ich war sehr froh diesen thread hier zu finden und dachte mit mit dem beispielprogramm erste erfahrungen zu sammeln. Das von Carsten gepostete XC800_CAN_DEMO.zip lässt sich zwar öffnen und compilieren, wenn ich es aber auf den µC laden möchte (mit einem Keil Ulink2) bekomme ich folgende fehlermeldung: http://img207.imageshack.us/my.php?image=fehlermeldungvx5.jpg Wir haben ein lauffähiges Projekt von unserem Vorgänger, aber da blicke ich überhaupt nicht mehr durch, es funktioniert aber (also das auf den µ Controller laden)
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.