Das sind keine Anforderungen, das ist Buzzword Bingo.
Eine wichtige Anforderung wäre die Minimale datenrate.
Also, was und wie oft sollen die µC untereinander austauschen:
Alive beacon, status reports, alarm messages, ...
UDP wird gern genommen.
Ich habe das vor vielen Jahren in einem System mit bis zu 16 Einkartenrechnern mit I2C gemacht, weil man damit (falls es die Hardware unterstützt - mit bit banging geht's nicht) relativ einfach eine multi-master Umgebung erstellen kann. Anforderung war, dass jedes Gerät auf eigene Initiative einem beliebigen anderen Gerät (oder allen auf einmal) Informationen schicken konnte und Informationen abrufen konnte. Die Geräte hatten auch ein eigenes kleines FAT-Dateisystem, auf das man zugreifen konnte. Wenn ich freie Wahl gehabt hätte, hätte ich das mit CAN realisiert, aber das hätte einen weiteren Baustein erfordert, während I2C im uC schon drin war. Heute würde ich das gleiche mit UDP machen.
I2C hat gut funktioniert, wir haben die Controller im 10bit Modus und mit relativ hoher Geschwindigkeit adressiert. Ich glaube aber, Deine Anforderungen sind wesentlich geringer. Müsstest Du halt mal etwas detaillierter beschreiben.
SPI und I²C schreiben dir vor, wie schnell du antworten musst.
Bei SD Karten muss man so lange Dummy Daten (und Takt) senden, bis die Karte antwortet. Bei I²C antworten die Geräte normalerweise sofort.
Bei UART ist hingegen asynchrone Kommunikation ein Standard Fall. Der Master sendet ein Kommando, und der Slave antwortet irgendwann danach, sobald er halt kann.
UART Kommunikation kann man manuell mit einem Terminalprogramm simulieren, wenn das Protokoll auf Text-Zeilen beruht.
UART kann man leicht mit RS485 oder RS422 Tranceivern über lange Kabel übertragen. Diese haben dann auch kein Problem, wenn Sender und Empfänger nicht ganz das gleiche GND Potential haben.
UART kann man auch leichter via USB Übertragen, als die anderen Protokolle. Entsprechende Adapter emulieren COM Ports, die man ohne spezielle Bibliotheken in allen Programmiersprachen nutzen kann.
Deswegen bevorzuge ich UART.
Was das Protokoll angeht, bevorzuge ich text-basierte wo immer es geht. Datensätze kann man z.B. im CSV oder JSON übertragen. Gerne auch mit Prüfsummen, um Übertragungsfehler erkennen zu können.
Da ich gerade USB Adapter erwähnt hatte: Für die Latenz ist USB allerdings eher uncool. Da muss man mit Verzögerungen im einstelligen ms Bereich rechnen. UART mit 57600 Baud ist bereits bedeutend schneller.
Mit dem 9. Takt muss der Slave das ACK senden, und direkt danach die angefragten Daten liefern.
Und wie sieht nun Deine Antwort aus?
Habe ich doch geschrieben. Wenn du eine Antwort der Art "die einzig wahre Lösung ist ...", dann kannst du lange warten. Solche Antworten bekommst du eher in der Kirche.
SPI kann eigentlich beliebig langsam sein. Auf der schnellen Seite ist das Limit die Responsezeit des Controller, denn die haben nur ein Byte buffer. Das sollte gelesen sein, bevor das Naechste kommt.
Ich verwende auch UART, mit RS232, oder RS422 leveln und Treibern. Waehrend RS232 punkt zu punkt ist, erlaubt RS422 einen Bus, wo mehrere kommunizieren koennen
Die Latenz ist zum Einen von der Baudrate, zum Anderen von der Antwortzeit des Controllers bestimmt. Baudrate wegen - erst muss die Meldung ankommen und verstanden werden.
Mit dem 9. Takt muss der Slave das ACK senden, und direkt danach die
angefragten Daten liefern.
Wenn der Master Clock-Stretching beherrscht, entspannt sich das Timing ein wenig. Wenn er es nicht beherrscht, ist er schlecht implementiert. Und schlecht implementierte Schnittstellen sollte man meiden.
UART kann man auch leichter via USB Übertragen, als die anderen
Protokolle. Entsprechende Adapter emulieren COM Ports, die man ohne
spezielle Bibliotheken in allen Programmiersprachen nutzen kann.
MCP2221a kann neben USB-Uart auch USB-I2C ;)
Ich würde aber auch zunächst schauen, ob mir Uart nicht genügt da man damit ein recht leicht durch den Menschen lesbares Protokoll erschaffen kann (Vorteil Terminal usw). Zudem habe ich vor geraumer Zeit das SCPI-Protocol für mich entdeckt, ich implementiere es nicht vollständig aber es hat mir eine gute Grundlage geschaffen.
Ich war sehr unpräzise.
die Mikrocontroller befinden sich auf demselben Board.
nur wenige 10 mm entfernt.
Das hat aber nur geringen Einfluß auf die Protokollwahl
Bei so kurzen Kram kommt halt als PHY immer noch I²C, SPI, PCI, PCIe etc. in Betracht, UART/CAN eher nicht. Persönlich würde ich zu SPI raten.
Hallo,
ich möchte zwischen zwei Mikrocontrollern eine Kommunikation haben.
Dabei frage ich mich, welches Protokoll eignet sich da am besten?
In Hardware könnte ich z.B. nutzen:
USART
SPI
I2C/TWI
oder etwas eigenes
Es ist ein AVR-Controller.
Wenn es einfach gehen sollte und wenn nicht ascii sondern Bytes zu übertragen sind, dann scheint mir USART in 9-bit-Mode am besten. 9. Bit kann man für Unterschied zwischen Befehl (z.B. Start der Sendung, Stop der Sendung, Byte zum Lesen vorbereiten usw.) und Daten benutzen. Falls mindestens ein von beiden Mikrocontrollern mit RC-Takt läuft, dann synchron (RxD/TxD und XCK), sonst asynchron.
Als mögliche Protocoll scheint mir die Variante mit Post-Befehl am einfachsten: zuerst werden mehrere Bytes in FIFO von Empfänger übertragen, danach folgt Befehl, somit wird Inhalt von FIFO bewertet.
Bei Bedarf kann man solch Aufbau für mehrere Slave erweitern: TxD von Master mit 74HC138 und RxD mit 74HC151/251 multiplexieren, XCK darf zusammen bleiben.
Aber FIFO kann man unkompliziert in Programm machen. Wenn SPI sehr schnell geschaltet wird, braucht man Pausen beim Senden, aber das kann man auch machen. FIFO futtern, ISR schalten - und weiter Bier trinken gehen...
Einzig stört mir bei SPI: keine 9-bit-Mode. Dann muß man andere Möglichkeiten suchen, um Command und Data zu unterscheiden.
Wenn Du genügend Pins frei hast, kannst Du auch 8/16/32 bit parallel
übertragen. Das reduziert Deine Latenz.
heute kommen die Kinder nicht mehr auf so einfache Dinge wie xmodem, zmodem usw. Und wofür die Pins CTS RTS auf FTDI Adaptern sind auch nicht. Und wieso hier ständig psysikalische Schnittstellen als Protokolle bezeichnet werden zeugt von sehr viel Unkenntnis. UART heisst Universal Asynchronous Receive Transmiter und stellt nur die Physik bereit.
die Mikrocontroller befinden sich auf demselben Board.
nur wenige 10 mm entfernt.
Dann stellt sich gleich die Frage, warum überhaupt zwei AVRs verwendet werden sollen.
Aduini im 5er Pack gekauft? Oder sollen zwei LEDs mit unterschiedlicher Geschwindigkeit blinken?
Mich würde hier garnichts mehr wundern ;-)
Wenn Du genügend Pins frei hast, kannst Du auch 8/16/32 bit parallel
übertragen. Das reduziert Deine Latenz.
heute kommen die Kinder nicht mehr auf so einfache Dinge wie xmodem,
zmodem usw. Und wofür die Pins CTS RTS auf FTDI Adaptern sind auch
nicht. Und wieso hier ständig psysikalische Schnittstellen als
Protokolle bezeichnet werden zeugt von sehr viel Unkenntnis. UART heisst
Universal Asynchronous Receive Transmiter und stellt nur die Physik
bereit.
Ich spreche nicht von Protokollen!
Der TO hatte oben auch mehrere phys. Schnittstellen genannt, und genau dazu habe ich ihm einer weitere genannt.
Dabei frage ich mich, welches Protokoll eignet sich da am besten?
Bitte hier auch verschiedene Schichten beachten. Mit SPI, I2C usw. kannst du Bytes übertragen. Ein Protokoll ist das noch nicht. Es ist der Physical Layer.
Darüber muss mindestens noch eine Schicht kommen, welche deine zusätzlichen Anforderungen an Robustheit umsetzt. Darüber evt. eine Schicht für die Applikation selbst.
Ich nehme meist immer was eigens. Mit einer eigenen
Fehlerbehandlungsroutine = Eigene Prüfsumme
Ja, immer wieder das Rad neu erfinden, was schon Generationen von Softwerkern seit der CPM Ära gemacht haben. Wenn Du in meiner Embedded Softwerker Gruppe so anfangen würdest wäre die Probezeit wohl schnell beendet.
Ja, immer wieder das Rad neu erfinden, was schon Generationen von
Softwerkern seit der CPM Ära gemacht haben.
Aber du darfst mir gerne mal erklären, warum im NEUEN HOME-Steuerungssystemen man sich mit X-Protokollen für den selben Mist herum schlagen muss.
Und man bei Steuerzentralen schauen muss welche Protokolle die für den Selben MIST (Lampe anmachen) alles beherrschen. Vielleicht machen die das nur, damit Tester schreiben können "Das Tassimoto-Protokoll ist in seinen Grundfunktionen brauchbar integriert."
Ich lach mich weg bei deinen Äußerungen. Klingen ja fein, aber sind Meilenweit von der Realität = Produktion von Elektroschrott (Wenn Firma mit komischen Portokoll) pleite geht entfernt.
Allerbesten Beispiel ist BT. Das ist ein einzigen Protokoll-Schrott.
Einzig stört mir bei SPI: keine 9-bit-Mode. Dann muß man andere
Möglichkeiten suchen, um Command und Data zu unterscheiden.
Das ist Aufgabe des Protokolls. Darum vermutlich auch die Frage vom TO. Das, was dafür zusätzlich erforderlich ist, nennt sich gemeinhin Protokoll-Overhead.
Einzig stört mir bei SPI: keine 9-bit-Mode. Dann muß man andere
Möglichkeiten suchen, um Command und Data zu unterscheiden.
SPI ist von der Bitanzahl völlig unabhängig. Das ist einzig eine Limitierung mancher SPI Hardware. Üblicher Workaround ist /SS selber zu kontrollieren, die Hardware z.B. 8 Bit rausschieben zu lassen und per Software (Bitbanging) das 9. Bit hinterher zu schieben, dabei einmal mit SCLK wackeln dann /SS wieder auf High.
Eine viel einfachere Lösung ist allerdings bei solch limitierter Hardware auf 16 Bit zu gehen und die Hardware 2x8 Bit rausschieben zu lassen. Reduziert die Datenrate, reduziert aber auch den Programmieraufwand. Vielleicht fällt einem noch was ein was man mit den 7 ungenutzten Bits machen kann.
Grundsätzlich UART bei den AVR, wenn du die Suche bemühst, findest du
auch die Gründe.
SPI ist mit CLK/2 bei weitem das schnellste Protokoll.
Und dazu kommt, daß senden und empfangen gleichzeitig geht.
Also, nochmal doppelt so schnell.
Und bei der Entfernung ist SPI absolut unkritisch.
Pakete mit SOF-Length-DataBlk-EOF genügen vollkommen.
Grundsätzlich UART bei den AVR, wenn du die Suche bemühst, findest du
auch die Gründe.
SPI ist mit CLK/2 bei weitem das schnellste Protokoll.
Und dazu kommt, daß senden und empfangen gleichzeitig geht.
Also, nochmal doppelt so schnell.
Und bei der Entfernung ist SPI absolut unkritisch.
Pakete mit SOF-Length-DataBlk-EOF genügen vollkommen.
Spielt alles keine Rolle, AVRs sind lausige SPI-Slaves.
Nur dann, wenn Performance völlig unwichtig ist...
Bei den bisher genannten Anforderungen ist das noch nicht wirklich klar.
Alleine zwischen SPI und I2C besteht bei der möglichen Übertragungsraten schon ein großer Unterschied.
Vielleicht erfahren wir noch, was genau mit "geringe Latenz" gemeint ist und was für eine Art von Daten zwischen den Prozessoren ausgetauscht werden soll.
SPI ist mit CLK/2 bei weitem das schnellste Protokoll.
Nur nicht vergessen, daß Slave die Zeit braucht, Byte aus dem SPI zu holen, vor dem nächste Byte kommt. D.h. Slave muß sehen, daß etwas gekommen ist (ISR oder permanent SPI-Zustand abfragen) und Byte lesen und irgendwo speichern. In 18 * F_CPU von Slave ist das kaum möglich, deshalb kann man SPI so benutzen nur wenn man die Bytes mit großen Pausen schickt. Hier bringt CLK/2 nichts.
Und dazu kommt, daß senden und empfangen gleichzeitig geht.
Das geht auch nur wenn es um 1 Byte geht: Slave kann Byte im voraus in SPI legen. Ansonsten sollte Slave merken, daß SPI-Ausgang leer ist, irgendwo nächste Byte holen und in SPI speichern, vor dem neue Byte getauscht wird. Das braucht Zeit. Hier bringt CLK/2 auch nichts.
Wenn hier jemand von verschiedenen SPI-Varianten denkt, mit Puffer und 16 bit, möchte ich erinnern: TO schriebt, er braucht eine Lösung für AVR.
Nur nicht vergessen, daß Slave die Zeit braucht, Byte aus dem SPI zu
holen, vor dem nächste Byte kommt. D.h. Slave muß sehen, daß etwas
gekommen ist (ISR oder permanent SPI-Zustand abfragen) und Byte lesen
und irgendwo speichern.
Nicht unbedingt ein Nachteil.
Beispiel:
Wenn Slave bereit ist, wird z.B. 0x80 in SPDR reingeschrieben.
Wenn nicht, steht z.B. 0x8F in SPDR.
Master schickt SOF, empfängt 0x80 und sendet entweder nur CmdByt
oder das ganze Telegramm.
Slave hat SOF per Interrupt empfangen, springt in die Routine,
empfängt und sendet weitere Bytes bis zum EOF.
Da ist mehr als genug Zeit, um alle Bytes zu empfangen und die
Antwort zu schicken.
IN und OUT dauern jeweils 1Cy, LD oder ST dauert 2 Cy.
Bei 4MHz SPI dauert 1 Byte 2us, das sind 16Cy.
Und falls es um irgendwelche Sensorwerte geht, kann der Slave jede
ms eine Messung machen und die Werte ins SendeBuffer schreiben.
Diese Werte werden dann beim antworten automatisch verschickt.
Glaube nicht, das ein Unterschied von 1ms so wichtig ist.
Da ist mehr als genug Zeit, um alle Bytes zu empfangen und die
Antwort zu schicken.
IN und OUT dauern jeweils 1Cy, LD oder ST dauert 2 Cy.
Bei 4MHz SPI dauert 1 Byte 2us, das sind 16Cy.
Ich habe nur geschrieben, daß F_CPU/2 nicht sinnvoll wäre und somit für SPI wegen Geschwindigkeit zu werben auch nicht sinnvoll. USART kann synchron auch 4 MHz, und USART-RX ist gepuffert.
Beim überflüchtigen Verfolgen dieses Threads, ist es schwierig sich nicht des Eindrucks zu verwehren, nach allen Regeln der Kunst auf den Arm genommen zu sein. Da wird wieder einmal mit Eurer Lebenszeit und Nerven gefrevelt.
Diese äusserst dünne Salamitaktik ist wieder einmal beispiellos. Richtig mitgemacht hat der Gast TO mit seinen paar Beiträgen auch nicht.
Er hätte ja sagen können, wieviele Daten zu übertragen wären, wie oft, wie schnell, und die anderen pertinenten Details.
Wenn keine variablen Datenmengen ausgetauscht werden müssen, wäre ein gemeinsames Datenpaket mit festgelegter Struktur, in regelmässigen Intervallen über das USART gegenseitig ausgetauscht, am zweckmässigsten. Das geht im Hintergrund durch ISRs und beeinflusst das Hauptprogramm wenig und sichert eine hohe Zuverlässigkeit. Durch die Datenstruktur wäre alles in Stein gemeisselt und sichert zusammen mit einem CRC Check eine hohe Übertragungssicherheit. So würde ich es nach Möglichkeit machen, wenn nicht andere Gründe dagegensprechen.
Wenn Slave bereit ist, wird z.B. 0x80 in SPDR reingeschrieben.
Wenn nicht, steht z.B. 0x8F in SPDR.
Der Slave kann aber nicht hellsehen, wann er das SPDR beschreiben darf.
Wenn der Master zufällig das SPI dabei taktet, gibt es eine Write-Kollision und der Master liest Mumpitz.
Ohne Sendepuffer muß der Master regelmäßig Däumchen drehen, damit der slave schreiben kann. Und die Wartezeit muß minimal so lang sein, damit der Slave auch seine eigenen Interrupts behandeln kann.
Laufen beide AVRs mit Quarz, ist die UART schon die optimale Idee. Man kann aber auch CKOUT des einen AVR als XTAL1 des anderen benutzen.
Ansonsten ohne genauen Takt ist I2C optimal. I2C kennt keine maximalen Zeitbedingungen. Der Slave kann SCL beliebig lange strecken, denn der Master kriegt erst dann den Interrupt, wenn der Slave SCL wieder freigegeben hat.
Vielleicht erfahren wir noch, was genau mit "geringe Latenz" gemeint ist
und was für eine Art von Daten zwischen den Prozessoren ausgetauscht
werden soll
Wozu? Es wird doch schon prima geschnattert. Gefragt wurde nach einem Protokoll und geantwortet wird mit Schnittstellen.
Läuft doch alles wie gehabt!
Der Slave kann aber nicht hellsehen, wann er das SPDR beschreiben darf.
Wenn der Master zufällig das SPI dabei taktet, gibt es eine
Write-Kollision und der Master liest Mumpitz.
Mumpitz bedeutet Fehler und auch "nicht bereit", wo siehst du da ein Problem?
Ohne Sendepuffer muß der Master regelmäßig Däumchen drehen, damit der
slave schreiben kann. Und die Wartezeit muß minimal so lang sein, damit
der Slave auch seine eigenen Interrupts behandeln kann.
Ja, im Gegensatz zu I2C und UART, wo der Slave seine Interrupts
nicht behandeln muss.
Und 8MHz (oder sogar 10MHz) sind immerhin mindestens 50 mal so schnell
wie die üblichen UART Geschwindigkeiten und 30 mal schneller als I2C.
Auch wenn der Slave nur NOPs zurücksendet weil er momentan keine Antwort hat.
Ein Telegramm mit {SOF-Cmd-8 Byte Data-EOF} dauert bei 8 MHz SPI
11us, bei 115Kb UART aber fast 1ms (956us).
Das ist für mich ein Unterschied von 945us oder 16700Cy.
In 16700Cy kann der Slave 50 INTs mit jeweils 200Cy abarbeiten.
Und zwischendurch Quadratwurzel aus 4684 ziehen.
Und verschiedene Sensormessungen.
Und...
In 16700Cy kann der Slave 50 INTs mit jeweils 200Cy abarbeiten.
Dazu muß der Master aber auch vor jedem Byte mindestens 200Cy + X warten, damit der Slave einen laufenden Interrupt beenden, dann in den SPI-Interrupt springen und das nächste Byte bereitstellen kann. Und ich habe die Einschränkung, daß andere Interrups max 200Cy dauern und keine höhere Priorität als der SPI haben dürfen.
Entweder ich hab so hohe Datenraten, daß SPI notwendig ist. Dann ist der Slave so mit auf SPI lauschen ausgelastet, daß er die Datenmenge gar nicht handhaben kann und auch nichts anderes mehr machen.
Oder ich habe moderate Datenmengen. Dann nehme ich doch viel lieber Interfaces, wo der Slave keine Rücksicht drauf nehmen muß und sie nachrangig behandeln kann, wann es ihm paßt. Insbesondere, daß seine Tasks keine Rücksicht drauf nehmen müssen, d.h. das Interface quasi unsichtbar ist.
Ich mag es, wenn Tasks möglichst wenig Seiteneffekte haben und möglichst keine Einschränkungen für andere Tasks bedeuten. Das programmiert sich einfach viel angenehmer und entspannter und ist damit auch zuverlässiger und gut erweiterbar.
SPI ist mit CLK/2 bei weitem das schnellste Protokoll.
Und dazu kommt, daß senden und empfangen gleichzeitig geht.
Also, nochmal doppelt so schnell.
Schnell, ja.
Aber Anfänger oder "generelle" Kommunikation ungeeignet.
SPI- oder I2C-Slave macht m.E. nur Sinn, wenn man die Geschwindigkeit braucht, ganz klar einer Master ist und die Verbindung bei SPI garantiert keine Reflexionen/Doppelimpulse auf der Clockleitung hat.
Nur die wenigsten haben sich bei I2C oder SPI jemals mit Slave-Modi beschäftigt.
Ich mag es, wenn Tasks möglichst wenig Seiteneffekte haben und möglichst
keine Einschränkungen für andere Tasks bedeuten. Das programmiert sich
einfach viel angenehmer und entspannter und ist damit auch zuverlässiger
und gut erweiterbar.
OK, ich versuche es mal einfacher:
a) Master sendet Request per SPI, empfängt "NotReady", bzw. nur
gesendete Bytes zurück. Dauert alles 11us.
b) Master sendet Request per UART, empfängt gar nichts zurück.
Dauert alles 950us, also 90 Mal länger, 940us mehr.
Bei SPI hat der Slave nun 930us Zeit, die Antwort vorzubereiten und
weitere 11us Zeit, diese Antwort zu senden, wenn der Master es fordert.
Und Request vom Master per UART ist noch nicht einmal fertig gesendetin dieser Zeit, geschweige denn die Antwort erhalten.
Entweder ich hab so hohe Datenraten, daß SPI notwendig ist. Dann ist der
Slave so mit auf SPI lauschen ausgelastet, daß er die Datenmenge gar
nicht handhaben kann und auch nichts anderes mehr machen.
Das ist nur bedingt richtig, aber dafür ist die Datenrate 90 mal höher,
da ist die Dauer vom MasterRequest und Warten auf die Vorbereitung der
Daten einfach nicht zu vergleichen mit der Dauer des Telegramms alleine
bei UART.
Und, wie gesagt, Slave schreibt irgendetwas != 0x80 in SPDR, beginnt
die Ausführung, wenn fertig, wird 0x80 in SPDR geschrieben.
Fertige Daten werden auf Request vom Master aus Buffer per IndexRegister
ausgegeben.
Dauert wieder ganze 11us, insgesammt mit Bearbeitung der Daten etwa 950us.
In dieser Zeit sind andere Interrupts ganze 22us gesperrt, entspricht
etwa 2% der Zeit.
Bei UART sind es 950us Request, 950us Antwort, 930us um Daten zu holen,
bzw. zu bearbeiten, insgesammt etwa 2800us.
Und du willst mich überzeugen, daß UART (oder I2C) irgendwie besser,
entspannter oder schneller ist?
Als ich dem Datenblatt der AVRs das hier entnommen hab:
"SPI hat keinen Sendepuffer. Der Slave hat maximal 0,5 SPI-Takte Zeit, um in den Interrupt zu springen und das SPDR zu laden."
Da habe ich nie auch nur ansatzweise überlegt, das AVR-SPI als Slave zu benutzen. Das konnte einfach nur ein Krampf werden.
Und es gibt hier massenweise Threads, die das bestätigen. Ob es je einer geschafft hat oder ob alle aufgegeben haben, läßt sich ja nicht feststellen.
Als ich dem Datenblatt der AVRs das hier entnommen hab:
"SPI hat keinen Sendepuffer. Der Slave hat maximal 0,5 SPI-Takte Zeit,
um in den Interrupt zu springen und das SPDR zu laden."
Da habe ich nie auch nur ansatzweise überlegt, das AVR-SPI als Slave zu
benutzen. Das konnte einfach nur ein Krampf werden.
Und es gibt hier massenweise Threads, die das bestätigen. Ob es je einer
geschafft hat oder ob alle aufgegeben haben, läßt sich ja nicht
feststellen.
Ich kann wirklich nicht verstehen warum man ein SPI, oder I2C, Slave Projekt auf einem AVR machen will. Da gibts wirklich bessere Alternativen.
Es wird gleichwohl möglich sein.
UART hat beim AVR immerhin ein Byte Puffer für beide Richtungen (das UDR Register und die beiden Schieberegister auf die man IMHO gar keinen direkten Zugriff hat).
Meiner Meinung nach hat der Einsatz von Gepufferten USART Datenaustausch den großen Vorteil, den Datenaustausch natürlich ablaufen zu lassen. Das USART selber steuert die Zeitpunkte des TX Registers wenn es durch Interrupt nach neurn Daten fragt. Das entkoppelt den Rest des Programms und verhält sich sehr robust. Wenn der Master Zeit getriggert ist, dann ergeben sich diese Datenaustausche in regelmäßiger Zeitfolge. Wenn man hohe Baudraten verwendet, geht das ruckzuck. Kleine Unregelmäßigkeiten durch andere Interrupts spielen keine Rolle. Einsatz der gleichen Datenstrukturen eliminiert polling, weil sowohl Master und Sklave mit den identischen Datenstrukturen arbeitet und direkt die wichtigsten Datenelemente ohne Parsing bearbeiten kann. Die Zuverlässigkeit anhand vorangegangener Projekte hat sich bestätigt. Bei Microcontrollern mit mehreren USARTs braucht man nicht auf I2C oder SPI zugreifen, die oft schon mitverwendet werden.
Viele Wege führen nach Rom. Trotzdem hat sich dieses Verfahren zumindest bei uns in solchen Projekten sehr bewährt und nie irgendwelche Überraschungen verursacht. Läuft wie ein Uhrwerk.
warum dann überhaupt 2 µC und nicht einer der beides kann?
Dann stellt sich die Frage überhaupt nicht.
Vielleicht weil ein einzelner acht ADC Kanäle hat und er sechzehn braucht?
Und vielleicht weil ein Controller mit sechzehn ADC Eingängen deutlich mehr kostet als zwei mit jeweils acht?
Da habe ich nie auch nur ansatzweise überlegt, das AVR-SPI als Slave zu
benutzen. Das konnte einfach nur ein Krampf werden.
Und es gibt hier massenweise Threads, die das bestätigen. Ob es je einer
geschafft hat oder ob alle aufgegeben haben, läßt sich ja nicht
feststellen.
Ja, ist mir damals gelungen, aber war ne grenzwertige Frickelei.
Wenn Daten vollständig empfangen wurden gibt's einen Interrupt.
Das ist nicht trivial. Und meistens bringts auch nichts.
Telegramme unterschiedlich lang, einzelne Zeichen verloren oder zuviel, egal. im Embedded-Bereich sind kleine Fifos oder DMA am Eingang interessant, wenn Interrupts zu lange gesperrt sind. Also z.B. 100µs bei 115.2.
Gerade für einen Anfänger erhöht sich die Komplexität deutlich.
Als ich dem Datenblatt der AVRs das hier entnommen hab:
"SPI hat keinen Sendepuffer. Der Slave hat maximal 0,5 SPI-Takte Zeit,
um in den Interrupt zu springen und das SPDR zu laden."
Aha, sicher, aber nur wenn der Master das ganze Telegramm auf einmal
per DMA rausfeuern würde.
Da die AVRs DMA aber nicht können, ist es kein Argument.
Und selbst dann stimmt es nicht, denn der Inhalt vom SPDR wird erst
nach dem Empfang von nächsten Byte verändert, nicht während des Empfangs.
EmpfangsBuffer ist " Double buffered ", sagt Atmel, bestätige ich.
Und der Master muß SPDR genauso lesen und schreibenwie der Slave auch.
Denn wenn der Master die Antwort vom Slave irgendwie auswerten will,
muß er empfangenes Byte auch irgendwo reinschreiben und nächstes Byte
von irgendwoher auslesen.
Das dauert auch gewisse Zeit, meinst du nicht auch?
Da habe ich nie auch nur ansatzweise überlegt, das AVR-SPI als Slave zu
benutzen. Das konnte einfach nur ein Krampf werden.
Und es gibt hier massenweise Threads, die das bestätigen. Ob es je einer
geschafft hat oder ob alle aufgegeben haben, läßt sich ja nicht
feststellen.
Ich habe es geschafft.
Und zwar wird SOF gesendet, SPDR beim Master auf 0x80 geprüft, wenn ja,
wird noch ein bisschen (10-16Cy) gewartet und weiter gesendet,
wenn nicht, wird nach gewisser Zeit wieder SOF gesendet.
Erstes Byte (mit Einsprung in die INT Routine) wird nach 6Cy gelesen.
Danach noch 16Cy für push, laden der Indexregister usw., deswegen die
etwas größere Pause zwischen SOF und restlichen Bytes.
Die restlichen Bytes brauchen beim Slave jeweils 11Cy with SPDR lesen,
Byte ins RcvBuffer schreiben, SPDR aus dem SndBuffer neu laden und
Telegramm aufs Ende prüfen.
Geschrieben noch vor xx Jahren, Master hatte ein GraphLCD mit Touch,
Slave hatte Sensoren und Aktuatoren.
Funktionierte einwandfrei, bis zum runterfallen von der Wand.
Das ist nicht trivial. Und meistens bringts auch nichts.
Ach ich weiß nicht, ich find's so praktisch das ich es bei jeder sich bietenden Gelegenheit in MicroPython benutze. Eine nette kleine Klasse drum herum gewickelt und fertig.
Nööö, tu ich doch gar nicht.
Wenn c-hater (auf seine höfliche Art) auf irgendein Beitrag
von mir reagiert, dann antworte ich darauf.
Entweder bin ich im Recht, oder er ist es, nicht so wichtig.
Peter D. ist hier anderer Meinung als ich, er hat seine Argumente,
ich habe meine, OK, dafür ist dieses Forum auch da.
Aber diese miese, feige Art mit Minusen nervt mich ziemlich.
Obwohl, jetzt nicht mehr so viel, weil ich sehe, daß keinervon denen zu einer halbwegs vernünftigen Antwort fähig ist.
Ich bewerte nur selten, hier in diesem Thread habe ich einmal + vergeben.
Ich sehe die Bewertung nur als Umfrage an (Zustimmung/Ablehnung) und nicht als persönlichen Angriff. Geht schneller, als einen Kommentar zu schreiben.
Aber diese miese, feige Art mit Minusen nervt mich ziemlich.
Warum eigentlich? Kann es dir nicht egal sein? Wie es schon geschrieben wurde, es gibt genügend, die deine Argumente nachvollziehen können und sie OK finden. Und ja, auch pedas Argumente kann ich Nachvollziehen und finde auch diese OK.
Lass dich doch nicht von so einem völlig nutzlosen Bewertungssystem triggern, die nur wegen so nem Quatsch wie FB und Co irgendwann mal in die Forensoftware implementiert wurden. Meines Erachtens nach sollte man diese Funktionalität abschalten, das braucht kein Mensch.
Aber diese miese, feige Art mit Minusen nervt mich ziemlich.
Du machst es Dir allerdings auch sehr einfach.
SPI-Slave ist ein Exot. Punkt. (I2C als Slave natürlich genauso)
Anfänger (wie der TO) sind damit überfordert, Experten nutzen es nur selten. Die Vorteile sind unbestritten (Datenmenge, -Geschwindigkeit, kein präziser Takt, ..). Du gehst jedoch auf keinen Nachteil ein, hier nur mal ein paar (die auch nicht immer gelten):
3 statt 2 Leitungen
Anfälliger für Spikes/Doppelimpulse bei Flankenwechseln
begrenzte Zeit bis zur Antwort
begrenzte Tool-Verfügbarkeit (HW/SW für PC) zum Mitlesen, testen
weniger Beispielcode
kann nur auf Anforderung senden
Durch Taktrate begrenzte Leitungslänge
Eine typische erste Kommunikation uC <-> uC sieht eher so aus, dass man auf beiden Chips den Uart zum laufen bringt per PC, dann Sende/Empfangsbuffer baut. Dann schickt man Kommandos (klartext, nummeriert, einzelne Zeichen) und wartet auf Antworten. Ob die Reaktion 10µs, 100ms oder 10s dauert (wegen anfängertypischer Delays) ist völlig egal. Ob das Signal über Glasfaser 100km läuft, auch. Variable Telegrammlängen: kein Problem. Schlechte Leitungsanpassung / Doppelimpulse: Beim Uart reduziert man die Baudrate, bei SPI hat die Baudrate keinen Einfluss.
Bei Dir liest es sich, als wäre SPI-Slave für den TO eine Alternative. Nein, ist es nicht. Es erfordert ungleich mehr Erfahrung, HW & SW.
Obwohl, jetzt nicht mehr so viel, weil ich sehe, daß keiner
von denen zu einer halbwegs vernünftigen Antwort fähig ist.
Wie kannst du die denn erkennen? Ich beispielsweise haben keinen Deiner Kommentare bewertet.
Eine nette kleine Klasse drum herum gewickelt und fertig.
Wie löst Du denn konkret das referenzierte Problem?
Du meinst welcher Transport-Mechanismus?
UART! Geschwindigkeit dabei so hoch wie nötig und so niedrig wie möglich.
Die UART->USB Wandler hier können von 50,75,110,…b/s bis 4Mb/s wenn's in Richtung PC geht.
Und wenn's sowieso nur ›onboard‹ ist, dann muss man selbst darüber kaum noch nachdenken.
Software:
Ein array für die Sendedaten anlegen.
Eine Klasse instanziieren und UART, array Adresse und ›callback-wenn-fertig‹ übergeben.
Senden.
Instanziieren geht aber auch ohne callback, da fragt man die Klasse wenn nötig nach einem Fertig-Flag.
Bei Dir liest es sich, als wäre SPI-Slave für den TO eine Alternative.
Nein, ist es nicht. Es erfordert ungleich mehr Erfahrung, HW & SW.
Wobei das hardwaremäßig bei zwei Controllern, die offenbar direkt nebeneinander sitzen, sowohl mit UART als auch SPI als auch I2C kein Unterschied macht.
Etwas OT:
Vielleicht noch ein Vorteil (jetzt nicht auf den OP bezogen) von SPI:
Damit kann man sehr einfach Module bauen, die über keine eigene "Intelligenz" (=Controller) verfügen müssen, bspw. einfache I/O-Module mit wenigen weit verfügbaren Logikbausteinen. Wir haben hier ein Schaltschrankbussystem mit 16 Plätzen auf SPI-Basis entwickelt mit Modulen ganz ohne eigenen Takt und mit äußerst sparsamer Hardware (bspw. sechs 74er-Bausteine für 2x16 I/O-Leitungen + Treiber) per seriellen Schieberegistern. Dadurch, dass auf diesen Modulen sich nichts "bewegt", wenn sie nicht angesteuert werden, sind sie äußerst robust gegenüber Störungen.
So hat jedes Bussystem seine Vor- und Nachteile :-)
nein, Telegramme unterschiedlich lang, einzelne Zeichen verloren oder zuviel, egal.
Da mir zumeist beide Controller gehören und auch von mir programmiert werden, lege ich das Protokoll fest.
Telegramme unterschiedlich lang
Natürlich mit fester Größe oder als zwei Pakete, ein kurzes mit der Länge und Prüfsumme und ein darauf folgendes passendes Datenpaket.
einzelne Zeichen verloren oder zuviel
Auf einer Platine? Im Millimeter Abstand? Da wäre es an der Zeit DARÜBER nachzudenken.
Bei größeren Entfernungen? Klar, da man weiß wie groß die Datenmenge ist, kann man von vorn herein einen passend ablaufenden Timer zum Schutz starten (wenn man's denn wirklich braucht).
Es funktioniert einfach wenn man's richtig macht. Und es braucht nahezu keine CPU Zeit (und Aufmerksamkeit). Also ich mag das.
Und ob man das jetzt mit INTERCAL, MicroPython oder in C++ oder C oder auch in Assembler löst, das ist gehupft wie gesprungen. ;-)
Nachsatz: Die Vorschau-Funktion der Forensoftware und deren Abbildung der Realität ist eine wirklich geniale Implementierung. Erinnert an Gemälde von Hieronymus Bosch…
SPI-Slave ist ein Exot. Punkt. (I2C als Slave natürlich genauso)
Anfänger (wie der TO) sind damit überfordert, Experten nutzen es nur
selten. Die Vorteile sind unbestritten (Datenmenge, -Geschwindigkeit,
kein präziser Takt, ..). Du gehst jedoch auf keinen Nachteil ein, hier
nur mal ein paar (die auch nicht immer gelten):
3 statt 2 Leitungen
Anfälliger für Spikes/Doppelimpulse bei Flankenwechseln
Durch Taktrate begrenzte Leitungslänge
Bei der Leitungslänge wie beim TO kein wirklicher Nachteil.
begrenzte Zeit bis zur Antwort
Du meinst zwischen Slave Empfang und neues Byte ins SPDR schreiben?
Auch kein wirklicher Nachteil, da der Master auch ein Byte empfängt.
Und dieses muss auch irgendwo geschrieben werden, neues Byte von
irgendwo gelesen und ins SPDR geschrieben werden.
begrenzte Tool-Verfügbarkeit (HW/SW für PC) zum Mitlesen, testen
weniger Beispielcode
Habe auch nie behauptet, dass es für Anfänger geeignet ist, es ging
ums Prinzip.
kann nur auf Anforderung senden
Ja, das ist auch für mich ein Riesennachteil und der Hauptgrund warumich nicht von SPI begeistert bin.
Wie kannst du die denn erkennen? Ich beispielsweise haben keinen Deiner
Kommentare bewertet.
Ich bewerte fremde Post auch nicht, außer wenn der Beitrag wirklich
hilfreich ist.
Dann gibt es 1 Plus, weil so ein Beitrag einfach keine Antwort bedarf.
Und wenn ich meine, dass irgendwelcher Beitrag nicht richtig oder sogar
shit ist, dann schreibe ich das auch, mit meinem Namen und meinen
Argumenten.
Diese anonymen Feiglinge nerven mich, assoziert mich aufDenunziation.
Auf einer Platine? Im Millimeter Abstand? Da wäre es an der Zeit DARÜBER
nachzudenken.
Dieser Anspruch besteht allerdings schon bei Verwendung eines ISP, wenn Du nach dem Programmieren einer Seite nicht sauber neu synchronisierst (entweder kompletter Reset beider Seiten oder Fehlerhandling über Telegrammrahmen).
… wenn Du nach dem Programmieren einer Seite nicht sauber
neu synchronisierst (entweder kompletter Reset beider Seiten
oder Fehlerhandling über Telegrammrahmen).
So isses. Man kann solch ein System beliebig komplex und (nahezu)** beliebig fehlertolerant gestalten.
Ja, natürlich! Hier ist ein kurzer Text auf Deutsch:
"Das Wetter heute ist ziemlich schlecht. Es ist bewölkt und es regnet immer wieder. Ich denke, ich werde den Tag drinnen verbringen und ein gutes Buch lesen. Vielleicht mache ich später auch eine Tasse Tee. Ich hoffe, dass das Wetter morgen besser wird, damit ich draußen spazieren gehen kann."
Please write in German complete sentences with this topics:
My impression only trollpostings left since the release of chatgpt
Normal people do not use or even need it anymore
Chatgpt way more polite, stays on topic and gives useful answers.
"Mein Eindruck ist, dass seit der Veröffentlichung von ChatGPT hier nur noch Troll-Postings übrig geblieben sind und normale Leute es nicht mehr verwenden oder gar benötigen, da ChatGPT wesentlich höflicher bleibt, sich auf das Thema konzentriert und nützliche Antworten liefert."
Now add a rant with the word Platzhirsche
"Und trotzdem gibt es immer noch einige Platzhirsche, die sich weigern, ChatGPT zu nutzen und weiterhin hier trollen. Aber warum sollten wir uns von ihnen die Stimmung verderben lassen? Es ist an der Zeit, dass wir sie ignorieren und uns auf die sinnvollen Gespräche konzentrieren, die ChatGPT ermöglicht. Die Zeiten haben sich geändert, und es ist an der Zeit, dass auch diese Platzhirsche sich daran anpassen."