Forum: Mikrocontroller und Digitale Elektronik MCP2515: Listen-only geht, normal geht nicht


von Sven P. (Gast)


Lesenswert?

He,

ein Problem mit dem CAN-Controller MC2515:
. saubere Platine,
. 8MHz-Quarz am Controller selbst,
. MC2551 als Buswandler.

Das Bit-Timing war elendige Pfriemelei; um mit dem 8MHz-Quarz auf 
100kbps zu kommen, habe ich mir folgende Einstellungen überlegt:
. 8MHz sind Tosc=125ns pro Takt,
. 100kbps sind 10us pro Bit;
. ich setze 'BRP' im Register auf 0b000010=2, das ergibt dann ein 
Zeitquantum von Tq = 2*(BRP+1)*Tosc = 1us.
. Das Synchronisationssegment ist im Chip fest auf Tsync=1*Tq=1us 
verdrahtet,
. als propagation delay wähle ich 'PRSEG' im Register als 0b001=1, das 
ergibt Tprop = (PRSEG+1)*Tq = 2us,
. Die Phasensegmente wähle ich in den jeweiligen Registern mit 
'PHSEG1'=0b011=3 und 'PHSEG2'=0b010=2. Das ergibt Tpha1=(PHSEG1+1)*Tq = 
4us und Tpha2=(PHSEG2+1)*Tq = 3us.

Zusammen sind das:
1
  Tsync             = 1us
2
  Tprop             = 2us
3
  Tpha1             = 4us
4
  Tpha2             = 3us
5
                    ------
6
                     10us

Der Samplezeitpunkt liegt nach Tpha1 und vor Tpha2, also liegen 7us vor 
und 3us nach dem Sampling. Ergibt ein Verhältnis von 70%:30%, also 
optimal. Der Sender ist ein Evaluationsboard; dieses habe ich mit dem 
CANalyzer getestet, funktioniert also.

Das Problem: Im Listen-only-Modus empfängt meine Schaltung Telegramme, 
die entsprechenden Pins am CAN-Controller wechseln ihre Zustände und so 
weiter. Die empfangenen Daten stimmen auch. Das Evaluationsboard sendet 
halt ewig die Retries weiter.
Wechsele ich nun in den normalen Modus, empfange ich nichts mehr, 
bekomme keine Interrupts und das Evaluationsboard geht nach einer Weile 
in CAN-passive, weil wohl der Fehlerzähler da vollläuft.

Ich habe meine Schaltung mal alleine senden lassen und die Bit-Zeit 
oszillographiert; da kamen exakt 10us pro Bit heraus. Sollte also 
stimmen. Interessanterweise geht das Evaluationsbort nicht in 
CAN-passive, wenn ich dem MC2515 eine falsche Bitzeit einstelle.

Ich bin verwirrt und hoffe auf Erleuchtung.

Vielen Dank und Grüße,
Sven

von cskulkw (Gast)


Lesenswert?

Hallo Sven,

im Normalbetrieb mußt Du die Filtermaske entweder deaktivieren - alle 
MSGs zulassen - oder die gewünschte Filtermaske einstellen.

Ansonsten empfängt der Controler nichts.

Für eine weitere Bewertung dazu müßte man die Registerinhalte mal sehen.

Stelle doch Deinen Initcode mal ein.

von Sven P. (Gast)


Lesenswert?

cskulkw schrieb:
> Hallo Sven,
>
> im Normalbetrieb mußt Du die Filtermaske entweder deaktivieren - alle
> MSGs zulassen - oder die gewünschte Filtermaske einstellen.
Ich habe sie gänzlich deaktiviert; die RMX1- und RMX0-Bits im RXB0CTRL 
sind gesetzt, was ja laut Datenblatt genau den gewünschten Effekt hat.

Ich habe mit dem Impulszähler einmal nachgesehen, was der Controller von 
sich gibt: Wenn ich die Bit-Timings einfach grundverkehrt einstelle, 
dann sendet der Sender (Evalboard) permanent und mein MCP2515 erzeugt 
keine Acknowledgements. Logisch, denn er kann sich ja nicht 
synchronisieren. Weil er aber eben garnichts sendet, bleibt das 
Evalboard bei den Retries.

Stelle ich die Bit-Timings korrekt an, so erzeugt der MCP2515 etwa 
tausend Acknowledgements, bevor der Bus schweigt. Empfangen tut er aber 
trotzdem nichts; die Interrupt-Flags bleiben gelöscht und im 
Empfangspuffer steht nichts.


> Stelle doch Deinen Initcode mal ein.
Ich lasse die SPI-Routinen aber weg. Die funktionieren ja offenbar, denn 
im Listen-only-Modus kann ich korrekte Daten abholen.
1
void can_prepare(void) {
2
  /* IRQ pin as input with pullup */
3
  DDRB &= ~_BV(PB1);
4
  PORTB |= _BV(PB1);
5
6
7
  /* Reset */
8
  can_command(CAN_RESET);
9
  _delay_ms(100);
10
11
12
  /* Tie BF pins */
13
  can_write_register(BFPCTRL,
14
    _BV(B1BFE) | _BV(B1BFM) | _BV(B0BFE) | _BV(B0BFM)
15
  );
16
17
  /* Disable RTS pins */
18
  can_write_register(TXRTSCTRL, 0);
19
20
21
  /* Configure baud rate to 100kbps.
22
    Given by the quartz oscillator used in the circuit:
23
      Fosc = 8 MHz -> Tosc = 125 ns
24
25
    The nominal baud rate 'NBR' of 100 kbps is also the
26
    nominal bit rate. This yields a nominal bit time of
27
      Tbit = 1/NBR = 10 us
28
29
    The bit time is divided into time quants 'Tq' by the can
30
    bus controller and the bit time is composed out of time
31
    quants as
32
      Tbit = Tsync + Tprop + Tpha1 + Tpha2
33
    where
34
      . Tsync is fixed to 1*Tq for synchronization to the bus,
35
      . Tprop is the physical propagation delay on the bus,
36
      . Tpha1 and Tpha2 divide the remaining bit time into
37
        two phase segments. The bit is sampled between these
38
        phase segments.
39
40
    The time quant must be choosen short enough to allow for
41
    a sensible choice of the propagation sement Tprop and large
42
    enough to be able to divide the total bit time at a ratio
43
    of about 60..70% : 40..30%.
44
45
    The time quant is determined by a prescaler 'BRP'.
46
      Tq = 2*(BRP+1) * Tosc
47
    Choosing 'BRP' = 2 yields Tq = 1 us.
48
49
    The propagation delay is programmed by 'PRSEG' as
50
      Tprop = (PRSEG+1) * Tq
51
    and 'PRSEG' = 1 gives a propagation delay of 2 us, which
52
    is enough for a tiny bus.
53
54
    After Tsync and Tprop, there are 6 time quants left.
55
    Splitting the total bit time at a ratio of 70% : 30% makes
56
    7 time quants before and 3 after the sampling point. As
57
    3 time quants have already been used up by synchronization
58
    and propagation, there are 4 time quants left for the first
59
    phase segment and another 3 for the second one.
60
      Tpha1 = (PHSEG1+1) * Tq
61
      Tpha2 = (PHSEG2+1) * Tq
62
    Choosing 'PHSEG1' = 3 yields Tpha1 = 4 us and choosing
63
    'PHSEG2' = 2 yields Tpha2 = 3 us.
64
65
    Summarizing:
66
      Tq = 1 us
67
      Tbit =  Tsync + Tprop + Tpha1 + Tpha2
68
           = (  1   +   2   +   4   +   3  ) * Tq = 10 us
69
                                    ^
70
                             sampling point
71
  */
72
  can_write_register(CNF1,
73
    _BV(SJW0) |
74
    _BV(BRP1) | _BV(BRP0) /* 'BRP' = 3 */
75
  );
76
  can_write_register(CNF2,
77
    _BV(SAM) |
78
    _BV(BTLMODE) |
79
    _BV(PHSEG11) | _BV(PHSEG10) | /* 'PHSEG1' = 3 */
80
    _BV(PRSEG0) /* 'PRSEG' = 1 */
81
  );
82
  can_write_register(CNF3,
83
    _BV(PHSEG21) /* 'PHSEG2' = 2 */
84
  );
85
86
87
88
  /* Interrupts on reception into any of the two RX buffers and on
89
  completing transmission of any of the three TX buffers. */
90
  can_write_register(CANINTE,
91
    _BV(RX1IE) | _BV(RX0IE) |
92
    _BV(TX2IE) | _BV(TX1IE) | _BV(TX0IE)
93
  );
94
95
96
  /* Accept anything in first buffer */
97
  can_write_register(RXB0CTRL, _BV(RXM1) | _BV(RXM0));
98
99
100
101
  /* Leave configuration mode and speed up clock output. */
102
  can_write_register(CANCTRL, _BV(CLKEN));
103
}

von Sven P. (Gast)


Lesenswert?

Nach Messung kann ich auch den Quarz als Fehlerquelle ausschließen. Die 
8 MHz sind in jedem Fall exakt genug getroffen und jittern praktisch 
nicht.

von Sven P. (Gast)


Lesenswert?

Weiter probiert: Im Loop-Back-Modus funktioniert es auch, der MCP2515 
empfängt seine eigene Nachricht und meldet das an den 
Interrupt-Leitungen.

Nachdem die Kommunikation im Normal-Modus abbricht steht 129 im 
Fehlerzähler 'REC' des MCP2515, da hat er sich dann wohl abgeschaltet.

von Sven P. (Gast)


Lesenswert?

Weiter gemessen. Es scheint am Transceiver MCP2551 gelegen zu haben.

Die Flankensteilheit auf der CAN-Seite des Transceivers lässt sich über 
einen kleinen Strom durch einen externen Widerstand programmieren. Den 
Pin habe ich sträflicherweise offen gelassen. Was auch immer mich dabei 
geritten hat...

Mit entsprechendem Widerstand funktioniert es nun tadellos.

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.