Ich habe mal eine Frage wie man es anstellt wenn man einen MOB so konfiguriert das er mehrere IDs akzeptiert wie ich dann die ID später auswerte. Angenommen ich konfiguere das ganze so, dass mir ein Bereich von 3 IDs akzeptiert wird, denn empfängt der MOB das ganze und legt es in den Puffer, nun kann ich zwar den Puffer auslesen und habe meine Daten weiß aber nicht auf welche ID reagiert wurde. Da ich 6 Mobs habe könnte ich jeden einzeln auf eine bestimmte ID konfigurieren, wenn ich aber mehr als 6 ID auswerten möchte muss ich es eh per Hand machen deswegen würde es mich interessieren, wie ich an die zugehörige ID komme wenn ein ganzer ID Bereich konfiguriert ist. Hoffe ihr versteht was ich meine.
Thomas O. schrieb: > Hoffe ihr versteht was ich meine. Nein, ich weiss nicht was ein MOB ist und will mich auch gar nicht erst auf die Suche begeben. Auch der Rest ist mehr als unverständlich codiert.
Meine CAN-Kommunikation funktioniert bereits deswegen behaupte ich mal das ich verstanden habe was ein MOB macht. Er kümmert sich eben in Hardware darum bestimmte Nachrichten ID Abhangig entgegenzunehmen. Wenn ich jedem der 6 MOBs eine ID zuordne dann kann ich ja auswerten welcher MOB einen Interrupt ausgelößt hat und kenne dadurch ja die ID. Was aber wenn ich einen MOB aber auf einen ganzen Bereich ID Bereich scharf schalte, wo lese landet die empfangene ID. OK habs gefunden, die beiden Bytes für IDT werden überschrieben, werds gleich mal testen.
ich habe immer noch das Problem das ich keine 2te Nachricht empfangen kann. Nach der ersten bekomme ich das ganze nicht mehr zurückgesetzt um auf dem gleichen MOB eine neue Nachricht empfängen kann. Weiß nicht genau was in welche Reihenfolge gemacht werden muss in dieser Hinsicht werde ich aus dem Datenblatt nicht schlau. Nach dem Empfangen und Verarbeitung der Nachricht führe ich folgende Schritte durch. Vielleicht kann mir jemand eine Abfolge posten den Code dafür kann ich dann schon selber schreiben.
1 | lds temp, CANMSG ; CAN Nachricht aus Buffer löschen |
2 | clr temp |
3 | sts CANMSG, temp |
4 | |
5 | lds temp, CANSTMOB ; CAN Statusregister löschen |
6 | ldi temp, 0 |
7 | sts CANSTMOB, temp |
8 | |
9 | lds temp, CANGIT ; Interrupt Flags löschen durch 1 lt. Datenblatt |
10 | ldi temp, (1<<CANIT)|(1<<BOFFIT)|(1<<OVRTIM)|(1<<BXOK)|(1<<SERG)|(1<<CERG)|(1<<FERG)|(1<<AERG) |
11 | sts CANGIT, temp ; (1<<CANIT) =readonly |
12 | |
13 | lds temp, CANCDMOB ; CANCDMOB disable |
14 | ldi temp,(0<<CONMOB1)|(0<<CONMOB0)|(0<<RPLV)|(0<<IDE)|(0<<DLC3)|(0<<DLC2)|(0<<DLC1)|(1<<DLC0) |
15 | sts CANCDMOB, temp ; disable Mode, CAN 11bit identifier, 8bit data lenght muss vor CANGCON übermittelt werden |
16 | |
17 | ;init_CAN_Identifier_Tag: IDT und IDM neu setzen |
18 | ldi temp, 0b01101000 |
19 | sts CANIDT1, temp |
20 | ldi temp, 0b00000000 |
21 | sts CANIDT2, temp |
22 | |
23 | ;init_CAN_Identifier_Maske: |
24 | ldi temp, 0b00000000 ;Bit10-3 IDM1 |
25 | sts CANIDM1, temp |
26 | ldi temp, 0b00000000 ;Bit 2-0 IDM2 |
27 | sts CANIDM2, temp |
28 | clr temp |
29 | ;sts CANIDM3, temp ;nur für CAN 2.0B erforderlich |
30 | ;sts CANIDM4, temp |
31 | |
32 | ldi temp,(1<<CONMOB1)|(0<<CONMOB0)|(0<<RPLV)|(0<<IDE)|(0<<DLC3)|(0<<DLC2)|(0<<DLC1)|(1<<DLC0) |
33 | sts CANCDMOB, temp ; RX Mode enable, CAN 11bit identifier, 8bit data lenght muss vor CANGCON übermittelt werden |
34 | ldi temp,(0<<CONMOB1)|(0<<CONMOB0)|(0<<RPLV)|(0<<IDE)|(0<<DLC3)|(0<<DLC2)|(0<<DLC1)|(1<<DLC0) |
Vielleicht hilft das: http://www.avrfreaks.net/forum/tut-using-8-bit-avr-controller-area-network-can-register
Der Betreff ist etwas seltsam, ohne MoB geht da gar nichts. Das Thema hatten wir doch vor ein paar Wochen schon? Die ID der empfangenen Botschaft landet im CANIDT Register der jeweiligen Message-Box.
ok der Betreff war nicht ganz zutreffend. Es ging mir darum das ich anstatt 6 IDs auszuwerten mehr IDs oder sogar alle auswerten möchte, das kann ich ja mit der Maskierung erreichen. Allerdings ist mein Problem das nach der ersten empfangenen Nachricht Schluß ist, da ich das ganze nicht korrekt zurücksetzen kann. Einmal frage ich mich wie dieser read-modify-write Prozess genau ablaufen muss. Muss man den CAN-Controller erst in den Standbysetzen usw... ich finde nirgend einen genauen ablauf, da ist das Datenblatt irgendwie zu grob so das ich den Fehler nicht finden kann. Der AVRFreaks Link sieht vielversprechend aus werde das mal durchgehen.
Öh, man muss einfach nur CANIDT lesen wenn eine Message-Box signalisiert das sie eine Botschaft empfangen hat. Da steht dann drin welche das genau war.
es ging nicht darum festzustellen welcher MOB die Nachricht empfangen zu hat sondern diesen wieder für die nächste Nachricht freizugeben.
Rudolph R. schrieb: > man muss einfach nur CANIDT lesen wenn eine Message-Box signalisiert > das sie eine Botschaft empfangen hat. Es geht wohl darum dass ein RX-MOB nach dem vollständigem Empfang einer Botschaft erst mal für weitere Botschaften gesperrt ist. Das MOB muss erst wieder freigegeben werden. So aus dem Kopf: CANIDT1 bis 4 löschen CANCDMOB neu beschreiben CANSTMOB löschen Nachtrag: Da die obigen alle MOB-Register sind muss man vorher das CANPAGE-Register auf das richtige MOB setzten.
Ah okay. Ich kann das gerade nicht testen und habe auch gerade keinen Code zur Hand bei dem ich das erfolgreich mit dem Filter auf mehr als eine Botschaft programmiert habe. Mal schauen, ob ich da heute Nachmittag mal dran komme. Zum wieder frei geben muss normalerweise RXOK im CANSTMOB gelöscht und CANCDMOB neu geschrieben werden. Wenn die Message-Box darauf konfiguriert ist überhaupt nur eine Botschaft anzunehmen ist das völlig ausreichend. Wobei CANCDMOB als letzte Aktion neu beschrieben wird. Mit mehreren Botschaften muss man wohl CANIDT neu schreiben oder zumindest einen Teil davon, weil das beim Empfang ja durch den erhaltetenen Wert überschrieben wird.
Rudolph R. schrieb: > Mit mehreren Botschaften muss man wohl CANIDT neu schreiben oder > zumindest einen Teil davon, weil das beim Empfang ja durch den > erhaltetenen Wert überschrieben wird. Nope, das hatte ich falsch in Erinerung, man braucht das nicht. Hier mal eine gekürzte Interrupt-Funktion in C mit der ich auf zwei MOBs jeweils vier Identifier empfangen habe:
1 | ISR (CAN_INT_vect) |
2 | { |
3 | uint8_t canpage; |
4 | |
5 | canpage = CANPAGE; // save canpage |
6 | |
7 | if(CANSIT2 & (1<<SIT1)) // MOB1 |
8 | { |
9 | CANPAGE = (1<<4); // select MOB1 |
10 | CANSTMOB &= ~(1<<RXOK); // clear interrupt flag |
11 | |
12 | switch(CANIDT2 & 0xe0) // IDT0, IDT1, IDT2 at bit-position 5, 6, 7 |
13 | { |
14 | case 0xe0: // ID = 0x62f |
15 | ...Botschaft lesen |
16 | break; |
17 | case 0x60: // ID = 0x62b |
18 | ... |
19 | break; |
20 | case 0xa0: // ID = 0x62d |
21 | ... |
22 | break; |
23 | case 0xc0: // ID = 0x62e |
24 | ... |
25 | break; |
26 | default: |
27 | break; |
28 | } |
29 | |
30 | CANCDMOB = (1<<CONMOB1) | (1<<DLC3); // set to receive, 8 bytes in message |
31 | } |
32 | |
33 | if(CANSIT2 & (1<<SIT2)) // MOB2 |
34 | { |
35 | ... |
36 | } |
37 | |
38 | CANPAGE = canpage; // restore canpage |
39 | } |
Die Bits die sich im CANIDT Register verändern sind ja durch die Maske vorher auf nicht beachten gestellt worden.
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.