Forum: Mikrocontroller und Digitale Elektronik Maskierung fuer CAN MSG ist falsch


von Stefan (Gast)


Lesenswert?

Hey Leute,

ich habe ein Problem und verstehe nicht ganz wo das problem liegt.
Mein uC (Atmega64C1) empaegngt und sendet alle CAN MSG wie erwartet, 
aber
mir ist aufgefallen, dass wenn die CAN ID sehr identisch  sind(1F1 und 
1F5 z.B.), wird ein Interrupt ausgeloest und es werden falsche daten 
reingeschrieben ins richtige MOB. Meine Vermuttung ist, dass es an der 
Maskierung liegt, jedoch ich sehe da keinen Fehler. Oder Ihr vielleicht.
1
void CAN_setIDMask(uint32_t idm)
2
{
3
   CANIDM4 = (uint8_t)(idm << 11);
4
   CANIDM2 = (uint8_t)(idm << 5); 
5
   CANIDM1 = (uint8_t)(idm >> 3);
6
}

Gruss Stefan
von crazy horse (Gast)


Lesenswert?

Stefan schrieb:
> mir ist aufgefallen, dass wenn die CAN ID sehr identisch  sind(1F1 und
> 1F5 z.B.),

find ich nicht sehr identisch. Kann überhaupt irgendwas sehr oder wenig 
identisch sein? :-)
von Stefan (Gast)


Lesenswert?

Hey,

sorry das ich es nochmal anspreche? Aber hat einer eine Idee was ich 
falsch mache?

@crazy horse
es haengt davon ab wie man identisch definiert :-)

Gruss

Stefan
von Lutz (Gast)


Lesenswert?

Stefan schrieb:
> void CAN_setIDMask(uint32_t idm)
> {
>    CANIDM4 = (uint8_t)(idm << 11);
>    CANIDM2 = (uint8_t)(idm << 5);
>    CANIDM1 = (uint8_t)(idm >> 3);
> }

Ich habe nun nicht ins Datenblatt geschaut und kenne diesen Chip auch 
nicht, aber:

Mal dir doch mal 1F1 und 1F5 binär als 32 bit Zahl auf.
Dann shifte diese 32 bit Zahl um 11 Stellen nach links.
Das Ergebnis castest du dann in eine 8 bit Zahl.

Was fällt dir dann auf?  Etwa eine Gleichheit?

Wenn du irgendeine Zahl hast, diese um 11 bits nach links shiftest und 
das Ergebnis in 8 bit castest: Es kommt immer Null raus! Schlag das 
casten noch mal im C-Buch nach.
von Hans_Dampf (Gast)


Angehängte Dateien:

Lesenswert?

CANIDM siehe Anhang (Aus dem Datenblatt des ATMEGA64C1)

Datenblatt: 
http://www.atmel.com/dyn/resources/prod_documents/doc7647.pdf

folglich sollte für CAN 2.0 Typ A

void CAN_setIDMask(uint32_t idm)
 {
    CANIDM2 = (uint8_t)(idm << 5);
    CANIDM1 = (uint8_t)(idm >> 3);
 }

und für CAN 2.0 Typ B

void CAN_setIDMask(uint32_t idm)
 {
    CANIDM4 = (uint8_t)(idm << 3);
    CANIDM3 = (uint8_t)(idm >> 5);
    CANIDM2 = (uint8_t)(idm >> 13);
    CANIDM1 = (uint8_t)(idm >> 21);
 }
richtig sein

Verwendest Du 11 oder 29 Bit Identifier?

Beachte, nach diesem Schreiben sind die Bits RTRMSK und IDEMSK gelöscht 
und müssen ggf. neu gesetzt werden!

Schönen Gruß
von Lehrmann M. (ubimbo)


Lesenswert?

Stefan schrieb:
> @crazy horse
> es haengt davon ab wie man identisch definiert :-)

Falsch.

Identität (zumindest im mathmatisch-technischen Sinne) bezeichnet eine 
absolute Gleichheit. Die Mathematik kennt für auch 2 Symbole. Das ein 
"=" bezeichnet die Gleichheit, das andere (ein "="-Zeichen mit 3 
horizontalen Strichen) bezeichnet Identität. Und das darf ich auch nur 
schreiben wenn beispielsweise x=x da steht (Identität). Steht hingegen 
x=y da (keine Identität), so darf ich das auch nicht schreiben - 
unabhängig davon ob der Zahlenwert von x gleich dem von y ist.
von Stefan (Gast)


Lesenswert?

Sorry war paar Tage unterwegs, konnte nicht Antworten und ausprobieren.

@Hans_Dampf
danke fuer die Hilfe. Ich habe es jetzt ausprobiert. Jedoch empfange ich 
immer die MSG, die ich nicht empfangen sollte. Ich sollte NUR 1F1 
empfangen, jedoch empfange ich auch 1F5 im gleichen MOB.

Ich versuche die ganze Zeit CAN MSG 11 Bit Adresse zu empfangen.

Liegt es vlt. an meiner Interrupt routine?
1
 #define SIG_CAN_INTERRUPT1    _VECTOR(18)
2
3
SIGNAL(SIG_CAN_INTERRUPT1)
4
{
5
  uint8_t mob; 
6
  uint8_t canstmob;
7
  uint8_t i=0;
8
  CAN_message message;
9
10
  mob = CAN_getMOBInterrupt();
11
   
12
  if(mob == NOMOB)
13
  {
14
    return;
15
  }
16
17
  mode  = CAN_getMode();
18
19
  CAN_selectMOB(mob);
20
    
21
  CAN_getData(message.data);
22
  
23
  message.id = CAN_getID();
24
  message.length = CAN_getLength();
25
26
  CAN_resetData();
27
28
  can_msg[mob].id=message.id;
29
  can_msg[mob].length=message.length;
30
31
  for(i=0;i<8;i++)
32
  {
33
    if(i<can_msg[mob].length)
34
    {
35
      can_msg[mob].data[i]=message.data[i];
36
    }
37
    else
38
    {
39
      can_msg[mob].data[i]=0x00;
40
    }
41
  }  
42
  
43
canstmob =  CANSTMOB;
44
  CANSTMOB =  canstmob & ~(1<<RXOK);
45
}

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