Hallo,
Ich habe ein Paar Fragen zum Thema Can-Bus:
Zunächst einmal...ich habe eine Steuerung die via Can mit anderen
Busteilnehmern kommunizieren soll. Zunächst ist hierfür ein laptop mit
angeschlossenen CANinterface vorgesehen.
Ich verwende einen AT90CAN128 und als Tranciver einen PCA82C250 mit den
Anschlüssen bin ich mir eigentlich sicher... (TXD an TXCAN und RXD an
RXCAN, RS an GND und GND und Vcc ist ja klar) als Ausgänge für den
Can-BUS geht dann CAN_H und CA_L, sowie einmal GND mit 120 Ohm
terminierung an beiden enden.
Zu testzwecken habe ich einfach einmal volgendes Programm aufgespielt:
1
#define F_CPU 16000000
2
3
#include<avr/io.h>
4
#include<stdint.h>
5
#include<stdio.h>
6
#include<util/delay.h>
7
8
#include"can.h"
9
10
intmain(){
11
12
int8_ti;
13
14
CAN_messagemsg;
15
16
msg.id=1;
17
msg.idm=0;
18
for(i=0;i<=7;i++)msg.data[i]=0xAA;
19
20
CAN_init(500,NONE);
21
22
CAN_enableMOB(0,TRANSMIT_DATA,msg);
23
24
while(1){
25
CAN_sendData(0,msg.data);
26
}
27
return0;
28
}
Die CAN-Bibliothek habe ich von hier:
Beitrag "CAN-Bibliothek für den at90CAN128 und das AVRStudio"
Leider bekomme ich keinerlei Reaktion des CANs darauf ich habe die
Ausgänge am Controller und am Tranciver genessen und es kommt zu keiner
Pegelwandelung. RXCAN bleibt auf Lowlevel und TXCAN geht auf Highlevel
nach dem Programmstart. Am Tranciver liegen dann bei CAN_H und CAN_L
gleiche Pegel an. Ich habe dieses Programm ohne angeschlossene
Gegenstelle getestet. Weiß jemand wo der Fehler zu suchen ist?
Gruß
Steffen
Aber würde dan nicht wenigstens eine Anfrage auf den CAN geschickt
werden. Das Interface arbeitet genauso, wenn es alleine ist schickt es
kontinuierlich eine Nachricht raus.
> Aber würde dan nicht wenigstens eine Anfrage auf den CAN geschickt> werden.
Kommt darauf an, wie das Programm gestricj´kt ist.
Normalerweise gibt der Betrieb ohne Gegenstation sofort einen Bus-Error.
>Normalerweise gibt der Betrieb ohne Gegenstation sofort einen Bus-Error.
Warum? Wieso sollte es nicht möglich sein, eine Nachricht zu versenden.
Und am Bus hängt ausser dem Sender nur zwei Abschlusswiderstände...
Wieso sollte die Nacricht nicht versendet werden? Es hört nur keiner
drauf...
- Hat die Gegenstelle auch 500kB eingestellt?
- "Listen only" muss ausgeschaltet sein bei der Gegenstation!
- beliebt auch: CAN-H / CAN-L vertauscht
- Im Code vermisse ich ich Einstellung der Messagelänge (msg.len) und ob
es eine RemoteRequest message ist (sollte keine sein, msg.rtr = 0)
- Übrigens wartet "Can_sendData()" nicht unbedingt ab, ob der inhalt vom
Sendepuffer auch wirklich gesendet wurde
Ich habe es jetzt nochmal versucht, aber ohne Erfolg.
Ich verwende ein USBCANmodul1 von SysTec (siehe Anhang).
Die Baudrate stimmt bei beiden mit 500KBps, auch in der Ini des
Programms wird die Baudrate in KHz angegeben.
@JoLe64: Kennst du dich mit der von mir verwendeten Bibliothek aus?
Die Länge wird in der Funktion nicht abgefragt und Remote Request wird
über einen eigenen Funktionsaufruf realisiert.
Die Fkt. CAN_sendData wartet auf den Sendepuffer:
1
// Warten bis die Datenübertragung beendet ist (TXOK-Flag von CAN-Controller gesetzt)
2
while(!getbit(CANSTMOB,TXOK));
Wenn ich das CANinterface anschließe, meldet es sich wie gewünscht an
und wartet auf befehle. Wenn ich dann versuche etwas zu senden, wird
kontinuierlich eine Nachricht versendet und eine "CAN Error" durch
Blinken einer LED signalisiert.
Meine Steuerung macht gar keiene Anstalten irgendetwas zu senden, weder
zeigt sich suf dem Oszilloskop etwas noch würde das Interface etwas
empfangen.
Die Daten vom Bus werden allerdings korrekt auf die Eingänge des
Controllers übermittelt.
Die Anschlüsse sind auch nicht vertauscht, das habe ich gerade nochmal
überprüft, CAN_H und CAN_L sind richtig verbunden.
Den Tranciver betreibe ich bei 5V, gleiche versorgung, wie µC und andere
IC´s auf dem Board. Und wie gesagt, die Nachricht vom Interface, wenn es
einen Error meldet wird korrekt vom Tranciver weiter gegeben.
Kommt bei mir auch so hin die 100n müsste ich zwar erstmal suchen, wo
der sich versteckt. RS habe ich direkt auf GND gelegt, so wie in der
anleitung vorgeschlagen. Ansonsten genau wie bei dir.
Also,
mit deiner speziellen bibliothek kenn ich mich nicht aus, aber irgendwie
sind sich die Bibliotheken ähnlich, und irgendwie sind es auch immer die
gleichen Fehler wenn der CAN nicht geht. Allerdings hab ich bis jetzt
immer fertige Hardware benutzt, musste also nur Software Fehler suchen.
Elektrisch ist es so, das im Ruhezustand CAN-L und CA-H gleiche Pegel
haben. Beim Senden eines Bits geht das Potential von CAN-H ungefähr 1V
rauf (Differentiell zu CAN-L). Dabei werden "High" und "Low" auf dem Bus
als "Dominant" und "Rezessiv" übertragen. Dominante Bits überschreiben
Rezessive Bits, wenn gleichzeitig gesendet. Ziemlich am Ende der Message
schickt der Sender das "ACK", das ist ein rezessives Bit, und da müssen
alle, die ihn hören, dieses Bit dominant überschreiben. Sonst geht der
Sender in bus-error und sendet gar nicht mehr (ist beleidigt weil ihm
keiner zuhört).
Du müsstest also mit einem Oszi im One-Shot zumindest diese erste
Message nach der Initialisierung einfangen können.
Im übrigen müsste dein Laptop eine Message senden können, und wenn dein
Controller lebt, wird er auf ACK antworten. Wenn nicht, geht dein Laptop
in "BusError".
JAaaaaaaaaa!!!!
Es funktioniert! Keine Ahnung warum oder wo der Fehler lag! Aber ich
hab´s nochmal mit einer anderen beispieldatei(selber Beitrag wie oben,
nur später im Verlauf) Beitrag "CAN-Bibliothek für den at90CAN128 und das AVRStudio"
und es hat sofort funktioniert!
Ich verstehe es zwar nicht, aber bin froh das zumindest keine Hardware
defekt ist und ich jetzt etwas habe auf dem ich aufbauen kann!
Danke für die Unterstützung.
Steffen
Hallo,
erst mal Glückwunsch, und poste doch noch mal wenn du rausgefunden hast
was dein Problem war.
Auf die Schnelle sind mir 2 sachen aufgefallen:
- In dem anderen Beitrag wird die MOB 0 auf RECEIVE gesetzt
(anstatt TRANSMIT wie bei dir)
- CAN_sendData() steht nicht in einer Endlosschleife
vielleicht hat's ja damit zu tun.
Sollte ich auf den maßgeblichen Unterschied zwischen beiden Programmen
stoßen werde ich ihn posten.
Das einmal TRANSMIT oder RECEIVE eingestellt wird ist sicher richtig.
allerdings habe ich auch bei meinem Programm alle verfügbaren
Operationsmodi durchprobiert, ebenso wie alle möglichen Baudraten (diese
unterscheiden sich auch). Das eine for-Schleife eine andere Reaktion
auslöst wie eine while-Schleife an dieser Stelle sollte meinem
C-Verständnis nach nicht passieren. Dann schon eher die fehlende
Wartefunktion for dem senden der Msg.
Ich werde sicherlich nach dem Wochenende einiges mehr ausprobieren. Bis
dahin bin ich froh dass die Hardware funktioniert und es sich "nur" um
eine Softwarefehler handelt!
Bis Dann,
Genießt das Wetter
Steffen