Forum: Mikrocontroller und Digitale Elektronik Großes SJA1000 Problem. Weiß nicht mehr weiter


von Christian L. (quadratqualle)


Angehängte Dateien:

Lesenswert?

Hallo,

ich hab den SJA1000 so wie auf dem Schaltplan zu sehen an den Atmega8 
angeschlossen. Ich konnte den Controller erfolgreich initialisieren. 
Sprich ich hab die Register, die ich geschrieben hab am Ende ausgelesen 
und die Werte verglichen. Außerdem ist auf dem ersten Logic Analysator 
auschnitt gut zu sehen, dass der Controller nach dem Reset die Clock am 
Clock Pin auschaltet. So wie ich es wollte. Nun mein Problem sobald ich 
eine Can Nachricht senden möchte kommt nur Mist auf dem Bus an. Ich hab 
die Nachrticht mal auf dem 3. Bild rangezoomt. Es ist einfach keine 
richtig CAN Nachricht.

Ich bin mittlerweile total am verzweifeln und weiß einfach nicht wo mein 
Fehler liegt.
Ich bin über jede Hilfe dankbar.

Gruß
Christian

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Einen CAN Empfänger hast Du aber schon dran ?

Um zu schauen ob CAN tut braucht es immer auch einen Empfänger der die 
CAN Nachricht quittiert (ACK Bit).

von Hugo (Gast)


Lesenswert?

Ohne den Source wird Dir keiner helfen können.

von crazy horse (Gast)


Lesenswert?

Ausserdem einen Transceiver-Baustein, damit der SJA auch seine eigene 
Botschaft mitlesen kann.
Hardware unvollständig, Software nicht vorhanden -> Hilfe unmöglich.

von Christian L. (quadratqualle)


Lesenswert?

Danke für die schnellen antworten.

Als Source hab ich die CAN Lib verwendet und auf SJA1000 gestellt. Hab 
da jetzt auch schon alles möglich versucht zu ändern. Brauchte alles 
kein Erfolg. Ich poste die Ausschnitt gleich mal. Als CAN Tranceiver 
nutze ich den MCP2551. Der SJA1000 bekommt seine nachricht auch über den 
RX Pin zurück. Das is auf dem 3. Bild gut zu sehen. Channel 2 ist TX und 
Channel 4 is RX.
Müsste ich nicht trotzdem eine vernünftige Nachricht sehen, auch wen 
kein Empfänger dran ist. Dann müsste doch nur das ACK Bit nicht gesetzt 
werden? Der Rest müsste ja trotzdem stimmen?

von Christian L. (quadratqualle)


Angehängte Dateien:

Lesenswert?

Entschuldigung ich hab den MCP auf dem SChaltplan total vergessen.
Also hier der Code.

Initialisierung:
1
void sja1000_write(uint8_t address, uint8_t data)
2
{
3
  // set address
4
  SET(SJA1000_ALE);
5
  PORT(SJA1000_DATA) = address;
6
  _NOP();
7
  RESET(SJA1000_ALE);
8
  
9
  // write data
10
  PORT(SJA1000_DATA) = data;
11
  RESET(SJA1000_WR);
12
  _NOP();
13
  SET(SJA1000_WR);
14
}
15
16
uint8_t sja1000_read(uint8_t address)
17
{
18
  uint8_t data;
19
  
20
  // set address
21
  SET(SJA1000_ALE);
22
  PORT(SJA1000_DATA) = address;
23
  _NOP();
24
  RESET(SJA1000_ALE);
25
  DDR(SJA1000_DATA) = 0;
26
  
27
  // read data
28
  RESET(SJA1000_RD);
29
  _NOP();
30
  data = PIN(SJA1000_DATA);
31
  SET(SJA1000_RD);
32
  DDR(SJA1000_DATA) = 0xff;
33
  
34
  return data;
35
}
36
#endif
37
38
// ----------------------------------------------------------------------------
39
// useable can-bitrates (for calculation see http://www.kvaser.com/index.htm)
40
41
prog_char _sja1000_cnf[8][2] = {
42
  // 10 kbps
43
  {  0xe7,
44
    0x4d
45
  },
46
  // 20 kbps
47
  {  0xd3,
48
    0x4d
49
  },
50
  // 50 kbps
51
  {  0xc7,
52
    0x4d
53
  },
54
  // 100 kbps
55
  {  0xc3,
56
    0x4d
57
  },
58
  // 125 kbps
59
  {  (1<<_SJW0)|(1<<_BRP1)|(1<<_BRP0),
60
    (1<<TSEG13)|(1<<TSEG12)|(1<<TSEG20)
61
  },
62
  // 250 kbps
63
  {  (1<<_SJW0)|(1<<_BRP0),
64
    (1<<TSEG13)|(1<<TSEG12)|(1<<TSEG20)
65
  },
66
  // 500 kbps
67
  {  (1<<_SJW0),
68
    (1<<TSEG13)|(1<<TSEG12)|(1<<TSEG20)
69
  },
70
  // 1 Mbps
71
  {  (1<<_SJW0),
72
    (1<<TSEG12)|(1<<TSEG20)
73
  }
74
};
75
76
// ----------------------------------------------------------------------------
77
// init sja1000-interface
78
79
bool sja1000_init(uint8_t bitrate)
80
{
81
  if (bitrate >= 8)
82
    return false;
83
  
84
  #if !SJA1000_MEMORY_MAPPED
85
    SET(SJA1000_WR);
86
    SET(SJA1000_RD);
87
    RESET(SJA1000_ALE);
88
    RESET(SJA1000_CS);
89
    
90
    SET_OUTPUT(SJA1000_WR);
91
    SET_OUTPUT(SJA1000_RD);
92
    SET_OUTPUT(SJA1000_ALE);
93
94
    SET_OUTPUT(SJA1000_CS);
95
    DDR(SJA1000_DATA) = 0xff;
96
  #endif
97
  
98
  // enter reset mode
99
  sja1000_write(MOD, (1<<RM)|(1<<AFM));
100
  
101
  // choose PeliCAN-Mode
102
  sja1000_write(CDR, (1<<CANMODE) | SJA1000_CLOCK_REGISTER);
103
  
104
  // select the bitrate configuration
105
  sja1000_write(BTR0, pgm_read_byte(&_sja1000_cnf[bitrate][0]));
106
  sja1000_write(BTR1, pgm_read_byte(&_sja1000_cnf[bitrate][1]));
107
  
108
  // filter are not practical useable, so we disable them
109
  sja1000_write(AMR0, 0xff);
110
  sja1000_write(AMR1, 0xff);
111
  sja1000_write(AMR2, 0xff);
112
  sja1000_write(AMR3, 0xff);
113
  
114
  // set output driver configuration
115
  sja1000_write(OCR, (1<<OCTP0)|(1<<OCTN0)|(1<<OCMODE1));
116
  
117
  // enable receive interrupt
118
  sja1000_write(IER, (1<<RIE));
119
  
120
  // leave reset-mode
121
  sja1000_write(MOD, (1<<AFM));
122
  
123
  return true;
124
}

Nachricht senden:
1
uint8_t sja1000_send_message(const can_t *msg)
2
{
3
  uint8_t frame_info;
4
  uint8_t address;
5
  
6
  if (!sja1000_check_free_buffer() || (msg->length > 8))
7
    return FALSE;
8
  
9
  frame_info = msg->length | ((msg->flags.rtr) ? (1<<RTR) : 0);
10
  
11
  if (msg->flags.extended)
12
  {
13
    // write frame info
14
    sja1000_write(TX_INFO, frame_info | (1<<FF));
15
    
16
    // write extended identifier
17
    sja1000_write(20, msg->id << 3);
18
    sja1000_write(19, msg->id >> 5);
19
    sja1000_write(18, msg->id >> 13);
20
    sja1000_write(17, msg->id >> 21);
21
    
22
    address = 21;
23
  }
24
  else
25
  {
26
    // write frame info
27
    sja1000_write(TX_INFO, frame_info);
28
    
29
    const uint32_t *ptr32 = &msg->id;    // used to supress a compiler warning
30
    uint16_t *ptr = (uint16_t *) ptr32;
31
    
32
    // write standard identifier
33
    sja1000_write(18, *ptr << 5);
34
    sja1000_write(17, *ptr >> 3);
35
    
36
    address = 19;
37
  }
38
  
39
  if (!msg->flags.rtr)
40
  {
41
    for (uint8_t i = 0;i < msg->length; i++) {
42
      sja1000_write(address + i, msg->data[i]);
43
    }
44
  }
45
  
46
  // send buffer
47
  sja1000_write(CMR, (1<<TR));
48
  
49
  CAN_INDICATE_TX_TRAFFIC_FUNCTION;
50
  
51
  return TRUE;
52
}

von Markus M. (Firma: EleLa - www.elela.de) (mmvisual)


Lesenswert?

Nein ohne irgend ein Empfänger sendet der CAN-Chip nicht die ganze 
Message!
Das ACK ist obligatorisch.

Auch wenn man einen zweiten SJA dran hätte und der im ListenOnly Mode 
betrieben wird, klappt das nicht.

von crazy horse (Gast)


Lesenswert?

Markus Müller schrieb:
> Nein ohne irgend ein Empfänger sendet der CAN-Chip nicht die ganze
> Message!
> Das ACK ist obligatorisch.
>
> Auch wenn man einen zweiten SJA dran hätte und der im ListenOnly Mode
> betrieben wird, klappt das nicht.

Das stimmt so nicht. Der SJA wird schon mehrfach versuchen, die message 
zu senden. Da kein ack kommt, wird er irgendwann das Senden einstellen.

von Christoph (Gast)


Lesenswert?

wobei ich meine, dass der SJA ohne Gegenstück den CAN-Bus "vollballert", 
er hört meines Wissens nach auch nicht auf mit senden auf sondern 
wiederholt so lange bis ein ACK-Bit gesetzt wird!

das kann man sehr schön am Oszi sehen!

von Christian L. (quadratqualle)


Lesenswert?

Bei mir sendet der SJA1000 die komische Nachircht nur einmal, danach 
kommt nix mehr.
Ich hab als Gegenstück jetzt einen CAN Analsyer dran gehangen. Was 
allerdings keine Besserung brauchte. Außer das dieser nach der Nachricht 
vom SJA1000 Error Frame meldet.

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.