Hallo Zusammen,
ich versuche gerade via Labview mit meinem PIC18F66K80 (mit 18Mhz
externem Oszillator) und dem dazugehörigen CAN-Transceiver MCP2551 zu
kommunizieren. Ich habe eine Übertragungsgeschwindigkeit von 1Mbit/s
eingestellt. Der uC hat die Rolle eines Slave und antwortet nur auf
Befehl des Master. Das funktioniert im Sekundenbereich einwandfrei:
Messdatenanforderung an PIC -> Senden von 12 CAN-Datenframes mit je 8 X
Datenbytes an den Master -> Wieder Messdatenanforderung. Jedoch muss ich
an meinem Master eine Wartezeit von mind. 1300 ms zwischen Senden und
Empfangen einhalten, um alle 12 CAN-Datenframes zu empfangen. Je weiter
ich die Zeit reduziere, desto chaotischer und unvollständiger sind die
Daten. Ich kann sehen das mein uC-Code ca. 700us zum durchlaufen der
FOR-Schleife mit 12 Durckläufen benötigt. Die theoretische
Übertragungszeit für den CAN-Datenframe sind 126 us -> 12 x 126 = ca.
1,5 ms. Zusammen sind das, großzügig gerechnet, 3ms vom Empfang der
Nachricht bis die Daten theoretische auf dem Bus sein müssten. Ich kann
mir einfach nicht erklären woher die Differenz von den theoretischen 3
ms zu den praktischen 1300 ms kommt. Das Datenblatt des MCP hat mir die
Antwort auch nicht verraten.
Hier mein C-Code:
sprintf(lcd_line1,"ID Module = %u OK",IDmodule);//The pec_error variable is simply set negative if any PEC errors
8
Lcd_Out(1,1,lcd_line1);
9
Delay_ms(1000);
10
11
if(Rx_Data[0]==9)//CAN-Init from master
12
{
13
Lcd_Cmd(_LCD_CLEAR);// Clear display
14
Lcd_Cmd(_LCD_CURSOR_OFF);// Cursor off
15
sprintf(lcd_line1,"ID Module = %u",IDmodule);//The pec_error variable is simply set negative if any PEC errors
16
Lcd_Out(1,1,lcd_line1);
17
Lcd_Out(2,1,"CAN INIT OK");
18
19
Tx_ID=IDmaster;
20
cell_count[0]=12;//LTC1 Cellcount
21
cell_count[1]=5;//LTC2 Cellcount
22
Tx_Data[0]=IDmodule-1;
23
Tx_Data[1]=cell_count[0];
24
Tx_Data[2]=cell_count[1];
25
CANWrite(Tx_ID,Tx_Data,3,Can_Send_Flags);
26
}
27
28
if(Rx_Data[0]==10)//Data acquisation from master
29
{
30
31
for(j=0;j<12;j++)
32
{
33
Tx_ID=IDmaster;//ID receiver
34
Tx_Data[0]=0x40;//Lowbyte voltage
35
Tx_Data[1]=0x9C;//Highbyte voltage
36
Tx_Data[2]=0x45;//Lowbyte temperature
37
Tx_Data[3]=0x9C;//Highbyte temperature
38
Tx_Data[4]=0x50;//Lowbyte current
39
Tx_Data[5]=0x9C;//Highbyte current
40
Tx_Data[6]=j;//Lowbyte cell information (Cellnumber)
41
Tx_Data[7]=0x0;//Highbyte cell information (Modulenumber)
42
43
CANWrite(Tx_ID,Tx_Data,8,Can_Send_Flags);
44
Delay_ms(1);
45
PORTC=0x00;
46
}
47
48
}
49
if(Rx_Data[0]!=9&&Rx_Data[0]!=10)//Send errorcode
50
{
51
Tx_ID=IDmaster;
52
Tx_Data[0]=0xAB;
53
CANWrite(Tx_ID,Tx_Data,1,Can_Send_Flags);
54
// PORTC = 0x3;
55
// delay_ms(10000);
56
}
57
}
Ich gehe von einer korrekten Beschaltung des MCP's aus, da das
prinzipielle Kommunizieren sauber funktioniert. Jemand hier der
unterstützen kann, ich weiß echt nicht mehr weiter.
VG und DANKE!!!!
Ein paar Ideen:
- Abschlusswiderstände vorhanden? Bei 1MBit an beiden Seiten wichtig!
- Widerstand an MCP2551 für Flankensteilheit? Der MCP2551 hat recht
lasche Flanken, kann unter gewissen Umständen zum Problem führen
- Klappen niedrigere Baudraten?
- Lass Dir mal die BusWarnings/Errors mit ausgeben (Im Falle eines
Errors könnte das die lange Recovery-Zeit erklären)
- Hast Du ein Scope zur Hand? Falls nicht, kauf Dir zumindest ein
Logic-Analyzer-Clone für 8Euro und schaue mit SIGROK auf den Bus
Hallo Zusammen,
Harald danke für deine Ideen! Das sind Dinge die man als Anfänger nur
teilweise überprüft. Vor alle Danke für den Tipp mit dem
Logic-Analyzer-Clone für 8Euro! Die habe ich bis jetzt nur für teuer
Geld gesehen.
CANNOT, da war der Hund begraben. Ich habe die Zeit auf 0 gesetzt und
jetzt kann ich alle 30 ms Werte abfragen, das hilft erstmal. Super!
Manchmal sieht man den Wald vor Bäumen nicht mehr...
VG André
Freut mich. Das delay nach dem Senden würde ich noch versuchen durch
eine passende Zustandsabfrage des CAN controllers zu ersetzen/ergänzen.
Mailbox frei? Fehler? Die Sorte. Ansosten wirst du dich irgendwann
wieder wundern wo deine Nachrichten bleiben...
...
CANWrite(Tx_ID, Tx_Data,8, Can_Send_Flags);
Delay_ms(1);
...
Wie bist du denn auf die 700us für die Schleife gekommen?
Viel Erfolg
CANNOT schrieb:> Freut mich. Das delay nach dem Senden würde ich noch versuchen durch> eine passende Zustandsabfrage des CAN controllers zu ersetzen/ergänzen.> Mailbox frei? Fehler? Die Sorte. Ansosten wirst du dich irgendwann> wieder wundern wo deine Nachrichten bleiben...>> ...> CANWrite(Tx_ID, Tx_Data,8, Can_Send_Flags);> Delay_ms(1);> ...
-> Ne Idee wie ich das abfragen kann? Ich habe mir da auch schon
Gedanken darüber gemacht und habe bei der Beschreibung der Library von
MicroC nur folgendes gefunden: "Returns zero if message cannot be queued
(buffer full)."
(http://www.mikroe.com/download/eng/documents/compilers/mikroc/pro/pic/help/can_library.htm#canwrite)
>> Wie bist du denn auf die 700us für die Schleife gekommen?
-> Auf die 700us bin ich gekommen, indem ich einen Eingang vor Beginn
der Codesequenz auf High gesetzt habe und nach Beendigung der Schleife
auf Low. Das ganze habe ich mir am Oszi angesehen.
Nebenbei: Ich frage gerade mit 1Mbit/s ca. 7000 mal hintereinander ab,
dann ist mein LabView abgestürtzt wegen zu großem Array, aber der
Controller lief sehr stabil und fehlerfrei! Sehr schön!!!!