Maskierung fuer CAN MSG ist falsch

Gast #2399947
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
Gast #2400830
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.
Gast #2401107
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ß
Angehängte Dateien:
#2401242
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.
Gast #2406485
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

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren