Forum: Mikrocontroller und Digitale Elektronik LPC11C14 CAN mit ROM API


von Alram L. (alram)



Lesenswert?

Hallo,

Ich habe eine selbst entworfene Platine mit einem LPC11C14 & SN65HVD234 
als CAN Tranceiver drauf. Der LPC11C14 sollte nun ein wenig CAN 
Kommunikation mit einem "Master" betreiben (das ist ein LPC1768 - sollte 
aber gerade eher nicht von Interesse sein).

Aktuell versuche ich einfach nur den LPC11C14 so weit zu bekommen, dass 
er eine CAN Message nach dem Booten sendet (unter Verwendung des ROM 
API). Daran scheitere ich und hab nun schon Stunden verbracht, ohne zu 
einem Ergebnis zu kommen.

Den Code hab im wesentlichen aus dem NXP LPCWare Sample entnommen. Und 
auch mit den Samples die man im Internet findet verglichen - ich finde 
keinen relevanten Unterschiede.

Das Problem:
Der LPC11C14 sendet das gewünschte CAN Telegramm die ersten 16x mit 
scheinbar sehr kurzen Zeitabständen auf den Bus. Der LPC1768 quittiert 
diese dann mit dem nicht sonderlich gut dokumentierten Fehler 
"Acknowledge Delimiter". Ab dem 16. Frame macht der LPC11C14 dann 
längere Pausen zwischen den Frames und der LPC1768 Empfängt die 
Nachricht ganz normal und sendet auch das erwartete ACK auf den Bus.
ABER: der LPC11C14 hört nicht auf, die Nachricht auf den Bus zu senden. 
Der sendet die gleiche Nachricht permanent ohne Pause auf den Bus.
Das besonders schräge daran: die CAN-ISR am LPC11C14 wird genau 1x 
aufgerufen und meldet dabei den Fehler "Missing ACK" (ISR Auruf ist der 
Ch2 Ausschlag jeweils am 2ms Oszi Bild). Die Oszi Bilder sind Aufnahmen 
direkt vom CAN Bus, einmal mit dem "Master" (LPC1768) angeschlossen und 
einmal ohne (der LPC11C14 ist alleine am Bus).

Ich habe schon viele Varianten ausprobiert - alles ohne Erfolg. Unter 
anderem:
- mit ISR/mit Polling
- CPU Takt variiert (10/20/30/40/50 MHz)
- Alles aus dem Projekt entfernt, was ich für den Zweck nicht benötige 
(FreeRtos, etc.)

Den RAM Bereich, der vom ROM Treiber API verwendet wird, hab ich in den 
Linker settings ausgenommen.

Der Saleae Logic Analyzer zeigt mir (hinter dem Tranceiver am LPC1768 
und auch am LPC11C14) auch keinerlei Fehler. Er erkennt die CAN Frames 
(Identifier, Daten, CRC) mit jeweils dem fehlerhaften und passendem ACK. 
Daraus würde ich einmal schliessen, dass die Tranceiver OK sind.

Der Code (die Standarddinge wie SystemCoreClockUpdate und Board_Init 
lass ich mal aussen vor):
1
void CAN_IRQHandler(void) {
2
  Board_PIN_Set(BOARD_PIN_RESERVED_B1, true); // am Oszi ch2
3
  DEBUGSTR("I+");
4
  LPC_CCAN_API->isr();
5
  DEBUGSTR("-\n");
6
  Board_PIN_Set(BOARD_PIN_RESERVED_B1, false);
7
}
8
9
void CAN_Init() {
10
  cntRx = cntTx = msgObjBusy = 0;
11
12
  uint32_t CanApiClkInitTable[2];
13
  Board_PIN_Set(BOARD_PIN_CAN_TRANCEIVER_ENABLED, true);
14
  Chip_Clock_EnablePeriphClock(SYSCTL_CLOCK_CAN);
15
  baudrateCalculate(CAN_BAUDRATE, CanApiClkInitTable);
16
  LPC_CCAN_API->init_can(&CanApiClkInitTable[0], true);
17
  LPC_CCAN_API->config_canopen((CCAN_CANOPENCFG_T*) &canOpenConfig);
18
19
  callbacks.CAN_rx = callback_CAN_rx;
20
  callbacks.CAN_tx = callback_CAN_tx;
21
  callbacks.CAN_error = callback_CAN_error;
22
  callbacks.CANOPEN_sdo_read = callback_sdo_read;
23
  callbacks.CANOPEN_sdo_req = callback_sdo_req;
24
  callbacks.CANOPEN_sdo_seg_read = callback_sdo_seg_read;
25
  callbacks.CANOPEN_sdo_seg_write = callback_sdo_seg_write;
26
  callbacks.CANOPEN_sdo_write = callback_sdo_write;
27
  LPC_CCAN_API->config_calb(&callbacks);
28
29
  NVIC_EnableIRQ(CAN_IRQn);
30
}
31
32
void sendBootUpMessage(void) {
33
  static CCAN_MSG_OBJ_T msg_obj;
34
  msg_obj.msgobj = MSGBUFFER_NMT;
35
  msg_obj->mode_id = CAN_MSGOBJ_STD | CAN_MSGOBJ_DAT | (0x700 + NODE_ID);
36
  msg_obj->mask = 0x0;
37
  msg_obj.dlc = 3;
38
  msg_obj.data[0] = 0x05;
39
  msg_obj.data[1] = 0xff;
40
  msg_obj.data[2] = 0x45;
41
  LPC_CCAN_API->can_transmit(&msg_obj);
42
}
43
44
int main(void)
45
{
46
  SystemCoreClockUpdate();
47
  Board_Init();
48
  DEBUGSTR("\033[2J\033[H");
49
  DEBUGSTR("*** CAN Node ***\n");
50
51
  CAN_Init();
52
  Board_PIN_Set(BOARD_LED_CAN_ACTIVITY, false);
53
  Board_PIN_Set(BOARD_LED_CAN_ERROR, false);
54
  sendBootUpMessage();
55
  while(true) {
56
    LPC_CCAN_API->canopen_handler();
57
    Board_PIN_Set(BOARD_LED_CAN_ACTIVITY, false);
58
    Board_PIN_Set(BOARD_LED_CAN_ERROR, false);
59
  }
60
  return 1;
61
}

Irgendeine Idee, was hier schief läuft? Ich bin so weit, dass ich schon 
die Hardware im Verdacht habe ... aber meine bisherige Erfahrung hat 
gezeigt, dass es so gut wie nie die Hardware ist ...

Danke für eure Hilfe!
vG Alram

von Harald (Gast)


Lesenswert?

Ich habe mich jetzt nicht tief in dein Projekt eingearbeitet, aber eine 
andauernde Wiederholung einer Message liegt ja meist an einem fehlenden 
Acknowledge. Sicher, dass der andere LPC richtig quittiert? Falls nein, 
lässt der Filter die Botschaft zu? Ein parallel am Bus hängender 
CAN-Dongle kann hilfreich sein, in Standardmodus werden einfach alle 
Botschaften quittiert. Natürlich kann man auch da Filter einsetzen oder 
einen Listen-Only Modus aktivieren.
Ansonsten empfand ich den LPC11Cx4 mit der ROM-API ohne Probleme in 
Betrieb zu nehmen.

von Jim M. (turboj)


Lesenswert?

Der LPC11C14 ist die Variante mit externem Tranceiver - checke mal ob 
CAN_RXD korrekt verbunden ist.

von Alram L. (alram)


Lesenswert?

Hi,

Danke für eure Hilfe - lese sie erst jetzt. Gestern Abend hab ich mich 
noch einmal dem Problem angenommen. Anfänglich bin ich etwas verzweifelt 
- dann bin ich langsam dahinter gekommen, dass nicht meine 
Codeänderungen wirklich etwas am Problem verändern, sondern die Stellen 
an denen ich Oszi bzw. Salea angeschlossen habe. Irgendwann hatte ich 
die glorreiche Idee, die Versorgungsspannung vom Tranceiver mit dem Oszi 
zu beobachten um dann festzustellen, dass ich im PCB Layout übersehen 
habe den CAN Tranceiver GND Pin auch tatsächlich mit GND zu verbinden 
... (ist jetzt fast ein wenig peinlich, wie lange ich gebraucht habe um 
das herauszufinden).
Nach dem die Verbindung hergestellt war, funktionierte alles gleich 
perfekt.
Interessant finde ich, wie gut der CAN Tranceiver eigentlich ohne GND 
funktioniert hat. Ich hätte erwartet, dass auf der CAN high/low seite 
einfach nichts passiert. Oder der CAN Controller gleich ein "bus 
offline" erkennt, wie es passiert, wenn der Tranceiver Enable PIN nicht 
aktiv ist. Senden hat aber an sich recht gut funktioniert - empfangen 
fast gar nicht. Und je nach dem wo mal der Tastkopf drann war, hats dann 
halt besser oder schlechter funktioniert.

Danke jedenfalls & schönen Abend!
Alram

von Harald (Gast)


Lesenswert?

Danke für die Rückmeldung, ist nicht selbstverständlich. Ein ganz 
normaler Fehler, der Dir bestimmt nicht peinlich sein muss. Parasitäre 
Versorgung und dadurch hervorgerufene Effekte können interessante 
Auswüchse hervorrufen.

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.