Problem mit CAN Interface MCP2515/2551

OP #2162043
Lesenswert?

Hallo zusammen!

Ich habe mir ein CAN Bus Interface mit den Chips MCP2515 und MCP2551 
gebaut. Dieses Interface spreche ich mit einem Arduino Mega 2560 Board 
über SPI an, dazu ist es mit den Anschlüssen CS, SCK, MOSI und MISO 
verbunden. Der Anschluß "Mode" geht auch zu einem Pin auf dem Arduino 
Board, spielt aber jetzt noch keine Rolle. Die +5V Versorgung kommt auch 
vom Board.

Zu Beginn des Programms auf dem Arduino sende ich einen Reset Befehl an 
den MCP2515. Allerdings bleibt dieser scheinbar immer im "Normal Mode" 
und wechselt nicht in den "Configuration Mode", daher scheiter ich an 
dieser Stelle schon: beim Auslesen des CANSTAT Registers stehen die 
OPMOD Bits immer auf 000, egal was ich tue. Das gleiche gilt, wenn ich 
statt des Reset Befehls die REQOP Bits im CANCTRL Register manuell 
setze.

Ich möchte erst mal ausschließen, dass mit der Schaltung irgendwas nicht 
stimmt, ob ich da irgendwas übersehen habe oder ob die Werte vielleicht 
nicht stimmen. Könnte da jemand mal drüber schauen?

Bitte nicht erschlagen, falls ich nicht exakt die richtigen Symbole oder 
so im Schaltplan verwendet habe. Das ist der erste Schaltplan, den ich 
mit Eagle erstellt habe...

Ich hoffe ich hab alles richtig erklärt, ist alles noch Neuland für 
mich.

Kann mir einer helfen?
Angehängte Dateien:
OP #2162154
Lesenswert?

Ok, ich dachte mir, man könnte erst mal so erkennen, ob es ein 
grundlegendes Problem mit der Schaltung gibt.
Hier ist dann auch noch der Code, steht aber noch nicht viel drin:

Wie gesagt, jedesmal, wenn ich canStatus ausgebe, bekomme ich "0" raus.

1
#include <SPI.h>
2

3
const byte READ = 0x03;
4
const byte WRITE = 0x02;
5
const byte RESET = 0xC0;
6
const byte CANSTAT = 0x0E;
7
const byte CANCTRL = 0x0F;
8
const int MISO = 50;
9
const int MOSI = 51;
10
const int SCK = 52;
11
const int SLAVESELECT = 53;
12
const int modePin = 49;
13
byte canStatus;
14
int i;
15
int counter;
16

17
void setup()
18
{
19
  Serial.begin(9600);
20
  Serial.println("--- START SETUP ---");
21
  SPI.begin();
22
  delay(100);
23
  Serial.println("--- SETUP FINISHED ---");
24
}
25

26
void loop()
27
{
28
  Serial.print("--- START LOOP --- ");
29
  Serial.println(counter, DEC);
30
  
31
  Serial.println("Reading MCP2515 status:");
32
  digitalWrite(SLAVESELECT, LOW);
33
  SPI.transfer(READ);
34
  SPI.transfer(CANSTAT);
35
  canStatus = SPI.transfer(0);
36
  digitalWrite(SLAVESELECT, HIGH);
37
  
38
  Serial.print("MCP2515 Status: ");
39
  Serial.println(canStatus, BIN);
40
  
41
  Serial.println("Trying to reset MCP2515");
42
  digitalWrite(SLAVESELECT, LOW);
43
  SPI.transfer(RESET);
44
  digitalWrite(SLAVESELECT, HIGH);
45
  delay(200);
46
  
47
  Serial.println("Reading MCP2515 status:");
48
  digitalWrite(SLAVESELECT, LOW);
49
  SPI.transfer(READ);
50
  SPI.transfer(CANSTAT);
51
  canStatus = SPI.transfer(0);
52
  digitalWrite(SLAVESELECT, HIGH);
53
  
54
  Serial.print("MCP2515 Status: ");
55
  Serial.println(canStatus, BIN);
56
  
57
  Serial.println("Setting to configuration mode");
58
  digitalWrite(SLAVESELECT,LOW);
59
  SPI.transfer(WRITE); 
60
  SPI.transfer(CANCTRL);
61
  SPI.transfer(0b10000000);
62
  digitalWrite(SLAVESELECT,HIGH);
63
  delay(200);
64
  
65
  Serial.println("Reading MCP2515 status:");
66
  digitalWrite(SLAVESELECT, LOW);
67
  SPI.transfer(READ);
68
  SPI.transfer(CANSTAT);
69
  canStatus = SPI.transfer(0xFF);
70
  digitalWrite(SLAVESELECT, HIGH);
71
  
72
  Serial.print("MCP2515 Status: ");
73
  Serial.println(canStatus, BIN);
74
  
75
  Serial.println("Setting to listen only mode");
76
  digitalWrite(SLAVESELECT,LOW);
77
  SPI.transfer(WRITE); 
78
  SPI.transfer(CANCTRL);
79
  SPI.transfer(0b01100000);
80
  digitalWrite(SLAVESELECT,HIGH);
81
  delay(200);
82
  
83
  Serial.println("Reading MCP2515 status:");
84
  digitalWrite(SLAVESELECT, LOW);
85
  SPI.transfer(READ);
86
  SPI.transfer(CANSTAT);
87
  canStatus = SPI.transfer(0xFF);
88
  digitalWrite(SLAVESELECT, HIGH);
89
  
90
  Serial.print("MCP2515 Status: ");
91
  Serial.println(canStatus, BIN);
92
  
93
  Serial.println("Setting to normal mode");
94
  digitalWrite(SLAVESELECT,LOW);
95
  SPI.transfer(WRITE); 
96
  SPI.transfer(CANCTRL);
97
  SPI.transfer(0b00000000);
98
  digitalWrite(SLAVESELECT,HIGH);
99
  delay(200);
100
  
101
  Serial.println("Reading MCP2515 status:");
102
  digitalWrite(SLAVESELECT, LOW);
103
  SPI.transfer(READ);
104
  SPI.transfer(CANSTAT);
105
  canStatus = SPI.transfer(0xFF);
106
  digitalWrite(SLAVESELECT, HIGH);
107
  
108
  Serial.print("MCP2515 Status: ");
109
  Serial.println(canStatus, BIN);
110
  
111
  Serial.println("--- LOOP FINISHED ---");
112
  counter = counter + 1;
113
  delay(1000);
114
}
#2162163
Lesenswert?

Hm, mit der Software kann ich erstmal nicht viel anfangen...
Zur Hardware:
sieht richtig aus, bis auf den Int-Ausgang, den solltest du auf jeden 
Fall noch zum Controller häkeln. Kann mir nicht vorstellen, wie du 
sinnvoll ohne Interrupt arbeiten kannst (hat aber nichts mit deinen 
momentanen Problemen zu tun)
Kontrollier als erstes mal mit einem Scope den clkout-Pin, nach reset 
müssen dort 1MHz anliegen.
OP #2162271
Lesenswert?

H.joachim Seifert schrieb:
> Kontrollier als erstes mal mit einem Scope den clkout-Pin, nach reset
> müssen dort 1MHz anliegen.

Gut, das werde ich heute Abend mal versuchen. Gott sei Dank hab ich ja 
noch das Osziloskop von meinem Vater zu Hause :-)

Noch ne Sache: Während meinen letzten Tests war an den CANH und CANL 
Leitungen vom MCP2551 nichts angeschlossen. Ich dachte mir, das brauch 
ich nicht unbedingt, um den MCP2515 zum laufen zu bringen. Ist das 
richtig?
OP #2163047
Lesenswert?

H.joachim Seifert schrieb:
> Kontrollier als erstes mal mit einem Scope den clkout-Pin, nach reset
> müssen dort 1MHz anliegen.

Also ich hab mal gemessen. Am clkout Pin liegt keine Frequenz an, der 
Pin ist immer auf 0. Nur etwa eine halbe Sekunde (schätz ich mal) direkt 
nach dem einschalten liegt da eine Frequenz an, die ich aber leider 
nicht genauer bestimmen kann.
Was bedeutet das jetzt? Ist der Chip an sich einfach kaputt?

Thomas Forster schrieb:
> Ich habe den Reset des MCP2515 mit dem Reset des Atmega verbunden. Dazu
> die übliche R und C Resetschaltung. Das funktioniert inzwischen bei
> mehreren Platinen problemlos.

Okay, das probier ich dann einfach auch mal.
#2163378
Lesenswert?

Tobias Kohnen schrieb:
> Also ich hab mal gemessen. Am clkout Pin liegt keine Frequenz an, der
> Pin ist immer auf 0. Nur etwa eine halbe Sekunde (schätz ich mal) direkt
> nach dem einschalten liegt da eine Frequenz an, die ich aber leider
> nicht genauer bestimmen kann.
> Was bedeutet das jetzt? Ist der Chip an sich einfach kaputt?

Nö, das ist ganz gut so.
Es bedeutet wahrscheinlich, dass der Oszillator + Stromversorgung 
funktioniert und auch deine SPI-Verbindung. Durch deine Schreiberei in 
den Chip wird dann der clkout abgeschaltet. Da du das gar nicht 
beabsichtigt hast, liegt entweder eine falsche Registeradressierung vor 
oder auch nur eine falsche Initialisierung der SPI-Schnittstelle.
Hier mal eine funktionierende SPI-Init (allerdings Mega88, kann gut 
sein, dass da Unterschiede zu deinem Prozessor sind. Und ja, das könnte 
man lesbarer schreiben, aber wenn es der wizard so funktionsfähig 
erzeugt, lass ich es auch so :-)

// SPI initialization
// SPI Type: Master
// SPI Clock Rate: 2000,000 kHz
// SPI Clock Phase: Cycle Half
// SPI Clock Polarity: Low
// SPI Data Order: MSB First
SPCR=0x50;
SPSR=0x01;
OP #2167177
Lesenswert?

H.joachim Seifert schrieb:
> // SPI initialization
> // SPI Type: Master
> // SPI Clock Rate: 2000,000 kHz
> // SPI Clock Phase: Cycle Half
> // SPI Clock Polarity: Low
> // SPI Data Order: MSB First
> SPCR=0x50;
> SPSR=0x01;

Also, ich habe jetzt versucht die SPI Schnittstelle mit sämtlichen 
Kombinationen von Clock Rate, Clock Phase, Clock Polarity und Data Order 
zu initialisieren. Jedesmal mit dem gleichen Ergebnis, dass der MCP2515 
nicht in einen anderen Modus wechselt und ich immer 000 zurück bekomme.

Die Registeradressierung übernimmt die SPI library, die beim Arduino 
schon dabei ist, und die ist auch korrekt.

Hat jetzt noch jemand eine Idee, wo der Fehler liegen könnte?
OP #2178551
Lesenswert?

Sooooooo, ich habs geschafft!
Habe jetzt alles mögliche ausprobiert. Letztendlich habe ich ein paar 
Bauteile ausgetauscht und anders dimensioniert. Und, ja, auch den INT 
Ausgang habe ich mir noch zum Controller "gehäkelt", danke für den 
Hinweis Joachim ;-)!

Und jetzt funktioniert es tatsächlich!!! Softwareseitig lag kein Problem 
vor, das war alles von Anfang an richtig.

Vielen Dank nochmal für die Tipps und Ideen von euch!

Bis demnächst!
Angehängte Dateien:

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