Forum: Mikrocontroller und Digitale Elektronik ATMega16M1 empfangene ID auswerten ohne MOB?


von Thomas (kosmos)


Lesenswert?

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.

von Nixversteher (Gast)


Lesenswert?

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.

von Thomas (kosmos)


Lesenswert?

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.

von Thomas (kosmos)


Lesenswert?

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)

von Thomas F. (igel)


Lesenswert?


von Rudolph R. (rudolph)


Lesenswert?

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.

von Thomas (kosmos)


Lesenswert?

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.

von Rudolph R. (rudolph)


Lesenswert?

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

von Thomas (kosmos)


Lesenswert?

es ging nicht darum festzustellen welcher MOB die Nachricht empfangen zu 
hat sondern diesen wieder für die nächste Nachricht freizugeben.

von Thomas F. (igel)


Lesenswert?

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.

von Rudolph R. (rudolph)


Lesenswert?

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.

von Rudolph (Gast)


Lesenswert?

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
Noch kein Account? Hier anmelden.