Angenommen, ich habe drei CAN-Knoten: A, B und C. Wir wissen, dass, wenn zwei Knoten gleichzeitig senden, der Knoten mit der geringsten SID den Bus überwiegt und der andere Knoten den Bus an den ersten abgeben muss Knoten. Was ich tun möchte, ist, dass Knoten B und C kontinuierlich nacheinander CAN-Frames an Knoten A senden (z. B. Knoten B -> Knoten A, Knoten C -> Knoten A, Knoten B -> Knoten A). Kann ich B einfach eine niedrigere SID als C zuweisen und einfach das folgende Code-Snippet ausführen?
Knoten B
while(1) sendCANmsg(data, NODE_A, sizeof(data), RTR_OFF);
Knoten C
while(1) sendCANmsg(data, NODE_A, sizeof(data), RTR_OFF);
Innerhalb von sendCANmsg ist hier das Snippet:
TXB0CONbits.TXREQ = 1; // Request Message Transmission
while (TXB0CONbits.TXREQ); // Wait until message is sent.
Übrigens verwende ich PIC18F25k80, um dies zu implementieren. Ich dachte nur, nachdem Knoten B die Nachricht gesendet hat, wenn Knoten C im Begriff ist, seine Nachricht zu senden. Der Knoten B gewinnt erneut die Busarbitrierung, wodurch dem Knoten C keine Übertragungsmöglichkeit gegeben wird. Also kann ich Abhilfe schaffen, die mir nur einfällt, indem ich eine kleine Verzögerung einfüge wie:
while(1) {
sendCANmsg(data, NODE_A, sizeof(data), RTR_OFF);
delay_us(10);
}
Oder liege ich falsch? :)
Da diese Methode den Bus nahezu zu 100 % auslastet, gehen wir davon aus, dass diese 3 Knoten die einzigen im Bus sind. Basierend auf Ihrer Verzögerungszeit von 10 µs gehen wir auch davon aus, dass die Busgeschwindigkeit 500 kbps beträgt (dh 5 Bit Verzögerung oder 1 Bit weniger Wartezeit nach der Arbitrierung zwischen Nachrichten).
Ob die Methode funktioniert oder nicht, hängt weitgehend von den Implementierungsdetails Ihres CAN-Treibers ab. Ein zuverlässigerer Weg, dies zu erreichen, wäre, Knoten B und C vor dem Senden darauf warten zu lassen, die Nachricht des jeweils anderen zu lesen (wobei Knoten B zunächst ohne Wartezeit sendet). IE:
Um die Desynchronisation zu berücksichtigen, sollte jede Wartezeit eine Zeitüberschreitung haben, nach der der Knoten sendet, unabhängig davon, ob er die Nachricht des anderen Knotens empfangen hat.
Dadurch wird die Busauslastung ausgeglichen und jeder Controller kann andere Aufgaben erledigen, während er auf die Nachricht wartet (anstatt im Falle eines Arbitrierungsverlusts ständig zu versuchen, zu senden).
Beachten Sie, dass dies eine unkonventionelle Verwendung von CAN ist. Möglicherweise sind Sie mit einem einfacheren Protokoll wie SPI besser bedient (Knoten A müsste B und C abfragen, aber es müsste keine Arbitrierung geben, und alles könnte DMA- und / oder Interrupt-gesteuert sein).
Erstens haben Knoten keine IDs, Nachrichten schon.
Das ist knifflig und ist nicht das, wofür CAN entwickelt wurde. Es sollte funktionieren, wenn jeder Knoten nach jeder erfolgreichen Übertragung absichtlich ein wenig verzögert. Ich kann mich nicht erinnern, ob die PIC 18F25K80-Hardware Sie wissen lässt, wann ein Frame tatsächlich gesendet wird, aber wahrscheinlich tut es das. Der andere Knoten benötigt nur ein kurzes Fenster, um das Ende des Rahmens zu sehen und mit der Übertragung zu beginnen. Sobald dieser zweite Knoten mit der Übertragung beginnt, verzögert der erste seine Nachricht sowieso automatisch bis zum nächsten Frame-Ende.
Dies klingt jedoch nach einem Missbrauch des CAN-Busses, und eine bessere Antwort könnte ein Überdenken der Gesamtarchitektur sein.
Xegara
Scott Wickler
Xegara
Scott Wickler
Xegara