Forum: Mikrocontroller und Digitale Elektronik Interrupt-Problem mit MCP2515


von Der Fragende (Gast)


Lesenswert?

Moin ihr wissenden :-)

Nachdem ich hier im Forum und im Internet geschaut habe und keine 
passende Antwort gefunden habe, stelle ich sie nun euch und hoffe den 
Fehler beheben zu können.

Über die CAN-Schnittstelle möchte ich dem FPGA Informationen zuschicken. 
Diese werden vom MCP2515 verarbeitet und über SPI dem Microblaze 
zugeführt. Die CAN-Schnittstelle betreibe ich mit 1Mbit/s. Die 
SPI-Schnittstelle liest den MCP2515 mit 3,75MHz aus.

Es tritt nun folgender Fehler auf. Sende ich dem MCP2515 kontinuierlich 
CAN-Nachrichten, ohne Pause, werden diese vernünftig empfangen und der 
MCP2515 reagier wie er soll. Dabei werden ca. 10 Nachrichten jeder 
15,9ms gesendet.

Schalte ich diesen Test ab und verschicke einzelne CAN-Nachrichten auf 
Tastendruck so kommt es vor das der MCP2515 seinen Interrupt nicht 
zurück setzt.

Um den Fehler auf die Spur zu kommen habe ich natürlich die 
Fehler-Interrupts eingeschaltet, diese werden aber nicht ausgelöst. Ich 
folgenden habe ich mal meine Initialisierung angehängt:
1
reset_can();
2
  //mode: configuration
3
  can_mode(0x80);
4
5
  // Die drei folgenden Settings wurden ermittelt anhand von
6
  // "Kvaser Bit Timing Calculator" mit folgenden Eingabewerten:
7
  // fclock (MCP)= 20MHz
8
  // Bit-Rate    = 1000 kBit/s
9
10
  //Konfiguartions-Mode
11
  send_can_command(CNF1, 0x00);
12
  send_can_command(CNF2, 0x92);
13
  send_can_command(CNF3, 0x02);
14
15
  // kein priorität
16
  send_can_command(TXB0CTRL, 0x00);
17
  send_can_command(TXB1CTRL, 0x00);
18
  send_can_command(TXB2CTRL, 0x00);
19
20
  // keine filterung
21
  send_can_command(RXM0SIDH, 0x00);
22
  send_can_command(RXM0SIDL, 0x00);
23
24
  send_can_command(RXM1SIDH, 0x00);
25
  send_can_command(RXM1SIDL, 0x00);
26
27
  send_can_command(RXF0SIDH, 0x00);
28
  send_can_command(RXF0SIDL, 0x00);
29
30
  send_can_command(RXF1SIDH, 0x00);
31
  send_can_command(RXF1SIDL, 0x00);
32
33
  send_can_command(RXF2SIDH, 0x00);
34
  send_can_command(RXF2SIDL, 0x00);
35
36
  send_can_command(RXF3SIDH, 0x00);
37
  send_can_command(RXF3SIDL, 0x00);
38
39
  send_can_command(RXF4SIDH, 0x00);
40
  send_can_command(RXF4SIDL, 0x00);
41
42
  send_can_command(RXF5SIDH, 0x00);
43
  send_can_command(RXF5SIDL, 0x00);
44
45
  //Receive all valid messages
46
  send_can_command(RXB0CTRL, 0x00);
47
  send_can_command(RXB1CTRL, 0x00);
48
49
  //Transmit
50
  send_can_command(TXB0SIDL, 0x00);
51
  send_can_command(TXB1SIDH, 0x00);
52
53
  // enable Interrupts nur RX*-Register
54
  send_can_command(CANINTE, 0x23);
55
  send_can_command(CANINTF, CANINTF_ALL_CLEAR);
56
57
  //normal mode + one shot mode
58
  can_mode(0x08);//08
59
60
  return TRUE

von cskulkw (Gast)


Lesenswert?

Hallo Fragender,

Deine Auslesestrategie ist mir nicht ganz klar.

Du setzt die Interrupts für den Fehlerfall und die Empfangsereignisse 
RXB0 und RXB1.

Sorgt Dein FPGA dafür, dass die Interruptflags wieder zurückgesetzt 
werden?

Stichwort: Bitmodify?

Wie liest Du die Empfangspuffer aus? Holst Du Dir mit 0x03 jedes 
Datenbyte einzeln aus den Register?

Wenn ja, würde ich Dir mal einen Blick auf das 1-Byte-Kommando Read RX 
Buffer empfehlen. 0x90, 0x92, 0x94 und 0x96.
Dabei brauchst Du nur z.w. 0x90 senden und im Anschluss 13 mal ein Null.
Dann schickt Dir der MCP2515 ab Registeradresse 0x61  zu nächst die 
empfangene ID, den DLC und die Datenbytes. Der Knüller ist, dass der MCP 
dann selbstständig das Interruptflag (inclusive Portpin) löscht.

Vielleicht hilft Dir das ja schon weiter.

Viel Erfolg

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.