Forum: Mikrocontroller und Digitale Elektronik CAN-Bus Management Senden/Empfangen


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Markus W. (mw73)


Bewertung
0 lesenswert
nicht lesenswert
Guten Morgen,

ich arbeite gerade an einem Testprojekt bei dem 5 Mega328 über CAN-Bus 
miteinander kommunizieren. Dabei habe ich die Lib von Fabian Greif 
(kreatives Chaos) im Einsatz.

Das System ist so konfiguriert, dass ein Master die Kommunikation 
steuert. Die Abfrage an die Slaves erfolgt zyklisch und genau so werden 
auch Kommandos übergeben.

Senden und Empfangen, sowie Filterkonfiguration klappen soweit ganz gut 
und der Bus läuft stabil. Zwischen jedem Sendevorgang, den der "Master" 
durchführt habe ich noch 5ms delay eingebaut, um die Antwort eines jeden 
"Slaves" abzuwarten.

Schema:

Master sendet --> Slave1 --> Slave1 sendet Antwort zurück an Master
Master sendet --> Slave2 --> Slave2 sendet Antwort zurück an Master
Master sendet.....

Nutzen:

Bei diesem Projekt soll eine Lichtsteuerung bzw. Rolladensteuerung 
realisiert werden. Die Tasterzustände der einzelen Teilnehmer werden vom 
Master abgefragt und wenn ein Taster eines Teilnehmers betätigt wird, 
soll eine Aktion ausgeführt werden (Licht ein/aus, Rollladen 
rauf/runter).

Meine konkrete Frage:

Wie würdet ihr die Datenverarbeitung des Mastercontrollers am 
effizientesten lösen?
- State-Machine?
- Scheduler?
- sofortige Auswertung der Daten nach Empfang?
- Zwischenspeicherung der Daten in einem Array und danach Bearbeitung?

Wie gesagt, die Kommunikation, wie ich sie im Moment betreibe 
funktioniert sehr gut. Unsicher bin ich mir, wie und wann ich die Daten 
am besten verarbeite. Vielleicht könnt ihr mir hierzu ein paar Tips 
geben, um ein vernünftiges Management aufbauen zu können.

Achja, hier noch einige Eckdaten:
Controller: mega328 16MHz
Can Controller: MCP2515 16MHz (Chinamodul)
Busgeschwindigkeit: 125kBpS
Filter: Master - keine Filter
        Slave - jeweils nur für ihn bestimmte Nachrichten.

Ich freue mich auf eure Tipps - Danke im Voraus!
Markus

von Wolfgang (Gast)


Bewertung
1 lesenswert
nicht lesenswert
Markus W. schrieb:
> Das System ist so konfiguriert, dass ein Master die Kommunikation
> steuert. Die Abfrage an die Slaves erfolgt zyklisch und genau so werden
> auch Kommandos übergeben.

Mit dem CAN-Bus hat dein Protokoll wenig zu tun. Bei der 
Datenübertragung in einem CAN-Bus werden keine Knoten adressiert, 
sondern der Inhalt einer Nachricht (z. B. Schalterzustand oder 
Sensorwert) wird durch einen eindeutigen Identifier gekennzeichnet. Der 
Identifier legt auch die Priorität der Nachricht fest.

von Thomas O. (kosmos)


Bewertung
2 lesenswert
nicht lesenswert
Es ist überhaupt nicht nötig einen Master oder Slaves zu haben. Entweder 
sagst du deinen "Slaves" sie sollen die Infos zyklisch ausgeben oder nur 
bei Zustandsänderung. Bei einer einfachen Rolladen/Lichtsteuerung wirst 
du nie in Bereiche kommen das der BUS überlastet wird.

Ansosten könnte man auch einen µC mit integriertem CAN-Controler nehmen 
z.B. ATMega16M1,32M1......

von Rolf M. (rmagnus)


Bewertung
1 lesenswert
nicht lesenswert
Markus W. schrieb:
> Das System ist so konfiguriert, dass ein Master die Kommunikation
> steuert. Die Abfrage an die Slaves erfolgt zyklisch und genau so werden
> auch Kommandos übergeben.

Du hast also selber noch ein eigenes Protokoll obendrauf gesetzt, den 
CAN kennt von sich aus keinen Master oder Slave. Welchen Zweck hat 
dieses Protokoll?

> Master sendet --> Slave1 --> Slave1 sendet Antwort zurück an Master
> Master sendet --> Slave2 --> Slave2 sendet Antwort zurück an Master
> Master sendet.....

Bei CAN wird nicht an einen bestimmten Knoten gesendet. Alle Botschaften 
sind Broadcasts, und wer immer sich für einen bestimmten Wert 
interessiert, lauscht auf der entsprechenden ID.

> Meine konkrete Frage:
>
> Wie würdet ihr die Datenverarbeitung des Mastercontrollers am
> effizientesten lösen?
> - State-Machine?
> - Scheduler?
> - sofortige Auswertung der Daten nach Empfang?
> - Zwischenspeicherung der Daten in einem Array und danach Bearbeitung?

Die empfangenen CAN-Botschaften in eine Queue stecken und dann 
abarbeiten. Irgendwo liegt eine Datenstruktur, die die in der Botschaft 
enthaltenen Werte aufnimmt und in der immer der aktuellste Wert drin 
steht.

Thomas O. schrieb:
> Es ist überhaupt nicht nötig einen Master oder Slaves zu haben. Entweder
> sagst du deinen "Slaves" sie sollen die Infos zyklisch ausgeben oder nur
> bei Zustandsänderung.

Oder beides, also z.B. zyklisch einmal pro Sekunde und zusätzlich sofort 
bei jeder Zustandsänderung. So kann man die Buslast gering halten, aber 
der "Master" bekommt trotzdem alle Werte mit, wenn er irgendwann erst 
später eingeschaltet wird.

> Bei einer einfachen Rolladen/Lichtsteuerung wirst du nie in Bereiche kommen
> das der BUS überlastet wird.

Genau. Im Auto werden auf die Weise Tausende von Werten über einen 
CAN-Bus geschickt.

von Markus W. (mw73)


Bewertung
-2 lesenswert
nicht lesenswert
Ich habe vor einiger Zeit mit RS-485 gearbeitet. Daher bin ich noch 
etwas auf die Master-Slave-Kommunikation fixiert.

Wolfgang schrieb:
> in einem CAN-Bus werden keine Knoten adressiert,
> sondern der Inhalt einer Nachricht (z. B. Schalterzustand oder
> Sensorwert) wird durch einen eindeutigen Identifier gekennzeichnet.

Natürlich arbeite ich nicht mit Adressen sondern mit Identifieren.

Thomas O. schrieb:
> Bei einer einfachen Rolladen/Lichtsteuerung wirst
> du nie in Bereiche kommen das der BUS überlastet wird.

Wenn alle meine "Slaves" oder "Nodes" zyklisch senden, besteht da nicht 
die Gefahr dass der "Master" überlastet wird? Der bekommt ja schließlich 
Nachrichten von allen Teilnehmern und muss diese Verarbeiten. Ich denke 
man kann auch das nur zeitgesteuert realisieren. Welche Intervallzeiten 
wären denn da sinnvoll?

Rolf M. schrieb:
> CAN kennt von sich aus keinen Master oder Slave. Welchen Zweck hat
> dieses Protokoll?

Das soll kein Protokoll sein, sondern nur eine Vorgehensweise, bei der 
der so genannte Master alle Vorgänge steuert. Weiters sollen zB. 
Öffnungs- und Schließzeiten der Rolläden vom "Master" vorgegeben werden. 
Narürlich läuft die Kommunikation entsprechend des CAN-Protokolls ab 
(Identifier, Prioritäten usw.)

Rolf M. schrieb:
> Die empfangenen CAN-Botschaften in eine Queue stecken und dann
> abarbeiten. Irgendwo liegt eine Datenstruktur, die die in der Botschaft
> enthaltenen Werte aufnimmt und in der immer der aktuellste Wert drin
> steht.

Für mich sehr wichtige Info - Leider kenne ich den Begriff "Queue" 
nicht.
Könntest Du mir das bitte etwas erklären bzw. einen kurzen Code-Snipped 
zeigen wie so etwas aussieht?

von Thomas O. (kosmos)


Bewertung
0 lesenswert
nicht lesenswert
Bei CAN können alle gleichzeitig lossenden es kommt aber nur die 
Nachricht mit der niedrigsten ID durch die anderen Knoten Stellen das 
Senden ein und wiederholen das Senden wenn die andere Nachricht fertig 
ist.

Schau dir mal im Wiki den Abschnitt Arbitrierung durch.

: Bearbeitet durch User
von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Markus W. schrieb:
> Thomas O. schrieb:
>> Bei einer einfachen Rolladen/Lichtsteuerung wirst
>> du nie in Bereiche kommen das der BUS überlastet wird.
>
> Wenn alle meine "Slaves" oder "Nodes" zyklisch senden, besteht da nicht
> die Gefahr dass der "Master" überlastet wird? Der bekommt ja schließlich
> Nachrichten von allen Teilnehmern und muss diese Verarbeiten.

Das muss er doch sowieso. Nur muss er bei deiner 
Master/Slave-Kommunikation zusätzlich noch die Anfragen verschicken.

> Ich denke man kann auch das nur zeitgesteuert realisieren. Welche
> Intervallzeiten wären denn da sinnvoll?

Das kommt darauf an, welche Verzögerungszeiten du für akzeptabel 
erachtest. Wenn der "Slave" einfach so senden kann, kannst du die 
Zykluszeit relativ lang machen und dann spontan in dem Moment senden, in 
dem der Taster gedrückt wird, um eine sofortige Reaktion auszulösen.

Übrigens: Das hier:

Markus W. schrieb:
> Senden und Empfangen, sowie Filterkonfiguration klappen soweit ganz gut
> und der Bus läuft stabil. Zwischen jedem Sendevorgang, den der "Master"
> durchführt habe ich noch 5ms delay eingebaut, um die Antwort eines jeden
> "Slaves" abzuwarten.

bedeutet ja, dass der "Slave" in maximal 5 ms auf die Anfrage 
geantwortet haben muss. Was passiert denn, wenn die Antwort später 
kommt?

> Das soll kein Protokoll sein, sondern nur eine Vorgehensweise, bei der
> der so genannte Master alle Vorgänge steuert.

Genau sowas nennt man Protokoll :)

> Rolf M. schrieb:
>> Die empfangenen CAN-Botschaften in eine Queue stecken und dann
>> abarbeiten. Irgendwo liegt eine Datenstruktur, die die in der Botschaft
>> enthaltenen Werte aufnimmt und in der immer der aktuellste Wert drin
>> steht.
>
> Für mich sehr wichtige Info - Leider kenne ich den Begriff "Queue"
> nicht.

Eine Warteschlange.
https://de.wikipedia.org/wiki/Warteschlange_(Datenstruktur)

: Bearbeitet durch User
von Wolfgang (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Markus W. schrieb:
> Natürlich arbeite ich nicht mit Adressen sondern mit Identifieren.

Es hörte sich aber so an, als ob dein Master die Slaves der Reihe nach 
abfragt. Soll dein Identifier dann ein "Poll"-Identifier sein und der 
Nachrichteninhalt wäre die Slave Adresse? Oder wie ist das gemeint?
Das würde doch genau einer individuellen Adressierung entsprechen und 
nichts mit dem grundsätzlichen Broadcast-Konzept vom CAN zu tun haben, 
zumindest bezogen auf die Antworten deiner Slaves. Irgendwie mischt du 
da zwei Konzepte.

von A. S. (achs)


Bewertung
1 lesenswert
nicht lesenswert
Dein Master Slave Konzept ist gut für andere Halbduplex Leitungen, bei 
CAN eher über.

Zur Frage: mach einfach. Du brauchst Erfahrung. Bei master/slave wirst 
Du feststellen, dass es egal ist, bzw alles gleich: du kannst direkt 
auswerten, es wird dadurch nicht langsamer, im Gegenteil.

Dann wirst Du feststellen, das CAN viel besser ist und keinen Master 
braucht. Je nach Art der Nachrichten und Leistung deines uControllers 
brauchst Du dann Fifos: vielleicht reichen die im CAN-Controller, 
vielleicht eigene im uC. Manche nur Zustände (den letzten, ältere 
überschreiben, dafür mehrere parallel), manche Aufträge (keiner darf 
verloren gehen)

von Markus W. (mw73)


Bewertung
0 lesenswert
nicht lesenswert
@all

vielleicht ist das von mir nicht richtig rüber gekommen. Das Senden und 
Empfangen seitens CAN funktioniert so weit sehr gut. Ich habe mich in 
die Thematik CAN-Bus eingelesen (darunter auch die Arbitrierung) und 
mich mit der von mir verwendeten Lib (Fabian Greif - kreatives Chaos) 
vertraut gemacht.

Wahrscheinlich muss ich mich aber noch von der bis jetzt angewendeten 
Master-Slave-Kommunikation lösen, um die Vorteile von CAN besser nutzen 
zu können.

Mein Problem besteht allerdings wie ich die empfangenen Daten am besten 
und effektivsten verarbeite.

Ich möchte jetzt bewusst nicht mehr die Begriffe "Master" und "Slave" 
verwenden. Also, wenn ein Teilnehmer von verschiedenen anderen Knoten 
Daten erhält, wie realisiere ich dieses Handling am besten.

Rolf hat mir hierzu einen guten Hinweis gegeben - die Queue.
Könntest Du mir vielleicht ein kurzes Beispiel zukommen lassen?

Ich hoffe ich konnte mich jetzt etwas klarer ausdrücken.

von Thomas F. (igel)


Bewertung
0 lesenswert
nicht lesenswert
Zum Master/Slave wurde jaschon ausreichend gesagt dass dies bei CAN eher 
fehl am Platz ist.

Markus W. schrieb:
> Wie würdet ihr die Datenverarbeitung des Mastercontrollers am
> effizientesten lösen?

Der MCP2515 löst ja nach Empfang einer Nachricht einen Interrupt aus. 
Daraufhin liest man die Botschaft schnell aus und speicert diese in eine 
Zwischenspeicher.
Bei jedem Durchlauf der Hauptschleife schaut man nun ein oder zweimal 
nach ob eine neue Botschaft im Zwischenspeicher liegt und wenn ja so 
arbeitet diese ab.

So mache ich das jedenfalls.

von Heinz (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Markus W. schrieb:
> Mein Problem besteht allerdings wie ich die empfangenen Daten am besten
> und effektivsten verarbeite.

Lass einfach alle Knoten in einem festen Raster ihre Zustände (Taster 
etc) oder Kommandos (Rolladen, Licht) senden - pro Knoten möglichst 
alles in einer Botschaft. Ich schätze ein 20ms Raster sollte hier 
reichen und die uCs nicht überfordern.

Für mich lesen sich deine Anforderungen so, als wäre eine Queue hier 
nicht erforderlich. Queues nutzt man, wenn jede einzelne Nachricht 
bearbeitet werden muss. Hier scheint es mir aber so als würde es 
ausreichen, wenn du nur jew. die aktuelle Nachricht bearbeiten musst:

alle 10ms:
CanDatenEinlesen();
Verarbeiten();
CanDatenAusgeben();

Wenn du keine Nachricht verpassen willst oder darfst: Lies im Interrupt 
die relevanten CAN Frames ein, schreibe sie in einen Ringbuffer und 
dann:

CanDatenAusRingbufferVerarbeiten();
CanDatenAusgeben();

Anregung dazu:
Nimm in jede CAN Botschaft einen Botschaftszähler auf. So merkst du, ob 
du eine aktuelle Botschaft verarbeitest oder eine ältere. Das kann 
aufgrund von Taskzyklus-Jitter vorkommen und ist absolut normal. Mit dem 
Zähler kannst du auch Ersatzreaktionen auslösen (Ausfall des 
Busteilnehmers).
Wenn du über den Bus ein Protokoll fährst, kannst du so auch die 
Zustandsautomaten zurücksetzen.

> Rolf hat mir hierzu einen guten Hinweis gegeben - die Queue.
> Könntest Du mir vielleicht ein kurzes Beispiel zukommen lassen?
Queue vs. Ringbuffer:
Ich kenne nicht alle deine Anforderungen, aber im Normalfall nimmt man 
einen Ringbuffer.
Wenn du mit einer Queue arbeitest, musst du Leser und Schreiber 
synchronisieren (Interruptsperre o.ä.). Wenn du einen Ringbuffer nimmst, 
müssen Schreiber und Leser nicht gegeneinander gesperrt werden, sofern 
die Ringbuffer-Implementierung etwas taugt.

von Heinz (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:
Wenn dein System hochläuft hat noch kein Knoten Daten empfangen.
Daher solltest du einen Init-Zustand (never-received) festlegen, mit dem 
das System hochkommt und zu Beginn erstmal 100ms warten bevor du 
empfangene CAN-Daten verarbeitest.
Wenn nach Ablauf der 100ms immer noch nichts empfangen wurde, kannst du 
in den Zustand Timeout wechseln und ggf mit Ersatzwerten arbeiten oder 
Ersatzreaktionen aufschalten - was auch immer in deinem Fall gerade 
sinnvoll ist...

von A. S. (achs)


Bewertung
0 lesenswert
nicht lesenswert
Heinz schrieb:
> Wenn du mit einer Queue arbeitest, musst du Leser und Schreiber
> synchronisieren (Interruptsperre o.ä.). Wenn du einen Ringbuffer nimmst,
> müssen Schreiber und Leser nicht gegeneinander gesperrt werden, sofern
> die Ringbuffer-Implementierung etwas taugt.

Das ist falsch. Beide Konzepte sind geeignet und Standard, um 
verschiedene Tasks zu synchronisieren.

Der Unterschied: Queues händel in der Regel externe Speicherblöcke, die 
gesondert verwaltet werden müssen.

Ring-Puffer sind direkt der Puffer, jedoch muss meist byteweise oder 
semiblockweise rein und rausgeschrieben werden. Sie sind daher eher für 
byteorientierte Kommunikation (seriell) geeignet.

Bei CAN könnte der Ring-Puffer auch nachrichtenorientiert sein. Dann 
spricht man aber einfach von Fifo und kümmert sich nicht  die 
Implementierung

von Tilo R. (joey5337) Benutzerseite


Bewertung
0 lesenswert
nicht lesenswert
Was mir auch schon geholfen hat:
Anhand der Bitrate und Größe der Nachrichten ausrechnen, wie schnell 
Nachrichten überhaupt kommen können.

Dann kannst du gegenrechnen, wie viel Zeit pro Nachricht für das Abholen 
über SPI verbraucht wird und wie viele CPU-Cycles du dann noch übrig 
hast zur Verarbeitung.

Ich bin so teilweise zum Schluss gekommen, dass ich keine zusätzliche 
Empfangswarteschlange brauche und sogar auf das Abholen in der ISR 
verzichten kann.
Dazu kommt, dass der MCP2515 2 Empfangspuffer hat und, sebst wenn beide 
voll sind, gleichzeitig noch eine dritte Nachricht empfangen kann.

von Heinz (Gast)


Bewertung
0 lesenswert
nicht lesenswert
A. S. schrieb:
> Das ist falsch. Beide Konzepte sind geeignet und Standard, um
> verschiedene Tasks zu synchronisieren.
Queue: Beim Einhängen und ausklinken von Elementen aus einer Queue 
werden die Queuepointer auf Vorgänger- und Nachfolgerelement geändert. 
Prinzip-bedingt ist eine atomare Bearbeitung der Queuepointer nicht 
möglich.
Daher muss synchronisiert werden (Interruptsperre, Semaphore, 
Spinlock..)

Ringbuffer: Der Schreiber ändert den Schreibindex, der Leser ändert den 
Leseindex - keine Synchronisation erforderlich, sofern die 
Ringbuffer-Implementierung etwas taugt.

Soweit mein langjähriger Kenntnisstand, aber ich lerne gerne dazu (keine 
Ironie!!). Kennt hier jemand eine Queue-Implementierung, bei der Leser 
und Schreiber asynchron laufen dürfen?

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Heinz schrieb:
> Queue: Beim Einhängen und ausklinken von Elementen aus einer Queue
> werden die Queuepointer auf Vorgänger- und Nachfolgerelement geändert.

Wieso Vorgänger?

> Ringbuffer: Der Schreiber ändert den Schreibindex, der Leser ändert den
> Leseindex - keine Synchronisation erforderlich, sofern die
> Ringbuffer-Implementierung etwas taugt.

Und wenn die Indizes gleich sind und somit der Schreiber den Eintrag 
verändert, den der Leser gerade liest? Oder der Leser liest schneller 
als der Schreiber schreibt?

Mir ist nicht so ganz klar, wo für dich der fundamentale Unterschied 
zwischen einer Queue und einem Ringpuffer ist. Ich würde sagen, ein 
Ringpuffer ist eine gängige Art, eine Queue zu implementieren.

von Heinz (Gast)


Bewertung
0 lesenswert
nicht lesenswert
> Wieso Vorgänger?
Ich ging von einer doppelt verketteten Liste aus, damit man vorwärts und 
rückwärts iterieren kann.

> Mir ist nicht so ganz klar, wo für dich der fundamentale Unterschied
> zwischen einer Queue und einem Ringpuffer ist.
Queues sind für meine Begriffe flexibler. Man kann bspw. mitten drin 
Elemente einhängen oder entfernen.
Der wichtigste Unterschied ist für mich aber: Ringbuffer können ohne 
weitere Synchronisation in ISRs befüllt und von anderer Stelle geleert 
werden, sofern die Implementierung etwas taugt.

von Heinz (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Rolf M. schrieb:
> Und wenn die Indizes gleich sind und somit der Schreiber den Eintrag
> verändert, den der Leser gerade liest?
Dann ist aus Sicht des Lesers der Ringbuffer noch leer.

> Oder der Leser liest schneller als der Schreiber schreibt?
Das sollte der Normalfall sein. Der Leser liest einfach, bis nichts mehr 
drin ist.

von Markus W. (mw73)


Bewertung
0 lesenswert
nicht lesenswert
Wow, danke erstmals an alle,

da waren jetzt sehr viele nützliche Infos und gute Tips dabei. Das hat 
wirklich sehr geholfen. Es gibt eurer Ansicht nach mehrere Wege, wie man 
die Verarbeitung lösen kann, was natürlich von der Menge der zu 
verarbeitenden Daten abhängig ist.

Sollten meine Daten vielleicht mehr werden bzw. die Erfordernis 
eintreten, jede einzelne Nachricht bearbeiten zu wollen/müssen, müsste 
ich mir also Gedanken über eine gute Implementierung eines Ringpuffers 
machen. Kann mir vielleicht jemand von euch so eine Implementierung 
empfehlen, bzw. ein kleines Beispiel zukommen lassen, da ich auf diesem 
Gebiet überhaupt keine Erfahrung habe.

Auf alle Fälle bedanke ich mich noch einmal recht herzlich für die 
zahlreichen tollen Tips von euch.

Grüße Markus

von Rudolph R. (rudolph)


Bewertung
0 lesenswert
nicht lesenswert
Markus W. schrieb:
> Sollten meine Daten vielleicht mehr werden bzw. die Erfordernis
> eintreten, jede einzelne Nachricht bearbeiten zu wollen/müssen, müsste
> ich mir also Gedanken über eine gute Implementierung eines Ringpuffers
> machen.

Dein CAN ist jetzt wie schnell? 100kBit/s?
Licht- und Rolladen-Steuerung bedeutet das sind lange Strecken, also 
muss die Datenrate eher niedrig angesetzt sein.
Edit: bäh, überlesen, also 125kBit/s.
Überlegt mal, wie lange eine einzelne Nachricht auf dem Bus unterwegs 
ist.
Eine 1-Byte Botschaft mit 11 Bit Identifier ist schon mindestens 44 Bits 
lang.
Das sind 352µs bei 125kBit/s, weniger Zeit kann zwischen zwei CAN-Frames 
mit 1 Byte Nutzdaten gar nicht vergehen.
Auch wenn ich jetzt ein Bit unterschlagen oder zwei zu viel habe, das 
ist selbst für einen Mega328 mit SPI-Nadelöhr dazu ziemlich viel.
Klar kann man den SPI auch auf 1MHz oder gar niedriger einstellen, wenn 
man das unnötig langsam haben will.

Ich kenne den MCP2515 nicht, ich habe nur gerade das Datenblatt auf.
Nutzt man nur den /INT Pin braucht man wohl erst ein Read Status 
Kommando, das sind zwei Bytes auf dem SPI.
Ein Byte Nutzdaten zu lesen mit dem Read RX Buffer Kommando sind auch 
wieder nur zwei Bytes auf dem SPI.
Also selbst bei 1MHz auf dem SPI sollte das in <33µs durch sein.
Nutzt man /RX1BF und/oder /RX0BF braucht man das Status Register nicht.

Edit: ist der Empfangs-Puffer völlig offen braucht man noch die ID, 
okay, das sind dann 7 Bytes auf dem SPI, Kommando und lesen von RXB0SIDH 
bis RXB0D0. Bei 1MHz SPI so um die 60µs.

So langsam wie das ist könnte man auch alle 250µs oder so das Status 
Byte pollen und ohne Empfangs-Interrupt auskommen.

: Bearbeitet durch User
von Markus W. (mw73)


Bewertung
0 lesenswert
nicht lesenswert
Danke Rudolf auch für Deine sehr umfangreiche Erklärung.
So wie ich das lese, gehe ich davon aus, dass Du der Meinung bist, dass 
ich hier ohne Ringpuffer auskomme.

von Rudolph R. (rudolph)


Bewertung
0 lesenswert
nicht lesenswert
Naja, Anforderungen bestimmen, Nachrechnen, Implementieren, Testen.

Interessant ist da noch was so ein Controller noch so machen soll und 
wie viel Overhead die wofür-auch-immer-überhaupt "libs" verursachen.
Der SPI von dem Mega328 läuft mit 8MHz, der MCP2515 kann das auch und 
mit mehr als einem Datenbyte auf dem CAN wird es tendenziell auch nicht 
schlimmer.

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.