Hi Leute,
ich würde mir gern einen eigenen CAN-Bus aufziehen. Dazu hab ich mir den
dsPIC30f6014 von Microchip zugelegt und ein passendes Board dazu.
Jetzt würde ich gerne prinzipiell eine Nachricht auf Tastendruck eine
Nachricht senden, diese dann verzögert wieder empfangen ( geschieht über
2tes Board).
Hört sich doch eigentlich ganz einfach an, aber meine Probleme gehen
leider schon beim initialisieren des CAN`s schief....
Kann mir da jemand helfen? Oder gibts irgendwo ein BSP. zum anschauen
und lernen?
Thx
Tom
Hi
Ich hab mit dem CAN-Modul leider noch nichts gemacht, aber probiers mal
im Microchip Forum oder im Fernando Heitor Forum.
forum.microchip.com
www.fernando-heitor.com
mfg schoasch
also danke für die beiden posts,
ich hab mal unter beiden geschaut und auch gepostet, bin mal gespannt.
was nicht geht:
eigentlich wollt ich eine folge von bits ausgeben lassen und mit dem
oszi anzeigen, also erst so, bevor ich an das 2te board gehe, aber ich
bekomm nichts raus, und ich vermute, dass es an der init liegt...
da kommt nichts raus, aber rein gar nichts..aber ich hab jetzt glaub ich
was entdeck, wenn ich schritt für schritt debugge, dann hängt mir das
progi in einer schleife fest und geht nimmer raus (schleife im normal
mode)
und dann kann ich ja net weitermachen, wenns da immer hängt
OK, das meinte ich nicht.
Das ist das Disassembly listing.
Ich habe gemeint, dass du dein komplettes projekt packst und die
gepackte datei hier in den anhang hängst.
Dann kann man die dateien mit mplab simulieren.
kein thema,
hab ich falsch verstanden...
hab noch ein fehler gefunden..und zwar waren die configuration bits
falsch...gesetzt, also in mplab, habs jetzt ins progi mit eingebunden...
mach gerade nen neuen test
thx
Wunderbar, so kann man da was machen.
Erst mal allgemeine C Sachen:
- Variablen am Anfang eines Blocks deklarieren, nicht mittendrin
- Am Ende von Main steht return 1;
Das würde bedeuten, dass main mit einem Fehler beendet wurde.
Da er da eh nicht hinkommt deklarier die main einfach als void.
- schreib alles was du zur initialisierung brauchst in die CAN Init
Funktion.
Dann muss man beim lesen nicht dauernd springen.
In der Main sollte dann nur noch stehen:
can_init();
can_senden(...);
while(1);
Zum CAN Problem.
- Wo genau bleibt er hängen, wenn du ihn mit dem Debugger laufen lässt?
- Versuchst du den CAN in den Loopback Mode zu versetzen?
-> Dann kanns nicht gehen
- Wie bist du auf den Code gekommen?
Mich wundert dass du das alles ohne Interrupt machen willst.
* also mit dem debugger bleibt er nur hängen, bzw. bleibt in der
while schleife, wenn ich auf die empfangene nachricht abfrage, ansonsten
läuft der durch...
while (C1RX0CONbits.RXFUL);
* ja, ich setz den CAN in den loopbackmode, ist das falsch?
* wieso ohne interrupt? kann ich nicht wirklich gut...also interrupt
routinen aufrufen und richtig behandeln...aber werd dass dann später
noch versuchen, wenn das jetzt so mal irgendwann laufen sollte
* das ich am Oszi nichts darstellen kann, also die frames, liegt das
am loopbackmode?
* das mit dem return 1; habe ich schon geändert gehabt, war nur ein
fehler, der mir erst nach dem posten aufgefallen ist...
* bei void main(void) gibt der c30 nen fehler raus, dass da ein int
hin muss...(Version 6.6 hier auf dem rechner, bei version 7.6 nimmt er
auch das void)
und das mit dem code ist überlegens- und probiersache...
ich hab mich durch den ganzen papierkram gewühlt und mir das versucht
irgendwie zu verinnerlichen...hab auch schon im netz rumgesucht, aber da
findet sich nicht wirklich was zum can mid dem dspic30f6014...
Stimmt das was ich im code mach? oder hab ich da noch nen großen
verständnissfehler?
z.b. ist mir noch nicht klar, wie das mit den buffern ist. wenn ich die
daten in den buffer schiebe und den dann sende, woher weiß das prog.
wohin er die buffer ausgeben muss?
ich hab zwar in der define_portpins:
#define CAN_RXD PORTFbits.RF0
#define CAN_TXD PORTFbits.RF1
die sache deklariert, aber wirklich an CAN_*XD übergeben tu ich nich
muss ich statt in den loopback mode in den normal operation mode (000)?
loopback brauch ich dann für was?
? wenn ich ein echo an den selben pic zurücksenden will?
okay, die eine frage mit dem mode hat sich geklärt:
Normal Operation Mode
Normal Operating mode is selected when REQOP<2:0> = ‘000’. In this mode,
the module is
activated, the I/O pins will assume the CAN bus functions. The module
will transmit and receive
CAN bus messages as described in subsequent sections.
Loopback Mode
If the Loopback mode is activated, the module will connect the internal
transmit signal to the
internal receive signal at the module boundary. The transmit and receive
pins revert to their
PORT I/O function.
The transmitter will receive an acknowledge for its sent messages.
Special hardware will
generate an acknowledge for the transmitter.
dann ist mir schon klar, wieso ich da nix sehe...
Genau. Hasts ja schon selbst rausgefunden.
Wenn du code zu dem CAN Modul suchst, kannst du auch ma bei den Code
Examples von den 33ern schauen. Die haben zwar ein anderes CAN Modul,
die Befehle sind aber weitestgehend gleich.
Kommt was raus, wenn du nicht in den loopback modus gehst?
ja und wie, bin gerade dabei das signal mit dem oszi darzustellen und
den frame auseinander zu nehmen, damit ich seh obs richtige raus
kommt...
wie ist das mit den SID und EID?
gibts da was zu beachten?
stimmen die so in meinem progi?
Was heisst stimmen die?
Soweit ich sehe, hast du die Eingangsfilter und Masken gesetzt.
mit dem Senden hat das nichts zu tun.
Das heisst nur, dass nicht alle CAN Nachrichten empfangen werden,
sondern nur diejenigen, die von Filter und Maske akzeptiert wurden.
Aber das was rauskommt ist schon mal sehr gut.
Bei SID und EID musst du eigentlich nichts beachten.
Ich würde dir raten für den Anfang nur SID zu verwenden und Filter und
Maske so einzustellen, dass alles durchgelassen wird.
ah okay, mit dem SID, bzw. EID stelle ich dann an den einzelnen Knoten
ein, welche der vielen nachrichten empfangen werden kann, bzw. werden
darf.
ist also bildlich die adresse des senders (also die maske) und der
filter entscheidet dann, ob angenommen werden darf via vergleich?
Knoten A:
SID: 1
Filter: 2
Knoten B:
SID: 2
Filter: 1
----> Knoten B, kann nachrichten von A empfangen und umgekehrt, wenn
jetzt aber eine nachricht mit SID: 3 kommt, dann kann weder A noch B
empfangen?
Hast du das getestet?
Ich hab dich gesagt, du sollst erst mal Filter und Maske weglassen. Das
macht dir nur Probleme, wenn dus nicht 100%ig verstanden hast. Damit
kannst du dich auseinandersetzen wenn der rest geht.
Setz mal alle Masken auf 0, dann müssten auch alle IDs durchkommen.
Ja.
Mit der Maske kannst du die eintreffende ID maskieren.
damit sagst du im Prinzip welche Bits der ID überhaupt gefiltert werden
sollen.
Wenn Maske = 0 wird kein Bit gefiltert.
Wenn Maske = 0x7FF kommen alle Bits in den Filter.
also irgendwie check ich das nicht....
ich bekomme vom bus einmal den identifier und die daten
identifier -> SID oder EID
dann habe ich den filter und die maske
kannst du mir das irgendwie an einem bsp. erklären?
z.b.
SID = 0x3BF = 1111011111 -> das ist der SID, der vom Knoten B stammt
Knoten A empfängt SID und Data
Filter & Maske ?
Ich hoff ich erzähl dir jetzt kein blödsinn. ich habe die filter noch
nicht oft benutzt.
Filtern kannst du nur die IDs.
Vergiss erst mal die EIDs.
Angenommen du willst alle ungeraden IDs wegfiltern:
Maske: 1 // für unterstes Bit
Filter: 0 // Alle geraden erlauben
wenn du die geraden weghaben willst, mach folgendes:
Maske: 1 // für unterstes Bit
Filter: 1 // Alle ungeraden erlauben
Alle Angaben ohne Gewähr ;-)
aha, also muss ich mir das so vorstellen:
SID = 0x7BF = 11111011111 Knoten B
Acceptance mask: Knoten A
CiRXMnSID = 0x000 = 00000000000 -> alle kommenden id`s werden
durchgelassen
CiRXMnSID = 0x700 = 11100000000 -> nur die bits <10:8> werden an den
filter weitergegeben
Acceptance filter: Knoten A
CiRXFnSID = 0x 7FF = 11111011111 -> nur diese ID wird erlaubt
-> alle bits werden verglichen, message kommt nur durch, wenn bits, die
durch die maske kommen mit filter übereinstimmen
???
gut dann hab ich das jetzt verstanden....
jetzt ist mir gerade noch was anderes aufgefallen:
wenn ich das signal am scope anschaue das ich sende...ist das immer
gleich...egal, ob ich daten im register C1TX0B1 = 0xFF
stehen hab oder net...
das was über den CANH rausgeht sollte doch normalerweise so aufgebaut
sein:
Start of frame <1>
SID <11>
RTR <1>
IDE <1>
RB0 <1>
DLC <4>
Data <8>
CRC <16>
ACK <2>
End of Frame <7>
<anzahl der bits>
im anhang hab ich die beiden scope-auszüge
einmal mit C1TX0B1 = 0x0 und dann mit 0xFF
--> wenn ich mir das so anschau, dann mach ich doch wohl noch irgendwo
einen fehler....
ich hab nur einen knoten...vorerst...den zweiten knoten bau ich aber
genauso auf wie den ersten, änder nur die sid und die maske ab...
das die nachricht ständig gesendet wird, klar..hab ich ja so ins prog.
geschrieben...nur was da gesendet wird...damit komm ich noch nicht
klar..
normalerweise müsste ich doch aus dem signal am CANH das Frame auslesen
können und so vergleichen, was ich im prog gesendet hab und was da jetzt
wirklich rauskommen tut...weil das scheint ja laut scope nicht daselbige
zu sein..*leider*
wäre ja zu schön gewesen, wenns gleich ohne probleme gefunzt hätt...lol
Da bei dir die Nachricht nie empfangen wird, wird diejenige, die als
erstes gesendet wurde immer wieder gesendet. Daher ist es völlig ok,
dass du immer dasselbe auf dem scope siehst.
So einfach kannst du mit dem Scope die CAN Nachricht nicht ablesen, weil
du dazu erst mal deine wirklich zu sendende nachricht ausrechnen
müsstest. Dazu musst du auch die Stuff Bits beachten. Ganz zu schweigen
von der CRC. Ich habe noch keine Quelle gefunden die sagt wie die CRC
berechnet wird. Weiss das jemand?
Bau erst mal den zweiten Knoten auf, dann erst kannst du sagen ob es
geht oder nicht. Ein CAN Bus mit nur einem Teilnehmer gibt es nicht.
mit gleich bei den bildern meinte ich aber nicht, dass die message immer
gleich bleibt, sondern
das wenn ich das wort 0xff schicke am scope bild 1 kommt
das wenn ich das wort 0x0 schicke am scope bild 2 kommt
jedesmal neu gestartet und initialisiert, deswegen meinte ich das ich da
nen unterschied sehen müsste
wenn ich 0xff und 0x00 hintereinander schicken würde, dann wärs mir auch
klar, aber da erst das eine wort (1), dann ein neues programming und
dann wort 2 geschickt wird....kommt mir das spanisch vor
misst jetzt muss ich mir erst noch so nen can-treiber besorgen, sonst
kann ich den 2ten knoten nicht anbinden....
naja ich mach mal und poste wieder wenns da ist..
merci
und nen schönes wochenende
Bei zwei Knoten kannst du ausnahmsweise mal die CANRX und CANTX
Leitungen gekreuzt verbinden.
Aber wenn der zweite Transceiver da ist, vergisst du das wieder !
also ich hab jetzt versucht den zweiten knoten auf meinem dsPICDem 28 zu
realisieren, scheitere aber da noch an der mangelnden Beschreibung zu
dem Board. Die Register für den Can bleiben bei einem dsPIC30F4012
gleich wie beim 6014, aber die portinitialisierung, bzw. beim clock ist
irgendwas anders...des funzt net....ich probier mal weiter. Das mit den
überkreuzten Leitungen lass ich mal lieber, net das ich das aus dusselei
dann so lass und mich wunder wenn nichts geht....lol
ui ui ui....
jetzt geht ein neuer bug um....habs mal in einem anderen thread
gepostet...
bitte mal durchlesen wenns geht...
danke
Thomas
Beitrag "dsPIC30F6014 using 2 CAN-Module"
So langsam zweifel ich wieder daran ob ich das richtig gemacht habe...
Wenn ich das Progi so, wie ich es geschrieben habe auf dem gleichen
board, aber mit verschiedenen ds teste, kommt jedesmal ein anderes
signal am ende raus....
kann es sein, dass ich beim init, bzw. bei den timings einen
gravierenden fehler drinn habe, so dass ich wenn ich was senden will,
immer das error-frame gesendet bekomme?
hab mich mit der frage noch nicht auseinandergesezt. kennst du dich
damit aus?
>du eh der einzige bist der hier zurückschreibt, bzw. bereit ist mit>bei meinem problem zu helfen
Ok Tom, wenn Du auf meine Fragen nicht eingehen willst, wirst Du schon
mit Willivonbienemaja's (großzügiger) Hilfe auskommen müssen. (Oder
liest du deinen zweit-Thread nicht?)
Gruss,
Edson