Forum: Mikrocontroller und Digitale Elektronik CAN Problem Freescale S12X


von Michael M. (aesis)


Angehängte Dateien:

Lesenswert?

Hi,

ich hab mal wieder ein Problem, wo ich nicht weiß, wo es hängt. Ich muss 
sagen, dass ich vorher noch nie etwas mit dem CAN zutun hatte, doch hab 
mir einen Sample Code geschnappt und den Spaß an meinen CAN0 angepasst, 
doch ich sehe keine Daten von der µC Seite. Empfangen geht auch nicht.

So habe ich den Sample Code mal genommen und geflasht und siehe da:

Ich sehe hier am Oszi auch nix.

Der Code ist doch recht überschaubar, doch weiß nicht, warum es einfach 
nicht geht.

Hab es auch mit einem Eval Board von Freescale probiert und bin alle 
möglichen PINs durchgegangen.

Laut Debugger zählt der duty auch hoch und die Sende-Funktion returnt 
eine 1 somit ist das Programm durchgelaufen.

Hat einer eine Idee, warum das so nicht funktioniert? Der Spaß ist mit 
dem CodeWarrior erstellt worden.

Viele Grüße und Danke im Voraus,

aesis
von Volker Z. (vza)


Lesenswert?

Hier eine Liste mit möglichen Fehlern:

falscher Takt
ungenauer Takt
falscher Samplepoint
falscher Transceifer
kein/falscher Busabschluss
Kein (funktionsfähige) Gegenspieler
Busleitungen vertauscht
keine Masseleitung

etc.

Hast du keinen Tranceifer/keinen Gegenspieler sollte der CAN-Kontroller 
das Paket ein paar mal senden (jeweils mit einem Errorframe angehängt) 
und dann in den BUS-OFF Zustand wechseln. Dies geht sehr schnell.
Hast du ein Speicher-Oszi?


......

Das waren ein paar Anregungen.
von aesis (Gast)


Lesenswert?

Nein ich habe kein Speicher-Oszi.

Also das mit Takt und so würde kommen, wenn ich überhaupt ein Signal 
sehen würde, doch ich sehe rein Garnichts an den µC-Ausgängen - nur 2 
unterschiedl. high Level des CAN.

Was meinst du mit Sample-Point?

Masse, so wurde mir gesagt, kann weggelassen werden, doch hatte sie auch 
testweise mal gebrückt und kein Unterschied.

Der Bus ist mit 60 Ohm terminiert und die Leitungen stimmen.

ich gehe nicht davon aus, dass es an der hardware liegt, da auch das 
Eval Board SK-S12XDP512-A keinen Mucks von sich bezüglich CAN gibt. :(
von Volker Z. (vza)


Lesenswert?

Ohne Speicher-Oszi wird es schwierig, zu Beweisen, das er wirklich 
nichts gesendet hat.

> Sende-Funktion returnt eine 1
Das heißt wahrscheinlich nur das er es an den Controller übergeben hat. 
Bitte prüfen.
Fehlerzähler und das Gesended-Flag auslesen und Anzeigen

Bei jedem CAN-Controller kann man den Samplepoint bestimmen. Das 
beeinflusst den Empfang unter schwierigen Bedingungen. Er sollte aber 
trotzdem senden.

> nur 2 unterschiedl. high Level des CAN.
Im Ruhezustand sollten sie gleich sein (recessiver Pegel)
Bei manchen µC muss man noch die Portpins umschalten.
Oder du hast doch noch einen Verdrahtungsfehler.

>Masse, so wurde mir gesagt, kann weggelassen werden, doch hatte sie auch
>testweise mal gebrückt und kein Unterschied.
Dies ist falsch.
Auf dem Labortisch und nur zwei Busteilnehmen klappt es meistens. Bei 
dreien nicht mehr.

Volker
von aesis (Gast)


Lesenswert?

Also vom PCAN sehe ich ganz genau, dass er eine Menge schickt.

Ja ich habe nur einen PCAN und halt das Board.

Also ich hab einmal 5V (CAN_h) und 4,6V (CAN_l). Das ist aber beim PCAN 
genauso.

Ich hab den Spaß aus folgendem Buch:

Introduction to Embedded Systems Interfacing to the Freescale 9S12

Und da steht:

Send message:

void CAN_Send(unsigned short id, char length,
char *data, char priority) {
char *pt=(char*)&_CANTXDSR0; // points to transmit message buffer
while((CANTFLG&0x07)== 0){} ; // Wait for transmit buffer available
CANTBSEL = CANTFLG; // Request selection of empty xmt buf
CANTXIDR0 = id>>3; // Write Identifier into ID registers
CANTXIDR1 = id<<5; // with RTR and IDE=0
CANTXDLR = length; // 0 to 8 bytes
while(length){
*pt++ = *data++; // copy data into data registers
length--;
}
CANTXTBPR = priority; // set priority of this message
CANTFLG = CANTBSEL; // flag buffer as ready for transmission
}

Receive message:

void CAN_Receive(char msg[13]) {
while (CANFifo_Get(msg) == 0){} ; // wait for incoming message
}
interrupt 38 void CANInterruptHandler(void){
char *msgPtr = (char*)&_CANRXIDR0;
if(CANRFLG & RXF){
CANCTL0 |= RXFRM; // clear Received frame flag
CANFifo_Put(msgPtr); // puts 11 bytes of message into 13-byte FIFO
CANRFLG |= RXF; // clear RXF by writing a 1.
}
}

Und noch Spaß für die main:

void main(void){ // example foreground program
char msg[13]; // received message
unsigned short id; // ID of received message
char length;
char i;
short sum;
CAN_Open(); // activate CAN
for(;;) {
CAN_Receive(msg); // wait for incoming message
id = (msg[0]<3)+(msg[1]>>5); // bytes 0,1 are CANTXIDR0-1
if(id == 50){ // bytes 2,3 contain no information
length = msg[12]; // byte 12 is CANTXDLR
i = 4;
sum = 0;
while(length){
sum += msg[i++]; // bytes 4-11 are data
length—;
}
CAN_Send(51,2,&sum,0);
}
}
}


Die Register hae ich für meinen CAN0 angepasst und natürlich noch 
Sachen, was er unter welcher ID verstehen soll und was er regeläßig nach 
eine PIT interrupt schicken soll doch nix passiert.
von Volker Z. (vza)


Lesenswert?

aesis schrieb:
> Also ich hab einmal 5V (CAN_h) und 4,6V (CAN_l). Das ist aber beim PCAN
> genauso.

Die Pegel sind definitiv Falsch. sowohl als recessiver als auch als 
dominanter Pegel.
1
CAN_Receive(msg); // wait for incoming message
2
if(id == 50){ // bytes 2,3 contain no information

Er wartet bis eine Message mit ID 50 kommt. Er sendet nicht von alleine.
1
id = (msg[0]<3)+(msg[1]>>5); // bytes 0,1 are CANTXIDR0-1

Dies ist Murks.

Feierabend. Muss nach Hause.
von aesis (Gast)


Lesenswert?

Das ist der code aud dem Buch. Ich hab den siehe Projekt ganz oben 
angepasst (Testsoftware).

Also das Demo-Board hat CAN0-4 und bei manchen ist CAN_h bei 5V und 
CAN_l bei 0V.

Bei anderen wiederum CAN_h als auch CAN_l @ genau 3V.
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.