Forum: Mikrocontroller und Digitale Elektronik SPI für verteilte Systeme


von Felix (Gast)


Lesenswert?

Hallo zusammen,
ich würde gerne einen Raspberry Pi mit einem oder mehreren ATmegas als 
verteiltes System betreiben, realisiert über SPI. Der Raspberry als 
Master würde den ATmegas Befehle erteilen und Rückgabewerte empfangen - 
quasi eine light-Version eines verteilten Systems.
Ein Befehl könnte als remote-Aufruf einer C-Funktion realisiert werden, 
ggf auch als Kommunikation über (virtuelle) Register, wie bei Sensoren 
(z.B. BME280). Sahnetüpfelchen wäre die Redefinition der Arduino 
Serial-Libary mit Verwendung dieses Kanals statt UART. Das spart 
Leitungen, außerdem könnte man bei geschickter Programmierung dann 
Serial.Write() auch im Interrupt verwenden.

Problem: die unzähligen Tutorials im Internet schieben 1-2 Bytes über 
die Leitung. Man freut sich, wenn eine LED leuchtet oder ein Byte 
zurückkommt. Die Libraries für dedizierte Sensoren machen letztlich auch 
nicht viel mehr.
Was fehlt, ist eine Art OSI-Modell für SPI.
Kennt da jemand was in diese Richtung?  Würde ungern das Rad neu 
erfinden. Alles ist willkommen, was mehr tut als nur 1 oder 2 Bytes zu 
schieben.

Grund für SPI: Verbindung ist bereits vorhanden, da ich die ATmegas 
darüber mit avrdude auf dem Raspberry Pi programmiere. Das Projekt 
könnte natürlich auch über I2C oder UART realisiert werden, aber die 
Problematik bleibt die gleiche.

Gruß,
 Felix

: Verschoben durch Admin
von Irgend W. (Firma: egal) (irgendwer)


Lesenswert?

Wenn du mit "die ATmegas" diese in mehrzahl meinst hast du erstmal der 
problem mit dem Chip-Select signal mit dem die die einezelen salves 
geziehlt aktivieren/deaktivieren musst. Da kommen ganz schnell eine 
ganzer büschel an leitungen zustande.
I2C kennt dagegen z.B. sowas wie Adressierung  wenn mehrere Geräte 
gleichzeitig dran hängen.
Und UART(RS232/RS428) wird interessant wenn die Leitung mehr als einige 
cm haben soll usw.
Kommt also sehr genau darauf an was du tatsächlich machen willst und was 
dafür am geeignetzten ist. "Ist schon da" ist da eher ein schlechter 
Ratgeber (zumal selbst hierfür noch einiges fehlen dürfte).

von Name: (Gast)


Lesenswert?

Es kommt drauf an wie weit verteilt. SPI ist elektrisch ungünstig, weil 
es taktsynchron ist und viele Leitungen hat.
Ich würde einen bestehenden Bus verwenden, dazu mal nach Feldbus 
googlen.

Wozu das Rad neu erfinden?

von Felix (Gast)


Lesenswert?

Name: schrieb:
> Es kommt drauf an wie weit verteilt.

Nicht sehr weit verteilt. Die Geräte sitzen in einem Gehäuse, vielleicht 
10-20 cm Leitung. Eigentlich habe ich auch nur einen ATmega verbunden, 
würde es nur gerne für die Zukunft offen lassen. Bzw. soll sich der 
SPI-Bus auch für weitere Sensoren oder Displays nutzen lassen.

Den Hardware-Aspekt würde ich gerne erstmal beiseite lassen. Die 
SPI-Probleme lassen sich lösen. Daisy-chaining wäre möglich, da ich ja 
selbst die ATmega-Slaves konzipiere. Dann hat Mikrochip z.B. beim 
MCP23008 ein ganz interessantes Konzept, bei dem auch für SPI eine 
Geräte-Adresse verwendet wird. Ist mir aber egal, denn momentan reicht 
erstmal eine 1:1 Verbindung und Umstieg auf ein anderes Bussystem wäre 
ja jederzeit möglich.

Mir geht es um "höherwertige Protokolle" auf einem Bus. Was gibt es da?

Gefunden habe ich https://github.com/openmv/openmv-arduino-rpc, einen 
recht flexiblen Ansatz in diese Richtung. Würde ich wohl weiter 
verfolgen. Ist mir allerdings schon fast zu flexibel. Wenn mir jemand 
sagt, schau Dir Projekt XY an, da ist Dein Beispiel schon realisiert, 
dann wäre ich dankbar.

von Felix (Gast)


Lesenswert?

Irgend W. schrieb:
> "Ist schon da" ist da eher ein schlechter
> Ratgeber

Grundsätzlich absolut richtig. Wenn es um wirklich viele Geräte geht, 
größere Entfernung, Funkverbindung etc. , dann werde ich wohl umdenken 
müssen.

Nun ist es aber so, dass ich einen Versuchsaufbau habe, bei dem die 
SPI-Verbindung da ist und funktioniert. Das würde ich gerne nutzen, um 
das Softwareproblem "höherwertiges Protokoll" zu lösen, denn dieses 
besteht ja bei allen Verbindungen. Es bringt mir wenig, jetzt die 
Hardware zu optimieren und den Usecase "LED einschalten" für 100 LEDs in 
Australien stabil zu kriegen. Dann bastele ich noch Monate weiter und 
bin beim Problem der verteilten Programmierung keinen Schritt weiter 
gekommen.

von Oliver S. (oliverso)


Lesenswert?

ATmega als SPI Slave ist schon mal keine gute Idee.

Ansonsten ist das schöne am OSI-Modell ja, daß das in Schichten 
aufgebaut ist. Da musst du nur die Transportschicht auf SPI umstricken 
;)

Oliver

: Bearbeitet durch User
Beitrag #6567606 wurde von einem Moderator gelöscht.
von Cyblord -. (cyblord)


Lesenswert?

Felix schrieb:
> Was fehlt, ist eine Art OSI-Modell für SPI.

Das fehlt sicher nicht. SPI bildet die unterste Ebene der Kommunikation 
ab. Du kannst fast jedes höhere Protokoll damit nutzen. Es braucht kein 
höheres Protokoll nur für SPI.
Ob SPI hier aber sinnvoll ist, steht auf einem anderen Blatt.

Beitrag #6567625 wurde von einem Moderator gelöscht.
von Felix (Gast)


Lesenswert?

Oliver S. schrieb:
> ATmega als SPI Slave ist schon mal keine gute Idee.

Warum? Das wird oft in Foren behauptet. Aber einen stichhaltigen Beleg 
dafür habe ich noch nicht gefunden.

von Cyblord -. (cyblord)


Lesenswert?

Felix schrieb:
> Oliver S. schrieb:
>> ATmega als SPI Slave ist schon mal keine gute Idee.
>
> Warum? Das wird oft in Foren behauptet. Aber einen stichhaltigen Beleg
> dafür habe ich noch nicht gefunden.

Warum probierst du es nicht einfach aus?

Du behauptest viel und bist sehr von allem überzeugt. Das TU es einfach.

Programmierung eines SPI Slave ist eben eine Nummer schwieriger als ein 
Master. Man muss die Zustände besser im Auge haben und man muss ständig 
Daten bereit halten, falls der Master etwas lesen möchte.

Natürlich kannst du zwischen einem Pi und einem ATMega alles per SPI 
machen. Nur es ist nicht optimal und du wirst einiges rumprobieren 
müssen.

Als erstes wäre zu prüfen ob ein verteiltes System notwendig ist. Der 
Aufwand und die Komplexität steigen schnell. Ohne Not würde ich das 
nicht machen.

Einen ATMega als Subcontroller für spezielle Aufgaben lässt sich noch 
gut machen. Ein eher allgemein gehaltenes verteiltes System nicht mehr.

Dafür gibts auch kein Kochrezept. Etablierte höhere Protokolle tun auch 
nicht alles für dich. Du kannst damit vielleicht Adressierung und 
Fehlererkennung und Retry usw. realisieren. Aber am Ende überträgst du 
immer noch Bytes und was die bedeuten wirst du dir selbst ausdenken und 
ausprogrammieren müssen.

Also bitte bitte bitte, wenn du denkst du bist der coole Frood und 
kannst das und weißt das besser, dann mach doch einfach und laber hier 
nicht rum.

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Felix schrieb im Beitrag #6567625:

> Immerhin ist der SPI-Bus der vom
> ATmega-Hersteller vorgesehene Bus zur Programmierung des Chips.

Nein, das ist natürlich nicht der Fall. Zur Programmierung benutzt man 
ISP, das ist was anderes als SPI und insbesondere auch kein Bus 
(höchstens, wenn man RST im Sinne von CS benutzt).

Bei vielen AVR8 sind (neben CS, was sowieso nie passt) auch die anderen 
Anschlüsse nicht identisch. Bei den Tinys sind MOSI und MISO getauscht, 
bei einigen Megas liegen sie sogar auf völlig anderen Pins als SPI.

Sprich: du hast absolut keine Ahnung, davon aber eine ganze Menge...

Beitrag #6569176 wurde von einem Moderator gelöscht.
von Felix (Gast)


Lesenswert?

c-hater schrieb:
> Nein, das ist natürlich nicht der Fall. Zur Programmierung benutzt man
> ISP, das ist was anderes als SPI...
>
> Sprich: du hast absolut keine Ahnung, davon aber eine ganze Menge...

Tut mir leid, bin noch relativer Einsteiger beim ATmega. Hatte mich halt 
auf Atmels Datasheet vom ATmega328p verlassen, die gleich auf einer der 
ersten Seiten schreiben "The on-chip ISP flash allows the
program memory to be reprogrammed in-system through an SPI serial 
interface..." Dank Deines Rates weiß ich jetzt also, dass das falsch 
ist, vielen Dank für die Hilfe.

von Felix (Gast)


Lesenswert?

Cyblord -. schrieb:
> Also bitte bitte bitte, wenn du denkst du bist der coole Frood und
> kannst das und weißt das besser, dann mach doch einfach und laber hier
> nicht rum.

Möchte ich natürlich sein und deswegen bastele ich daran weiter statt 
noch mehr zu schreiben. Bisher läuft der ATmega sehr gut als SPI-Slave, 
aber halt nur Byte-für-Byte. Werde das wie oben angedeutet aufbohren.

Falls es jemand inhaltlich interessiert, hier zwei recht 
vielversprechende Projekte dazu:
https://simplerpc.readthedocs.io/en/latest/
https://github.com/openmv/openmv-arduino-rpc

Wenn was bei rauskommt, werde ich das Ergebnis vorstellen.

Beitrag #6569963 wurde vom Autor gelöscht.
von Philipp B. (philipp_b993)


Lesenswert?

Wenn du schon du schon von "höherwertiges Protokoll" sprichst, warum 
nimmst du nicht einfach nen W5100?
Dann hast du dein SPI und kannst auch viele andere Geraete ansprechen.
Dann kannst du frei UDP,TCP, raw MAC oder raw IP machen. CAT5/6/7 Kabel 
bekommst du wie Sand am Meer und die sind auch guenstig. All deine 
Probleme waeren geloest. Dann koenntest du sogar dieses "IoT" relativ 
einfach umsetzen ^^

: Bearbeitet durch User
von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Oliver S. schrieb:
> ATmega als SPI Slave ist schon mal keine gute Idee.
Schon SPI an sich ist zur Kommunikation zwischen unabhängigen Modulen 
ungeeignet.

Und besonders dann, wenn einer ganz naiv "erst" mit SPI ein Kommando an 
einen Slave schickt, und sofort "danach" die Antwort vom Slave abholen 
will.
Denn dann wird 1. der ganze Bus nur halbduplex gefahren und 2. muss der 
Slave "in kürzester Zeit"  a) das Kommando abholen, b) das Kommando 
auswerten und c) das Ergebnis zur Übertragung bereitstellen.
"In kürzester Zeit" bedeutet hier bei den meisten Anfängerentwürfen "nur 
1 SPI-Taktzyklus".

Ein brauchbarer Bus zur Übertragung von Daten zwischen zwei 
"intelligenten" Geräten ist ein RS232, RS422 oder RS485 Bus. Die ersten 
beiden sind sogar vollduplex.

von Felix (Gast)


Lesenswert?

Lothar M. schrieb:
> Schon SPI an sich ist zur Kommunikation zwischen unabhängigen Modulen
> ungeeignet.

Das stimmt sicherlich, nur sind meine Module nicht wirklich unabhängig.

Vielleicht habe ich mein Szenario nicht präzise genug dargestellt. Ich 
möchte das Problem ja gar nicht allgemein lösen, d.h. Kommunikation und 
Jobverteilung zwischen beliebig vielen autonomen Modulen in einem 
physikalisch verteilten Netz.

Ich möchte einen Raspberry Pi Zero für ein Robotics-Project als 
Steuerung nutzen. Mit seinem WLAN kann er gut kommunizieren, sein 
Betriebssystem erlaubt mir die Installation von allerlei nützlichen 
Tools. Um ihn zu entlasten und echtzeitfähiger zu machen, habe ich ihm 
eine Platine mit einem ATmega als Unterkontroller aufgesteckt. Der 
ATmega steuert die Motoren und fragt deren Hall-Sensoren ab. PI und 
ATmega sind per SPI verbunden, weil ich das zur Programmierung des 
ATmega nutze. Deswegen die Idee, den SPI-Bus gleich zum Datenaustausch 
zu nutzen - der Datenaustausch ist bisher nicht befriedigend gelöst. Die 
Lösung würde ich gerne so bauen, dass noch ein zweiter oder vielleicht 
dritter ATmega als Unterkontroller eingebaut werden kann.

Das Duplex-Problem werde ich mit getrennten Schreib/Lese-Puffern lösen 
und  das Protokoll zum Datenaustausch so gestalten, dass Warten möglich 
ist (Software-Handshaking). Der Master würde also nicht sofort die 
Antwort erwarten, sondern erstmal eine Reihe von Nullen akzeptieren. In 
einem SPI-Taktzyklus brauchen dann nur die Puffer gelesen oder 
beschrieben zu werden.

RS232 bzw. der serielle Port wäre auch eine Möglichkeit. Ich könnte 
damit den ATmega auch programmieren, wenn ich einen Bootlader verwende. 
Allerdings ist mir hier nicht klar, wie ich einen zweiten ATmega 
reinbringen könnte.


Ganz allgemein habe ich gerade die Befürchtung, dass mir 
interrupt-gesteuerte Kommunikation die Messung der Hall-Sensoren kaputt 
machen könnte. Für die Sensoren muss ich 80µs auflösen können, gemessen 
per Pin-Interrupt. Wenn ich diese Interrupts durch höher priorisierte 
Kommunikations-Interrupts unterbreche, ist die Messung kaputt. Umgekehrt 
würde ein hoch priorisierter Mess-Interrupt den Kommunikations-Interrupt 
stören. Hier wäre ein Kommunikationsverfahren besser, das ich ohne 
Interrupt in der Loop-Routine machen kann. Könnte ein Argument gegen SPI 
sein...

von Felix (Gast)


Lesenswert?

Philipp B. schrieb:
> warum nimmst du nicht einfach nen W5100?

Weil für meinen Anwendungsfall (siehe letzter Beitrag) die Integration 
dieses Chips die Komplexität des Gesamtaufbaus übersteigen würde. Im 
allgemeinen Fall wäre das aber in der Tat eine gute Empfehlung. Sorry, 
falls ich mein Problem nicht präzise genug beschrieben habe.

von 100Ω W. (tr0ll) Benutzerseite


Lesenswert?

Warum nimmst du nicht einfach Modbus?

von Cyblord -. (cyblord)


Lesenswert?

100Ω W. schrieb:
> Warum nimmst du nicht einfach Modbus?

Das ändert erst mal wenig. Modbus arbeitet mit virtuellen Registern, die 
man lesen und schreiben kann. So arbeiten viele SPI Slaves auch. Das ist 
ohne großen Aufwand realisiert. Löst das Problem des TE aber auch nicht.

von (prx) A. K. (prx)


Lesenswert?

Zu den Schwachpunkten der AVRs gehört dessen SPI-Modul. Traditionell hat 
es zwar einen vom Shift-Register getrennten Receive-Buffer, aber keinen 
Transmit-Buffer. Antworten an den Master kann der Slave also nur in 
Pausen zwischen den Byte-Transfers ins Shift-Register schreiben. Der 
Master muss folglich das worst-case Timing des AVR bei der Reaktion auf 
SPI-Transfers in sein eigenes Zeitverhalten einrechnen.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Felix schrieb:
> der Datenaustausch ist bisher nicht befriedigend gelöst.

Genau das ist das Problem bei Anfängern, sie stellen sich eine 
zuverlässige Kommunikation popeleinfach vor. Erfahrene Programmierer 
nehmen mehrere MCs erst dann, wenn es wirklich nicht anders geht.

Felix schrieb:
> Ganz allgemein habe ich gerade die Befürchtung, dass mir
> interrupt-gesteuerte Kommunikation die Messung der Hall-Sensoren kaputt
> machen könnte.

Diese Befürchtung ist voll berechtigt. Und genau deshalb ist SPI-Slave 
bei den AVRs ganz großer Mist.
Nimm I2C, das streckt automatisch den Takt, solange der Slave nicht 
bereit ist. Der Slave kann also alle wichtige Echtzeit ohne Rücksicht 
auf die Kommunikation machen.
Der Slave kann auch temporär sein I2C disablen, dann kriegt der Master 
ein NACK auf die Adresse. Der Master weiß also immer, ob ein Transfer 
geklappt hat. Ganz im Gegensatz zum SPI.

Felix schrieb:
> Der Master würde also nicht sofort die
> Antwort erwarten, sondern erstmal eine Reihe von Nullen akzeptieren.

Der Master liest aber keine Nullbytes, sondern Mumpitz, wenn der Slave 
nicht schnell genug ist.
Der Slave kriegt ein Kollisionsbit, wenn er erst im Transfer das 
Sendebyte schreibt. Nur kann sich der Master dafür nichts kaufen. Er muß 
durch höhere Protokolle den Mumpitz erkennen, alles nochmal anfordern 
und hoffen, daß es diesmal klappt.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Peter D. schrieb:
> Der Master liest aber keine Nullbytes, sondern Mumpitz, wenn der Slave
> nicht schnell genug ist.

SPI ist zur Kommunikation zwischen 2 softwaregesteuerten Modulen 
ungünstig, weil der Master dem Slave (s)einen externen Takt bzw. Zyklus 
aufzwingt. Der Slave muss also immer für einen Empfang bereit sein, 
gleich auch noch passende Sendedaten bereithalten und so seine 
eigentliche "Echtzeitarbeit" für die Kommunikation unterbrechen.

Bei einer simplen Hardwarekomponente wie einem Schieberegister, das 
jederzeit angesteuert werden kann, ist SPI aber ein toller Bus ohne viel 
Protokolloverhead: SS# aktivieren und lostakten. Einfacher geht es kaum.

: Bearbeitet durch Moderator
von H. (Gast)


Lesenswert?

Lothar M. schrieb:
> Der Slave muss also immer für einen Empfang bereit sein,
> gleich auch noch passende Sendedaten bereithalten und so seine
> eigentliche "Echtzeitarbeit" für die Kommunikation unterbrechen.

Das ist DER zentrale Kern überhaupt, den man als Anfänger meist nur 
schwer nachvollziehen kann. Man denkt, der SPI ist doch bidirektional, 
jeder Teilnehmer kann lesen und schreiben. Die Synchronisierung der 
Datenhaltung zwischen den Teilnehmern wird zum Hauptproblem.

Ein übergeordnetes Kommunikationsprotokoll kann genau das nicht lösen, 
da die Anwendungsfälle zu unterschiedlich sind.

Ein wirklich schönes Protokoll für eine Multiprozessorarchitektur ist 
CAN, da muss man sich in der Anwendungsebene schon mal weniger um die 
eigentliche Kommunikation kümmern. Mittlerweile in vielen CPUs drin und 
einfach handzuhaben.

von (prx) A. K. (prx)


Lesenswert?

Peter D. schrieb:
> Nimm I2C, das streckt automatisch den Takt, solange der Slave nicht
> bereit ist.

Bei den RasPis funktioniert das leider nicht. Bug. Mindestens nicht bei 
den Versionen 1 und 2. Ob das bei den neuen behoben ist, weiss ich 
nicht.

: Bearbeitet durch User
von Felix (Gast)


Lesenswert?

(prx) A. K. schrieb:
> Bei den RasPis funktioniert das leider nicht.

Der Meinung bin ich auch. Bis zu meinen SPI-Versuchen hatte ich I2C im 
Einsatz. Es hat leidlich funktioniert, war aber nie absolut stabil. 
Außerdem kann der ATmega dann nicht selber als Master agieren um 
I2C-Sensoren einzubinden. Deswegen will ich davon weg.

von Maxe (Gast)


Lesenswert?

Felix schrieb:
> Oliver S. schrieb:
>> ATmega als SPI Slave ist schon mal keine gute Idee.
> Warum? Das wird oft in Foren behauptet. Aber einen stichhaltigen Beleg
> dafür habe ich noch nicht gefunden.

Den AVRs fehlt der DMA.
SPI ist eigentlich eine gute Schnittstelle, die hohe Datenraten 
ermöglicht, wo I²C, CAN usw. lange nicht mitkommen. Das Problem ist 
eben, wie einige hier schon geschrieben haben, dass die Daten auch im 
richtigen Moment geliefert werden können müssen.

So wie ich das kenne, sendet der Master einen (Lese-) Befehl mit ein 
paar Byte, darin ist auch die Datenlänge zum Lesen kodiert. Der Master 
wartet dann eine feste Zeit, bis er die Lesevorgänge startet. In dieser 
Zeit muss der Slave seinen Interrupt ausführen, den Befehl dekodieren, 
die Daten im RAM bereitstellen und den DMA darauf konfigurieren. Wenn 
der Master dann zum Lesen lostaktet, kümmert sich der DMA um den 
Datennachschub. Die Zeit die der Master wartet zwischen Lesebefehl und 
Lesevorgang, richtet sich eben danach, wie lange der Slave für die 
Datenbereitstellung braucht. Also wenn deine Messung einen Interrupt mit 
höherer Priorität hat (Interrupt-Prioritäten gibts beim AVR auch nicht), 
spielt die auch in die Wartezeit rein. Eine ADC-Messung anzustoßen 
sollte aber in ein paar Takten vonstatten gehen und auch die Ergebnisse 
in einen Puffer wegzuschreiben geht schnell, nur muss man das Anstoßen 
und Auslesen dann in getrennten Interrupts durchführen und kann nicht im 
Interrupt blockierend auf das Ergebnis warten.
D.h. insgesamt setzt das auf der Slaveseite eine genaue Planung des 
Aufbaus und der Latenzen voraus.

Prinzipiell finde ich es immer gut, sich an anspruchsvollere Themen zu 
wagen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Angehängte Dateien:

Lesenswert?

Maxe schrieb:
> So wie ich das kenne, sendet der Master einen (Lese-) Befehl mit ein
> paar Byte, darin ist auch die Datenlänge zum Lesen kodiert. Der Master
> wartet dann eine feste Zeit, bis er die Lesevorgänge startet.
Genau diese "Warten" ist Murks.

Ein gutes SPI-Protokoll sendet jetzt z.B. ein 16-Bit langes Kommando 
und bekommt gleichzeitig 16 Bit vom vorherigen Kommando als Antwort 
zurück. Der AD7490 ist ein gutes Beispiel dafür (siehe Screenshot). Dann 
nutzt man wenigstens ansatzweise die volle Bandbreite des Busses aus.

von Felix (Gast)


Lesenswert?

(prx) A. K. schrieb:
> Zu den Schwachpunkten der AVRs gehört dessen SPI-Modul. Traditionell hat
> es zwar einen vom Shift-Register getrennten Receive-Buffer, aber keinen
> Transmit-Buffer. Antworten an den Master kann der Slave also nur in
> Pausen zwischen den Byte-Transfers ins Shift-Register schreiben. Der
> Master muss folglich das worst-case Timing des AVR bei der Reaktion auf
> SPI-Transfers in sein eigenes Zeitverhalten einrechnen.

Habe ich nicht ganz verstanden. Ich schreibe als Slave entweder Nullen 
zurück (wenn der Puffer leer ist) oder übertrage den Puffer 
Byte-für-Byte. Das mache ich direkt im Interrupt, schreibe also sofort 
nach Auslesen von SPDR das Sendebyte in SPDR.
Laut Datasheet sollte es auch umgekehrt gehen, dann sollte also nichts 
mehr schief gehen: The slave may continue to place new data to be sent 
into SPDR BEFORE reading the incoming data. The last incoming byte will 
be
kept in the buffer register for later use.

Ich habe es ausprobiert: Ab einer bestimmten Baudrate (etwa 115200) gibt 
es den zu erwartenden Bitsalat, darunter läuft es absolut stabil. Auf 
der physikalischen Ebene habe ich also keine Probleme, außer 
Zeitkonflikte mit meiner Messung (was natürlich ein ko-Kriterium sein 
könnte).

von (prx) A. K. (prx)


Lesenswert?

Felix schrieb:
> Das mache ich direkt im Interrupt, schreibe also sofort
> nach Auslesen von SPDR das Sendebyte in SPDR.

Und du hast dafür genau so viel Zeit, bis der Master das nächste 
Taktsignal liefert. Wenn das immer reicht - kein Problem. Sobald du zu 
spät dran bist, weil ein anderer Interrupt schneller dran war, ist das 
SPDR blockiert und der Master kriegt sein eigenes Byte retour.

: Bearbeitet durch User
von Cyblord -. (cyblord)


Lesenswert?

Felix schrieb:
> Habe ich nicht ganz verstanden. Ich schreibe als Slave entweder Nullen
> zurück (wenn der Puffer leer ist) oder übertrage den Puffer
> Byte-für-Byte.

Und woher weiß der Master ob die Nullbytes nun nicht vielleicht 
Nutzdaten sind?
Du brauchst mindestens einen Header vor den Nutzdaten.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Felix schrieb:
> Ab einer bestimmten Baudrate (etwa 115200) gibt es den zu erwartenden
> Bitsalat

Wenn ich SPI höre, dann denke kommen mir Taktraten um und über 2MHz in 
den Sinn. Der obige AD7490 kann  z.B. bis zu 20MHz. Dort ist der SPI 
zuhause und dort gehört er hin.

> darunter läuft es absolut stabil.

Das ist sowas wie "immer" und "nie". Solche Begriffe verwende ich nur 
überaus ungern und wenn ich mir wirklich sicher bin. Weißt du sicher, 
warum es einen Bitsalat gibt, wenn es mal nicht "absolut stabil" 
läuft? Denn nur, wenn du das sicher weißt, kannst du wissen, dass es 
"absolut stabil" laufen wird.

: Bearbeitet durch Moderator
von Peter D. (peda)


Lesenswert?

Felix schrieb:
> Das mache ich direkt im Interrupt

Genau das ist der Knackpunkt, Du mußt rechtzeitig in den Interrupt 
kommen und den Prolog abgearbeitet haben.
Es dürften also keine weiteren Interrupts enabled sein, bzw. es muß 
genug Zeit vom Master gewartet werden, um diese abzuarbeiten.

Felix schrieb:
> Ich habe es ausprobiert:

Ja aber nur, wenn Deine Applikation sonst nichts weiter zu tun hat.

Z.B. wenn man den SCK auf 1kHz runter setzt, dann hat der Slave ein 
Zeitfenster von 500µs, um andere Interrupts zu beenden und das 
SPI-Register zu füllen.

von (prx) A. K. (prx)


Lesenswert?

Felix schrieb:
> (prx) A. K. schrieb:
>> Bei den RasPis funktioniert das leider nicht.
>
> Der Meinung bin ich auch.

http://www.advamation.de/technik/raspberrypi/rpi-i2c-bug.html

von Felix (Gast)


Lesenswert?

Eine Sammelantwort

> Du brauchst mindestens einen Header vor den Nutzdaten.

Das ist eingeplant. Nutzdaten werden eine Transaktionsnummer bekommen 
(um die Antwort zuordnen zu können), Längenangabe und mit einer Checksum 
enden.

> Weißt du sicher, warum es einen Bitsalat gibt, wenn es mal nicht "absolut 
stabil" läuft?
Nicht wirklich genau. Wenn das mit der Checksum fertig ist, kann ich 
einen Massentest machen. Bisher kann ich es nur auf Basis von wenigen 
hundert Byte und ohne weitere Interrupts sagen. Werde es aber auch 
nochmal mit dem Oszilloskop ansehen, z.B. einen Ausgabepin im Interrupt 
toggeln und mit SCLK vergleichen. Bzw. mal überschlagen, wie lang der 
Code der Interrupt-Routine dauert.


>Wenn ich SPI höre, dann denke kommen mir Taktraten um und über 2MHz in den Sinn
Mein ATmega läuft mit 8MHz (wegen 3.3V Spannung). Aber der Unterschied 
ist in der Tat groß. Da habe ich noch keine Erklärung... Clock-Divider 
sollten nicht gesetzt sein.



> wenn man den SCK auf 1kHz runter setzt, dann hat der Slave ein
Zeitfenster von 500µs,
Damit muss ich noch experimentieren, mit dem Zusammenspiel Messung und 
Kommunikation habe ich noch keine Erfahrung.

Was ich mich dazu frage: Welches Kommunikationsverfahren würde mir denn 
bei diesem Problem helfen? I2C und USART sind vielleicht nicht so 
Ressourcen-intensiv, aber da kommen ja auch Interrupts, nur nicht so 
oft. Ob mir so ein Interrupt ständig in die Messung reingrätscht oder 
nur manchmal, ist dann auch fast egal. Ideal wäre ein 
Kommunikationsverfahren, das ganz ohne Interrupts auskommt (da ich sie 
wohl beim ATmega nicht priorisieren kann).

von Maxe (Gast)


Lesenswert?

Lothar M. schrieb:
> Maxe schrieb:
>> So wie ich das kenne, sendet der Master einen (Lese-) Befehl mit ein
>> paar Byte, darin ist auch die Datenlänge zum Lesen kodiert. Der Master
>> wartet dann eine feste Zeit, bis er die Lesevorgänge startet.
> Genau diese "Warten" ist Murks.
>
> Ein gutes SPI-Protokoll sendet jetzt z.B. ein 16-Bit langes Kommando
> und bekommt gleichzeitig 16 Bit vom vorherigen Kommando als Antwort
> zurück. Der AD7490 ist ein gutes Beispiel dafür (siehe Screenshot).

In Hardware, ja. Aber bei einem Mikrocontroller als Slave bleibt das 
Problem das gleiche, also dass dieser bis zum nächsten Befehl die Daten 
vorbereiten muss. Das gilt aber letztlich für jede Schnittstelle, der 
Teilnehmer muss ja erst wissen, was die Gegenstelle von ihm verlangt, 
bevor er antworten kann. Der einzige Unterschied beim SPI ist, dass das 
Timing vom Master vorgegeben wird.

> Dann nutzt man wenigstens ansatzweise die volle Bandbreite des Busses aus.

Da gehts doch gar nicht drum? Ein Raspi soll mittels angestöpseltem 
Mikrocontroller echtzeitfähig gemacht werden, ich denke SPI bietet sich 
da durchaus an. UART wäre einfacher, ist aber langsamer.

von Maxe (Gast)


Lesenswert?

Nachtrag: Und gerade bei mehreren Slaves kann der Master die Wartezeit 
bis die Antwort bereit ist, sinnvoll nutzen: Er schickt allen Slaves der 
Reihe nach den Befehl und holt anschließend jeweils die Daten der Reihe 
nach ab.

von (prx) A. K. (prx)


Lesenswert?

Es könnte sinnvoll sein, die vom Master alle an einen Slave gesendeten 
Bytes stets von denen unterscheiden zu können, die vom Slave zurück 
kommen können. Dadurch wird erkennbar, dass ein Master sein eigenes 
Geschwätz retourniert bekommt, statt der gewünschten Antwort.

: Bearbeitet durch User
von Cyblord -. (cyblord)


Lesenswert?

Man muss eine grundsätzliche Registerarchitektur durchziehen. D.h. die 
Applikation kann jederzeit (das muss entsprechend gesynct oder gelockt 
werden), Daten in beliebige "Register" schreiben und daraus lesen.

Ein SPI Handler reagiert auf Anfragen des Masters und liest und schreibt 
diese Register die anhand einer Adresse spezifiziert werden.

Damit kann der SPI Interrupt schnell genug sein, und er arbeitet immer 
gleich und kümmert sich nicht um Zustände der Applikation.
Auch muss er die Daten nicht erst beschaffen oder berechnen.

Für den Fall dass ein Register gerade gelockt ist, muss ein Fehler 
übermittelt werden und der Master kann es nochmal versuchen.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Maxe schrieb:
> Er schickt allen Slaves der Reihe nach den Befehl und holt anschließend
> jeweils die Daten der Reihe nach ab.

Genau das "erst Schreiben und später Lesen" ist ja das Unsinnige, denn 
dadurch ist der Bus bestenfalls zur Hälfte "ausgelastet", weil der Bus 
immer nur Hablduplex verwendet wird, denn es ist zu jedem Zeitpunkt der 
Übertraung eine der beiden Leitungen unnötig, weil sie zu diesem 
Augenblick keine brauchbare Information überträgt.

Der eigentliche Witz am SPI ist das gleichzeitige Schreiben und Lesen: 
mit jeder Taktflanke wird zugleich 1 Bit gesendet und 1 Bit empfangen. 
Wenn man das nicht braucht oder keinen Vorteil daraus gewinnen kann, 
dann nimmt man besser einen anderen Bus.

: Bearbeitet durch Moderator
von Cyblord -. (cyblord)


Lesenswert?

Lothar M. schrieb:
> Der eigentliche Witz am SPI ist das gleichzeitige Schreiben und Lesen.
> Wenn man das nicht braucht oder keinen Vorteil daraus gewinnen kann,
> dann nimmt man besser einen anderen Bus.

Richtig. In diesem Fall würde sich I2C eher anbieten. Dann hat man auch 
gleich Adressierung und spart sich Leitungen.
Das Registerkonzept kann man hingegen genau gleich implementieren.

: Bearbeitet durch User
von Matthias L. (Gast)


Lesenswert?

>Ein Raspi soll mittels angestöpseltem
>Mikrocontroller echtzeitfähig gemacht werden

Dann solltest Du auch die übliche Vorgehensweise (TM, James Bond) 
nutzen:

Der PI koordiniert, verteilt Aufgaben und wartet die Ergebnisse ab. Die 
µC machen die ganze Echtzeitarbeit.

Somit ist das erste Kriterium, nichts zeitkritisches über die 
Kommunikation laufen zu lassen. Wenn Du zb eine Regelung brauchst, ist 
die komplett im Slave (µC) gelöst. Der Pi schickt nur den Sollwert hin. 
Und das nicht zyklisch, sondern wenn nötig. Abfragen macht er, wenn er 
etwas wissen will. Die Antwort erfolgt dann "zeitnah". Das dasrf im Pi 
keinierlei Probleme auslösen. Sollte es auch nicht, denn es wird ja 
nichts zeitkritisches gemacht. (also zb Istwerte nur angezeigt und 
Sollwerte verstellt)

Für diese Art Kommunikation würde ich wegen bereits erklärter Nachteile 
weder SPI noch I2C ansetzen. Mein erster Gedacnke wäre seriell: RS232 
oder RS422/485 je nach Länge der Kabel und nötiger/gewünschter 
Datenrate.

Das Protokoll wäre so designed, das die Datenmenge pro Übertragung 
(natürlich immer nur zu einem Slave) variable Längen hat. Das Protokoll 
könnte etwa so aussehen:
Byte0: Adresse_des_Partners
Byte1: eigene_Adresse (nötig für evtl. Antwort)
Byte2: Länge der dann folgenden Nutzdaten
Byte3..N: Nutzdaten
ByteN+1: Prüfsumme
(Nutzdatenlänge Null wäre somit denkbar, dann würden vier Bytes 
übertragen)

Die Zieladresse als erstes erlaubt Dir (bei den AVRs) den 
MultiProcessorCommunicationMode zu nutzen. Da wird schon etwas per 
Hardware wegefiltert und Deine Empfangsrouting muss nur die Adresse 
prüfen und die Bytes, die wirklich für einen selbst sind. (alle anderen 
werden durch die Hardware verworfen). Dann kann per state machine ( also 
nebenbei neben dem Echtzeitteil) in aller Ruhe die Meldung ausgewertet, 
die ANtwort zusammengebaut und dem Sendepuffer übergeben werden.

Das ist ein vernünftiger Ansatz. Aber unterschhätze den nicht.

von Felix (Gast)


Lesenswert?

Matthias L. schrieb:

So langsam leckt das Forum Blut :-)

> Der PI koordiniert, verteilt Aufgaben und wartet die Ergebnisse ab. Die
> µC machen die ganze Echtzeitarbeit.
Genauso ist das geplant, d.h. Notaus/Reset, Drehen, Geradeausfahrt mit 
Stoppbedingung, Positionsabfrage und Echolot wären Funktionsaufrufe. 
Damit würde der Raspberry die übergeordnete Regelung vorgehen mit 
Fernziel Kartenerstellung und -auswertung. Der ATmega macht 
Motorregelung, Hallsensorauswertung und Abfrage Infrarotsensoren autonom 
inklusive eventuellem Notstopp. Kommunikation ist also Prio2 gegen 
Messung und Steuerung.

> Für diese Art Kommunikation würde ich wegen bereits erklärter Nachteile
> weder SPI noch I2C ansetzen. Mein erster Gedacnke wäre seriell: RS232
> oder RS422/485 je nach Länge der Kabel und nötiger/gewünschter
> Datenrate.
SPI-Nachteile wurden genannt. Die Kabellänge beträgt aktuell 5 cm, das 
ist keine Problemquelle.
Aus meiner Sicht ungelöste Probleme bei USART: Einbinden eines weiteren 
ATmegas und die Tatsache, dass auch USART Interrupts auslöst. Die 
Messung wird potentiell also auch gestört, nur seltener.



> Das Protokoll könnte etwa so aussehen:
Geplant ist für Funktionsaufruf durch Master: Transaktions-ID (für 
Zuordnung Rückruf), Registeradresse (jede aufrufbare Funktion wird 
virtuell gegen ein Register gebunden beim Setup), Datenlänge, Payload, 
Checksum.
Das ist recht statisch, die ISV-Routine kann also das Ende der Nachricht 
leicht erkennen. Das eigentliche Parsen und Aufrufen wird dann aus dem 
Puffer in der loop gemacht.
Nach Beendigung sendet der Slave ein kurzes Acknowledge mit 
Transaktions-ID und Antwort-Payload im Erfolgsfall, bei Checksum-Fehler 
die Bitte um Wiederholung.

Das ganze ginge auch in Rückrichtung, d.h. Call durch den Slave, einfach 
in den gerade laufenden Traffic hinein (Konsequenz: Master muss alle 
paar Mikrosekunden pollen). Hier würde ich eine Device-ID vorsehen.
Unsicher bin ich beim Senden der eigenen Device-ID. Muss ein Empfänger 
wissen, von wem die Nachricht kommt? Potentiell wohl schon...

Ja, das wird wohl ein großes Projekt. Aber dank Corona sind die Abend 
frei...

von Oliver S. (oliverso)


Lesenswert?

Felix schrieb:
> Es hat leidlich funktioniert, war aber nie absolut stabil.
> Außerdem kann der ATmega dann nicht selber als Master agieren um
> I2C-Sensoren einzubinden. Deswegen will ich davon weg.

I2C ist per se vollständig multimasterfähig. Nur ist die Implementierung 
im AVR dazu leider nicht fehlerfrei.
Mit nur einem Master funktioniert das aber auch beim AVR stabil, wenn 
man es richtig macht,

Oliver

von Matthias L. (Gast)


Lesenswert?

>Die Kabellänge beträgt aktuell 5 cm

mal von den WOrt "aktuelL" abgesehen: Spielt keine Rolle. SPI oder I2C 
finde ich für Dein Problem weniger geeignet.


>Einbinden eines weiteren
>ATmegas und die Tatsache, dass auch USART Interrupts auslöst. Die
>Messung wird potentiell also auch gestört, nur seltener.

Die Priorität muss auf der Echtzeitaufgabe liegen. Somit würde diese nur 
für den Empfang der (für ihn bestimmten) Bytes unterbrochen. Und hier 
gibt es eine zulässige Reaktionszeit von einem Byte ggü einem Bit bei 
SPI. Denn das empfangene Byte muss nur aus dem UDR raus, bis das nächste 
fertig empfangen wurde. Weitere Aktionen sind im Interrupt nicht nötig.


>Transaktions-ID (für Zuordnung Rückruf), Registeradresse ...

Das wären bereits Nutzdaten nach meinem Beispiel.


>die ISV-Routine kann also das Ende der Nachricht leicht erkennen
Würde ich nicht machen. Das sollte rein durch die ANzahl der empfangenen 
Zeichen (deshalb wird die Länge weit vorn mitgeteilt) und einem Timeout 
geschehen. Das ist universeller wenn Du später Erweiterungen an einer 
Stelle machst. So brauchen die anderen nicht angefasst zu werden.


>Das eigentliche Parsen und Aufrufen wird dann aus dem Puffer in der loop 
>gemacht.Nach Beendigung sendet der Slave ein kurzes Acknowledge mit
>Transaktions-ID und Antwort-Payload im Erfolgsfall,

Richtig, weniger Prio als die Echtzeit.


>bei Checksum-Fehler die Bitte um Wiederholung.
.. oder anderen Fehlern einfach ein ErrorCOde verschieden GOOD 
zurücksenden (*)


>Das ganze ginge auch in Rückrichtung,

Klar. Ein Slave kann auch von allein einen Transmit anstossen (der 
Sendetreiber muss natürlich warten bis der Bus frei ist).


> d.h. Call durch den Slave, einfach in den gerade laufenden Traffic hinein

Hä? siehe "muss auf Bus frei warten"


>(Konsequenz: Master muss alle paar Mikrosekunden pollen).

Er muss sowieso empfangsbereit sein, denn er will ja hören. Alle µs? 
Kenne den Pi nicht, aber ich würde ich einen UART-Rx-Interrupt erwarten.


>Hier würde ich eine Device-ID vorsehen. Unsicher bin ich beim Senden der >eigenen 
Device-ID. Muss ein Empfänger wissen, von wem die Nachricht kommt? >Potentiell 
wohl schon...

Das ist die von mir genannte eigenen Adresse, die als zweites übertragen 
wird. DIese wird als Zieladresse bei der ANtwort eingesetzt.


(*) Somit würde ich das so machen:
Byte0: Adresse_des_Partners
Byte1: eigene_Adresse (nötig für evtl. Antwort)
Byte2: ErrorCode
Byte3: Länge der dann folgenden Nutzdaten
Byte4..N: Nutzdaten
ByteN+1: Prüfsumme

Ist ein Empfang fehlerhaft, erfolgt eine negative Antwort:
[0-Destination] ...
[1-Source] ich selbst
[2-ErrorCode]  Wert (verschieden Null), der den Fehlergrund angibt
[3- Länge Nutzdaten] NULL
Diese/Solche vier Bytes wären somit das kleinste zulässige Telegram.

von Frank K. (fchk)


Lesenswert?

Felix schrieb:

> Tut mir leid, bin noch relativer Einsteiger beim ATmega

Ja, das ist genau das Problem. Du hast einfach die falsche Hardware 
ausgesucht.

Schau mal wie die Profis es machen. Z.B. in der Automobilindustrie. Oder 
bei Baumaschinen. Oder in der Industrieautomation. Überall wird für so 
etwas CAN eingesetzt, und zwar aus gutem Grund:
- CAN ist relativ fix - bis 1MBit, bei CAN-FD noch deutlich mehr.
- CAN ist deterministisch - heißt also man kann vorher wissen, wie sich 
ein System verhält
- CAN macht sehr viel in Hardware, was Du anderswo in Software machen 
musst. Beispielsweise Warten bis der Bus frei ist. Prüfsummen erzeugen 
und vergleichen. Pakete bestätigen. Usw usw. Alles ohne 
Prozessoraufwand.
- CAN funktioniert. Das Zeugs ist seit 1990 millionenfach verbaut 
worden.

Willst DU Dir anmaßen, klüger als die Profis zu sein?

Also:
Als Master schlage ich einen Beaglebone vor. Der hat zwei CAN-Controller 
integriert. Ja, es gibt auch welche, die man am SPI anschließen kann. 
Die chipinternen haben aber viel weniger Overhead und kommen mit hoher 
Buslast besser zurecht.

Als Slaves nimmst Du z.B. Teensy 3.2. Die haben erstens einen viel 
leistungsfähigen Controller, CAN in Hardware eingebaut, und können 
trotzem per Arduino-IDE programmiert werden, wenn Du meinst, das 
unbedingt zu brauchen. Und trotzdem kann der noch 5V-Signale ab.

Du brauchst jeweils noch Transceiver. Das sind kleine 8-Pinner, die den 
Analogteil einer CAN-Schnittstelle darstellen. Je nachdem, wie schnell 
und wie lang Dein CAN-Bus sein soll, gibts verschiedene Transceiver.
Wenn Du 3.3V UND 5V zur Verfügung hast, ist der MCP2562 eine gute Wahl. 
Für ein reines 3.3V-System wäre z.B. der TCAN332 eine gute Wahl.

Für CAN gibts einen Haufen Literatur.

Für CAN gibts dann verschiedene High-Level-Protokolle wie CAN-Open, 
Devicenet, J1939 usw. Das sollte Deine Corona-Zeit durchaus füllen.

fchk

von MCUA (Gast)


Lesenswert?

> Zu den Schwachpunkten der AVRs gehört dessen SPI-Modul. Traditionell hat
> es zwar einen vom Shift-Register getrennten Receive-Buffer, aber keinen
> Transmit-Buffer.
Dürfte sich rumgesprochen haben, dass dieses Problem bei neueren gelöst 
ist.
Mehrere INT-Prio, DMA (FIFOs) fehlen dem AVR dennoch.

von (prx) A. K. (prx)


Lesenswert?

MCUA schrieb:
>> Zu den Schwachpunkten der AVRs gehört dessen SPI-Modul. Traditionell hat
>> es zwar einen vom Shift-Register getrennten Receive-Buffer, aber keinen
>> Transmit-Buffer.
> Dürfte sich rumgesprochen haben, dass dieses Problem bei neueren gelöst
> ist.

Deshalb schrieb ich "traditionell".

von c-hater (Gast)


Lesenswert?

MCUA schrieb:

> Mehrere INT-Prio, DMA (FIFOs) fehlen dem AVR dennoch.

Nö, die AVR128/64/32Dyy haben immerhin zwei echte Interrupt-Prioritäten, 
das dürfte für die allermeisten Anwendungen völlig ausreichend sein (mir 
hat i.A. eigentlich sogar die klassische eine praktisch immer gereicht).

DMA haben sie aber tatsächlich nicht.

von MCUA (Gast)


Lesenswert?

> Nö, die AVR128/64/32Dyy haben immerhin zwei echte Interrupt-Prioritäten,
Ja, man muss ws. nochmal 20 Jahre warten, bis welche dazu kommen.
Mit 2 Prio kann man nicht viel machen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Lothar M. schrieb:
> Der obige AD7490 kann  z.B. bis zu 20MHz. Dort ist der SPI zuhause und
> dort gehört er hin.

Da wird er übrigens auch schnell mal problematisch, wenn man ihn denn 
wirklich als Bus aufsetzen will.

Ich habe da schon mal unter die hochgebogenen Pins eines 144pinnigen 
Cortex-M7 noch 0201-Serienterminierungs-Widerstände eingelötet, weil der 
erste Entwurf das Thema ignoriert hatte. Allerdings war das SPI auf dem 
Board eben nicht mehr klassisch Punkt-zu-Punkt, sondern es hingen 
mehrere Devices dran, bis hin zum Controller, der selbst (mit zwei 
verschiedenen SPIs) beide Seiten bedient hat.

von c-hater (Gast)


Lesenswert?

MCUA schrieb:

> Mit 2 Prio kann man nicht viel machen.

Also ich konnte mit der klassischen einen eigentlich schon so ziemlich 
alles machen, was unterkam und nicht von vorherein zu "groß" für einen 
AVR8 aussah...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Jörg W. schrieb:
> Lothar M. schrieb:
>> Der obige AD7490 kann  z.B. bis zu 20MHz. Dort ist der SPI zuhause und
>> dort gehört er hin.
> Da wird er übrigens auch schnell mal problematisch, wenn man ihn denn
> wirklich als Bus aufsetzen will.
Ja, da ist es hilfreich, wenn man bedenkt, dass da dann doch so langsam 
HF anfängt. Und auch, welchen Zinnober um einzelne mm bei PCI mit seinen 
gerade mal 33MHz gemacht wurde.

> Ich habe da schon mal unter die hochgebogenen Pins eines 144pinnigen
> Cortex-M7 noch 0201-Serienterminierungs-Widerstände eingelötet
Schön, dass es sowas gibt, nicht wahr? Und sooo arg viele Beine sind es 
ja nicht...  ;-)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Lothar M. schrieb:
> Und sooo arg viele Beine sind es ja nicht...  ;-)

Zum Glück nur zwei: SCLK und MOSI. ;-) Aber man biegt diese Pins 
natürlich keine 32mal …

Gab ganz witzige Effekte: der Bus ist noch auf ein paar Mini-Stecker von 
JST rausgeführt, damit man zum Debuggen einen Logic Analyzer dran hängen 
kann. Mit LA funktionierte das System besser als ohne. :o  Am Ende 
landete am SCLK-Anschluss des Debug-Steckers noch ein kleiner Snubber.

von Peter D. (peda)


Lesenswert?

Jörg W. schrieb:
> Ich habe da schon mal unter die hochgebogenen Pins eines 144pinnigen
> Cortex-M7 noch 0201-Serienterminierungs-Widerstände eingelötet

Ich hab da auch schon schlechte Erfahrungen mit der Störempfindlichkeit 
von SPI machen müssen.

Bei I2C wird die slew-Rate begrenzt und die Eingänge gefiltert.
Und bei der UART erfolgt eine Dreifachabtastung mit Majoritätslogik. 
Dadurch sind beide deutlich störsicherer als SPI.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Peter D. schrieb:
> Bei I2C wird die slew-Rate begrenzt und die Eingänge gefiltert.

Schon dadurch, dass der Anstieg nur durch Pull-Ups erfolgt … aber wenn 
man schneller werden will als nur 100 oder 400 kHz, ist das eben nicht 
mehr ganz so einfach mit dem Begrenzen der slew rate.

Ansonsten volle Zustimmung zu den Statements weiter oben: SPI mit einem 
Controller als Slave ist alles andere als optimal. SPI funktioniert gut, 
wenn ich hintendran ein Schieberegister habe oder andere Hardware, die 
mir einen Takt später auf der Rückleitung die Antwort liefern kann. Eine 
CPU braucht notgedrungen ein paar Takte, bis sie eine solche Antwort 
bereitstellen kann.

von Pandur S. (jetztnicht)


Lesenswert?

Klopp CAN in die Tonne. Der ist gut fur Autos, die maximlae Packetlaenge 
ist 6 Bytes oder so.

von Pandur S. (jetztnicht)


Lesenswert?

SPI auf seinen 5 cm Laenge zu stoeren halte ich fuer sehr schwierig, 
ausser mit EMV.

Die Idee mit mehreren CPUs auf einem Board ist Muell. Das wird so nie 
was. Falls man Hardware funktionaittaet auslagern moechte, dann in ein 
FPGA.

von Felix (Gast)


Lesenswert?

Matthias L. schrieb:
>> d.h. Call durch den Slave, einfach in den gerade laufenden Traffic hinein
>
> Hä? siehe "muss auf Bus frei warten"
War zu kurz geschrieben. Ich meinte die Situation, in der ein Slave dran 
ist und mangels Daten im Puffer nur Nullen sendet.
In diesem Moment könnte er von sich aus einen Call initiieren und in den 
Datenstrom aus Nullen einschieben.

>>(Konsequenz: Master muss alle paar Mikrosekunden pollen).
>Alle µs?
Nein, das war unüberlegt. Wenn keine Antwort aussteht, würde Pollen 
durch den Master vielleicht alle 50-100 Millisekunden reichen

von Felix (Gast)


Lesenswert?

Frank K. schrieb:
> Ja, das ist genau das Problem. Du hast einfach die falsche Hardware
> ausgesucht.
>
> Schau mal wie die Profis es machen

Technisch ein sehr guter Rat und die Aufstellung der CAN-Hardware finde 
ich hilfreich, danke dafür. Die Frage ist nur, wie setze ich Deinen Tipp 
um? Ich schreibe das mal ausführlich, weil das für sehr viele 
Profi-Tipps an Amateure gilt.

Ich betreibe das als Hobby ohne das Ziel einer Vermarktung. Dabei stehe 
ich aktuell vor folgenden Herausforderungen:
- Lernen über Mikrocontroller, serielle Busse und Elektronik
- Hardware-Design des Roboters
- Software-Design des Roboters wie Fahrprogramme, Karten etc.
- Design eines höheren Kommunikationsprotokolls zwischen ATmega und 
Raspberry

Das kann ich mit meiner aktuellen Hardware erstmal sinnvoll 
weiterführen. Wahrscheinlich ist SPI ungeeignet, dann kann ich auf USART 
umsteigen, wird mich nur einen Abend kosten. Dabei würde ich dann auch 
mal mit dem MCP2562 experimentieren, ist mit knapp 90 Cent ja keine 
Investition. Natürlich werde ich den Karren trotzdem an die Wand fahren, 
wahrscheinlich in dem Moment, wo ich einen zweiten ATmega einsetzen 
will. Oder eine höhere Geschwindigkeit brauche.
Dann bin ich mit meinen 4 Punkte oben weiter und würde auf den 
Beagle-Bone (oder Alternativen) mit CAN-Bus-Unterstützung zurückkommen. 
Alles, was ich bis dahin gelernt und gebaut habe, kann ich weiternutzen, 
es ist also kein "Waste". Die 12 Euro für den Raspberry Zero und die 
2,50 Euro für den ATmega haben sich dann bezahlt gemacht.

Ein direktes Umsetzen Deines Tipps heute würde mich das zehnfache vom 
aktuellen Setup kosten, ich könnte die große Community rund um Arduino 
und Raspberry nicht mehr nutzen und ich stände wieder ganz am Anfang mit 
einer mir unbekannten Hardware. Umsetzen werde ich Deinen Tipp also 
erstmal nicht in Richtung Hardwarekauf, sondern in Richtung Verständnis 
einer sinnvollen Zielarchitektur.

Das gleiche gilt für Pandurs Tipp von eben mit FPGAs. Sicher auch 
sinnvoll, nur wenn ich all diesen Tipps (hinter denen verschiedene 
Engineering-Schulen stehen) direkt nachgehe, dann drehe ich mich im 
Kreis und komme nirgendwo an.

von MCUA (Gast)


Lesenswert?

> Bei I2C wird die slew-Rate begrenzt und die Eingänge gefiltert.
I2C zählt nicht, ist schnarchlangsam.
Auch UART (grade bei den meisten uCs) ist sehr langsam.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

MCUA schrieb:
> I2C zählt nicht, ist schnarchlangsam.
Der ist mit seinen "üblichen" 400kHz immer noch schneller, als das, was 
derzeit auf dem SPI von Felix läuft, denn
Felix schrieb:
> Ich habe es ausprobiert: Ab einer bestimmten Baudrate (etwa 115200) gibt
> es den zu erwartenden Bitsalat, darunter läuft es absolut stabil.

MCUA schrieb:
> I2C zählt nicht, ist schnarchlangsam.
Siehe auch https://www.i2c-bus.org/fastmode/

MCUA schrieb:
> Auch UART (grade bei den meisten uCs) ist sehr langsam.
Grade bei uCs ist der UART nicht mal soo arg langsam. Man darf dann eben 
nicht die aus der Telegrafensteinzeit stammenden "Standard-Baudraten" 
verwenden, sondern solche, die der µC gut kann. Und dann waren z.B. 
schon mit den alten 8051 bei DMX512 lockere 250kBit/s drin.

: Bearbeitet durch Moderator
von MCUA (Gast)


Lesenswert?

> I2C zählt nicht, ist schnarchlangsam.
Wenn man einer Schnecke einen "Fast"-Modus verpasst wird es auch nicht 
viel schneller.
Das I2C-Protokoll lässt prinz. keine hohen Raten zu.

von MCUA (Gast)


Lesenswert?

> Auch UART (grade bei den meisten uCs) ist sehr langsam.
UART kann (prinz.) bis einige Gbps gehen, nur eben bei fast jedem uC 
nicht.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

MCUA schrieb:
> UART kann (prinz.) bis einige Gbps gehen, nur eben bei fast jedem uC
> nicht.

Naja, 1 MBaud sind bei Controllern meist noch problemlos möglich, mit 
einem FTDI geht das sogar noch über UART in Richtung PC.

Bei Controllern kann man außerdem meist noch einen "synchronen" Modus 
fahren. Da bleibt zwar immer noch das blöde UART-Framing (anders als 
bspw. die Z80-SIO das vor Jahrzehnten konnte), aber man braucht das 
16fache oversampling der normalen UART nicht mehr.

von Pandur S. (jetztnicht)


Lesenswert?

Bevor man die Bardraten hochreibt sollte man sich vergewaertigen dass 
man auf der anderen Seite Intrrupts erzeugt. Das ist ja gut, wenn der 
auch Zeit hat. Und eher nicht, wenn nicht. zB ist ein SPI Interrupt bei 
hoher Taktrate sinnlos. Ein Byte rauszuschieben datert 8 clocks oder so. 
Ein Interrupt macht mal ein Push von allen Registern, und nachher 
nochmals ein Pop von allen Registern. Bei 16 Registern waeren das dann 
schon 32 clocks, bedeutet mehr als Clock -Viertel ist nichts fuer den 
SPI in diesem Betrieb. Ein 8 facher NOP waere passender. Ohne 
Interrupts.

: Bearbeitet durch User
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Pandur S. schrieb:
> Ein 8 facher NOP waere passender.

Stattdessen das ready-Flag zu testen, ist noch sinnvoller.

von Felix (Gast)


Lesenswert?

Pandur S. schrieb:
> wenn nicht. zB ist ein SPI Interrupt bei
> hoher Taktrate sinnlos. Ein Byte rauszuschieben datert 8 clocks oder so.
> Ein Interrupt macht mal ein Push von allen Registern, und nachher
> nochmals ein Pop von allen Registern. Bei 16 Registern waeren das dann
> schon 32 clocks, bedeutet mehr als Clock -Viertel ist nichts fuer den
> SPI in diesem Betrieb. Ein 8 facher NOP waere passender. Ohne
> Interrupts.

Nur der Neugier halber, denn mir würden für meinen Fall auch 9600 Baud 
reichen: Welche sinnvolle Anwendung kann man damit bauen? Das bedeutet 
ja, dass pausenlos ein Loop läuft, der entweder von sich aus genau 
taktet oder halt das Ready-Flag liest. Dann bleibt gerade noch Zeit ein 
paar IO-Pins zu lesen oder zu setzen und das wars. Vielleicht geeignet 
als Konverter, serial nach parallel. DA-Wandler gibt es nicht auf dem 
ATmega. Was bleibt als Einsatzmöglichkeit?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Felix schrieb:
> Welche sinnvolle Anwendung kann man damit bauen?

Allerlei Peripherie, die man schnell "befüllen" will: Funk-Transceiver, 
Frequenzwort für DDS-ICs, Flash-Speicher, … you name it. Man kann auch 
simple 74HC595 dranhängen und mit einem langen Schieberegister sackweise 
parallele IO-Pins (bspw. für eine LED-Matrix) ansteuern.

von (prx) A. K. (prx)


Lesenswert?

Pandur S. schrieb:
> Klopp CAN in die Tonne. Der ist gut fur Autos, die maximlae Packetlaenge
> ist 6 Bytes oder so.

8 Bytes, plus 29-Bit ID. Und? Ich habe darüber u.A. ein Eventlog von zig 
KB Länge ausgelesen. Man braucht dafür etwas Protokoll obendrauf, spart 
sich aber untenrum viel Arbeit.

von (prx) A. K. (prx)


Lesenswert?

MCUA schrieb:
> I2C zählt nicht, ist schnarchlangsam.

Kommt auf die Ansprüche an. Schneller als schnell genug bringt nichts.

von Frank K. (fchk)


Lesenswert?

Felix schrieb:

> Ein direktes Umsetzen Deines Tipps heute würde mich das zehnfache vom
> aktuellen Setup kosten, ich könnte die große Community rund um Arduino
> und Raspberry nicht mehr nutzen und ich stände wieder ganz am Anfang mit
> einer mir unbekannten Hardware.

Der Pi ist eine Linux-Maschine. Das, was Du da siehst, ist das Linux. 
Das ist in Prinzip das gleiche Linux wie auf einem PC. PC-Linux-Software 
kannst Du zu großen Teilen einfach neu compilieren, und sie laufen auf 
Deinem Pi.

Der Beaglebone ist auch eine Linux-Maschine. Der hat sogar die gleiche 
Architektur (armhf). Du kannst die meisten Programme vom Beaglebone 
einfach so auf dem Pi laufen lassen, und umgekehrt. Es sei denn, sie 
nutzen den Closed-Source Binärcode von der Pi Foundation - dann hängen 
sie in der Fliegenfalle. Gleiches gilt für die Coprozessoren beim 
Beaglebone. Das Linux selber kümmert sich um den Großteil der 
Hardwareunterschiede. Der Rest sind Details (wie baue ich mir eine 
SD-Karte? Wie konfiguriere ich die GPIO-Pins?)

Daher ist zu Deinem Argument zu sagen: "sachlich falsch". Lerne Linux 
(auf welcher Plattform auch immer), nicht Raspberry.

Und der Teensy wird auch mit der Arduino-IDE programmiert. Da kümmert 
sich das Arduino-System um die Unterschiede. Es gibt sogar von Arduino 
selber Boards mit ARM-Prozessor.

fchk

von MCUA (Gast)


Lesenswert?

>> Ein 8 facher NOP waere passender.
> Stattdessen das ready-Flag zu testen, ist noch sinnvoller.
Da sieht man wie schlecht es um den AVR steht, wenn NOPs schon besser 
sind!
An eine Schnitte gehören ein paar FIFOs (und weiter DMA), da brauchts 
keinen INT alle 8 Bits.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

MCUA schrieb:
> Da sieht man wie schlecht es um den AVR steht, wenn NOPs schon besser
> sind!

Quark. NOPs sind _nicht_ besser, höchstens fauler (für den 
Programmierer). Macht kein Mensch so.

> An eine Schnitte gehören ein paar FIFOs (und weiter DMA), da brauchts
> keinen INT alle 8 Bits.

Das hilft bei SPI in aller Regel rein gar nicht. Je nach Gerät hast du 
noch irgendwelchen Firlefanz drumrum zu machen (bspw. festzulegen, 
während welcher Perioden das Select-Signal gezogen und wann wieder 
losgelassen werden muss), dass das mit üblichen DMA-Logiken nicht 
handhabbar ist.  BTDT (nicht AVR, sondern verschiedene ARMs, auch deren 
"intelligentes" Select-Signal brachte es nicht).

DMA ist gut für Dinge, wo man in regelmäßigen Abständen oder langen 
Blöcken viele ansonsten gleichartig gelagerte Daten bearbeiten muss.

: Bearbeitet durch Moderator
von MCUA (Gast)


Lesenswert?

> Das hilft bei SPI in aller Regel rein gar nicht.
Quark. Was heisst hier in aller Regel?
Die Tiefe der FIFOs (wenn man welche hat) kann man steuern.
Bei 16 Bytes Tiefe ist es ein INT (oder DMA-Req.) nicht alle 1 Byte 
sondern alle 16 Bytes. Macht Faktor 16, den die CPU mehr Zeit (zu 
rechnen) hat, bis sie wieder unterbrochen wird.
Hat man weniger Bytes kann man (muss man aber nicht) auch weniger 
einstellen (dann wird die INT-Rate nat. umso grösser).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

MCUA schrieb:
> Bei 16 Bytes Tiefe ist es ein INT (oder DMA-Req.) nicht alle 1 Byte
> sondern alle 16 Bytes.

Wenn ich aller 8 µs 4 Bytes vom Gerät abholen muss (also vier Nullbytes 
senden) und dabei vorher ein passendes Kommando (3 Bytes) hinsenden 
(nicht zu vergessen, das Select-Handling um all diese Bytes herum), dann 
hilft mir der FIFO was?

Ein FIFO hilft nur bei einem längeren Datenstrom wirklich.

SPI-Geräte sind viel zu verschieden für solch pauschale Aussagen.

von MCUA (Gast)


Lesenswert?

Der FIFO kann ja auch senden, nicht nur empfangen.
Der kann also mal 16 Bytes rausbuttern, das auch lesen.
(\CS muss auch nicht nach jedem Byte geschaltet werden)

Das Schema funkt. genauso auch bei anderen Schnittstellen (sofern die 
auf Bitebene schnell genug sind)

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

MCUA schrieb:
> \CS muss auch nicht nach jedem Byte geschaltet werden

Nicht nach jedem, aber vor jedem Block eingeschaltet und nach dem Block 
ausgeschaltet. Die meisten Peripherals brauchen das als Synchronisation.

Da aber das CS-Handling halt nicht durch das normale SPI-Datenregister 
erfolgt, passt das alles nicht so recht in ein DMA-Schema.

Klar, wenn man nur einmal ein Kommando senden muss und dann /CS aktiv 
bleiben darf, um hin und wieder da mal was abzuholen, dann passt das. 
Lohnt aber eigentlich nur, wenn die periphere Daten(bereitstellungs)rate 
das limitierende ist. Wenn es die Bustaktrate ist (weil das Gerät seinen 
Blurb an Daten sowieso rumliegen hat), dann kann die CPU auch gleich 
solange warten. Nur, wenn die CPU-Geschwindigkeit sehr viel höher als 
die SPI-Rate ist, würde sich dort FIFO oder DMA lohnen, sofern die CPU 
mit den übrigen Zyklen auch wirklich was anderes tun kann. (Wenn sie nur 
auf das "DMA ready"-Bit warten muss, kann sie auch gleich selbst 
pollen.)

von MCUA (Gast)


Lesenswert?

Das "CS-Handling" ist aber nicht der Rede wert, wenn es nur 1x je Block 
ein-aus-geschaltet wird.
Die Hardware kann das machen, das kostet keine CPU-Zeit.

Und wenn die CPU "gleich solange warten" soll, stimmt sowiso schon was 
nicht.
Das ist vertrödelte (blockierende) Zeit (egal ob mit NOPs oder irgent 
welche Abfragen).

Die Grenze ist sozusagen die CPU-INT-Leistung.
CPU schafft nur eine bestimmte Anzahl ISRs/s.
(es fallen ja min schon min. ca 5..8 CPU-Clks an, nur bis der INT 
überhaupt mal angenommen wird (von ContextSwich ganz zu schweigen).
Solange man (rel. weit) unter dieser CPU-INT-Belastung ist, geht das.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

MCUA schrieb:
> Das "CS-Handling" ist aber nicht der Rede wert, wenn es nur 1x je Block
> ein-aus-geschaltet wird.

Sag ich ja: lohnt sich bestenfalls nur bei langen Blöcken.

> Die Hardware kann das machen, das kostet keine CPU-Zeit.

Dir sind scheinbare noch nicht genügend verschiedene SPI-Geräte über den 
Weg gelaufen. Wie ich oben schrieb: die Hardware hat schlicht keine 
Ahnung, an welchen Stellen sie /CS ziehen und an welchen wieder 
loslassen muss, wenn man da erst irgendwelche Kommandos runterschreiben 
muss (die nicht nur aus einem Byte bestehen). Dann kann das nur die 
Software machen.

> Und wenn die CPU "gleich solange warten" soll, stimmt sowiso schon was
> nicht.

Wenn sie die Daten an der Stelle braucht und sowieso nichts weiter tun 
kann als Däumchen zu drehen, dann könnte sie sich bestenfalls noch 
schlafen legen. Wenn nur ein paar Byte zu holen sind (und das dann auch 
mit 20 MHz SPI-Takt), lohnt das aber auch nicht. Sleep/wakeup hat auch 
Overhead.

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

MCUA schrieb:
> Das "CS-Handling" ist aber nicht der Rede wert, wenn es nur 1x je Block
> ein-aus-geschaltet wird.
Wenn das Wörtchen "wenn" nicht wär...

> Die Hardware kann das machen
"Wenn" sie es denn überhaupt kann. Bei den allerwenigsten 
SPI-Implementierungen in µC kann der SPI-Automat aber die Steuerung des 
Busses komplett selbständig machen.
Ich habe hier ein System mit 3 SPI-Bussen und 16 Slaves, die im ms-Takt 
alle mit unterschiedlichem Takt, variabler Wortbreite, mehreren SPI-Mode 
und änderndem CS-Timing angefahren werden wollen. Da ist nichts mit 
"das macht die CPU per DMA nebenher".
Diese SPI-Teilnehmer werden unabhängig von der CPU mit einem FPGA 
bedient, in dem ein Automat eine Anweisungsliste mit all den 
Einstellungen durchackert und dann rechtzeitig zum nächten Tick die 
empfangenen Daten der 16 Slaves bereitstellt.

Denn der Witz ist eben, dass ein SPI-Bus eben meist nur die 
physikalische Verbindung zwischen zwei Geräten ist, und das 
"Übertagungsprotokoll" schon beim Timing der Ansteuerung beginnt. Beim 
SPI habe ich u.U. bei 4 Teilnehmern 4 komplett unterschiedliche 
Ansteuersequenzen mit völlig unterschiedlichen 
SPI-Register-Einstellungen. Man braucht neben dem Oszilloskop auch die 
Datenblätter zum Timing jedes Bausteins um die Qualität der 
Übertragung zu kontrollieren.

In den allermeisten anderen Bussen muss man sich um das Timing nicht 
kümmern, weil das in der Busspezifiktation festgelegt ist und sich alle 
daran zu halten haben. Bei RS232 mit 96008N1 kann jeder mit einem 
Oszilloskop ohne Wissen um die Teilnehmer kontrollieren, ob die 
Übertragung so überhaupt funktionieren kann.

: Bearbeitet durch Moderator
von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Lothar M. schrieb:
> Diese SPI-Teilnehmer werden unabhängig von der CPU mit einem FPGA
> bedient

Wenn man das so braucht, auf jeden Fall eine elegante Lösung. Wenn man 
das FPGA noch direkt vom Controller aus konfiguriert, hat man trotzdem 
noch eine komplett per Software änderbare Lösung. ;-)

Ganz so schlimm war's bei uns zum Glück nicht, aber genügend SPI-Spaß 
habe ich in meinem aktuellen (und auch vorherigen) Job allemal gehabt …

von MCUA (Gast)


Lesenswert?

> Dir sind scheinbare noch nicht genügend verschiedene SPI-Geräte über den
> Weg gelaufen.
Mehr als du denkst. Ausserdem gibt es keine SPI-Geräte, nur SPI-ICs.

> Denn der Witz ist eben, dass ein SPI-Bus eben meist nur die
> physikalische Verbindung
"Den" SPI-Bus gibt es überhaupt nicht.

Klar kann die Schnittstellen-Hardware (zugegeben nicht Jede) auch das 
bisschen \CS-Steuerung übernehmen.

Und wenn man unterschiedliche Timing/Grössen-Anforderungen hat, 
kann/soll man das auch auf mehrere Busse aufteilen (sofern man dazu die 
Schnittst. hat).

Bloss, FIFOs die man nicht hat, kann man auch nicht benutzen.

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

MCUA schrieb:
> Klar kann die Schnittstellen-Hardware (zugegeben nicht Jede) auch das
> bisschen \CS-Steuerung übernehmen.

Woher bitte soll die eigentlich wissen, um welche Bytegrenzen herum sie 
das Signal schalten soll?

Genau daran scheiterte es bei uns selbst bei solchen Controllern, die 
das angeblich in Hardware könn[t]en.

von MCUA (Gast)


Lesenswert?

>> Klar kann die Schnittstellen-Hardware (zugegeben nicht Jede) auch das
>> bisschen \CS-Steuerung übernehmen.
> Woher bitte soll die eigentlich wissen, um welche Bytegrenzen herum sie
> das Signal schalten soll?
Muss ich das wirklich beantworten?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

MCUA schrieb:
>>> Klar kann die Schnittstellen-Hardware (zugegeben nicht Jede) auch das
>>> bisschen \CS-Steuerung übernehmen.
>> Woher bitte soll die eigentlich wissen, um welche Bytegrenzen herum sie
>> das Signal schalten soll?
> Muss ich das wirklich beantworten?

Naja: genau das war eins der Probleme, weshalb die "automatischen" 
CS-Handler der ARM-SPI-Units nicht funktioniert haben. Sie können so 
schlecht die Datenblätter der Peripheriebausteine lesen.

von Peter D. (peda)


Lesenswert?

SPI ist hauptsächlich dazu gedacht, dumme Slaves anzusteuern, wie 
IO-Register, ADC/DAC, LED-Treiber usw.
Daher sind die Slave-Implementierungen vieler MCs nur ungenügend 
durchdacht.

Soll aber ein MC dochmal Slave sein, wird oft folgendes Protokoll 
verwendet:
Adreßbyte, Befehlsbyte, Dummybyte, Daten ...
In der Zeit des Dummybytes kann der Slave dann das Kommando auswerten 
und entsprechend Daten lesen oder bereitstellen.

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.