Forum: Mikrocontroller und Digitale Elektronik Eigenes Serielles "Protokoll" - Meinungen?


von M. P. (phpmysqlfreak)


Angehängte Dateien:

Lesenswert?

Guten Abend,

ich habe mich heute mal ein Wenig hingesetzt, und mir Gedanken zu einem 
"Protokoll" gemacht.

Beide Routinen benötigen in einem Tiny48 zusammen 194Byte.
Die Takt-Rate ist nicht Fest und variiert während der Übertragung (wenn 
nur LOW oder nur HIGH übertragen wird, ist sie Jedoch Konstant.)

Der Angehängte Code beeinhaltet NUR die Sende-Routine und den 
Empfangs-Interrupt-Vektor. Es wird KEIN lauffähiges Programm erzeugen, 
ohne einen Interrupt zu konfigurieren und zu aktivieren.

Meine Bitte: Keine Stellungnahmen zur Sinnhaftigkeit im Angesicht von 
vorhanden Seriellen Übertragungsmethoden wie SPI, I2C oder die UART.

Ich möchte jetzt Wissen, ob der Code verständlich ist (Genug Kommentare 
sind vorhanden, denke ich) und ob es in der Art funktionieren kann. - 
Habe ich selbst richtig gerechnet, als ich die Zyklen addiert habe (für 
den besten Fall)?

Mangels µC konnte ich bisher noch nichts testen. - Habe noch nicht 
nachbestellt. -.- ;)

Gruß,

Marcel

: Verschoben durch User
von Sebastian .. (zahlenfreak)


Lesenswert?

Die Frage ist doch erstmal, was du mit deinem Protokoll besser machen 
willst. Ich hab die sourcen jetzt nur überflogen, aber auf die schnelle 
hab ich keinen großen Vorteil gesehen. Mit was eigenem bist du ja 
erstmal allein auf deiner Insel, da sollten schon wichtige Gründe für 
sprechen.

Erläutere dein Protocoll/Codierung und die Gedanken dahinter doch mal in 
Text. Das geht besser zu lesen als Quelltext, der zudem ja fehlerhaft 
sein könnte ;)

Sebastian

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Du solltest schon eine funktionale Erklärung unabhängig vom 
Programmcode/-Kommentaren bringen. NUR im Code zu dokumentieren, ist ne 
ganz üble auszuradierende Angewohnheit.

Nimms mir nicht übel. Als Projektleiter würde ich dir das so nicht 
abnehmen und erstmal nix zahlen.

von M. P. (phpmysqlfreak)


Lesenswert?

Sebastian ... schrieb:
> Die Frage ist doch erstmal, was du mit deinem Protokoll besser machen
> willst.

Mein Ansatz war nicht produktiv oder wirtschaftlich angedacht, daher 
habe ich auch nicht versucht, irgendwas besser zu machen.
Mir selbst geht es um den Lern-Erfolg - kann ich Abläufe in geeigneter 
logischer Weise auch wie erwartet in einem Programm umsetzen.

Sebastian ... schrieb:
> Erläutere dein Protocoll/Codierung und die Gedanken dahinter doch mal in
> Text.
 --- und ---
Abdul K. schrieb:
> Du solltest schon eine funktionale Erklärung unabhängig vom
> Programmcode/-Kommentaren bringen. NUR im Code zu dokumentieren, ist ne
> ganz üble auszuradierende Angewohnheit.

Dem Wunsch werde ich morgen nachkommen - ich brauche gleich erstmal 
meinen Schlaf. ;)
Aber ich muss Abdul recht geben - nur im Code zu dokumentieren ist nicht 
wirklich schön. Daher folgt morgen eine Beschreibung dessen, was ich 
versucht (oder geschafft?) habe, in Assembler um zu setzen.

Auch die folgende Aussage kann ich voll und ganz nachvollziehen. Ich 
würde selbst auch so handeln. :D

Abdul K. schrieb:
> Nimms mir nicht übel. Als Projektleiter würde ich dir das so nicht
> abnehmen und erstmal nix zahlen.

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Klingt gut.

Was mich verwundert <ich verstehe nix von AVR>, du erwähnst "Zyklen 
zählen". Das macht nur Sinn für asynchrone Prozesse. Du hast doch nicht 
etwa gedacht, du kannst zwei AVR ohne Taktsynchronisierung erfolgreich 
zur Zusammenarbeit bewegen? Irgendeine Synchronisierung muß vorhanden 
sein! Entweder auf Taktebene der CPU oder im Datenprotokoll.

siehe auch Beiträge zu "Wie genau muß mein UART sein?". In einem dieser 
Threads hatte ich es ganz exakt vorgerechnet.

von M. P. (phpmysqlfreak)


Lesenswert?

Abdul K. schrieb:
> Was mich verwundert <ich verstehe nix von AVR>, du erwähnst "Zyklen
> zählen". Das macht nur Sinn für asynchrone Prozesse. Du hast doch nicht
> etwa gedacht, du kannst zwei AVR ohne Taktsynchronisierung erfolgreich
> zur Zusammenarbeit bewegen? Irgendeine Synchronisierung muß vorhanden
> sein! Entweder auf Taktebene der CPU oder im Datenprotokoll.

Damit meine ich die Takt-Zyklen der CPU.
Ich habe mir selbst keine Gedanken zur Kommunikation von 2 µC gemacht, 
die mit einem unterschiedlichen Takt arbeiten, da ich persönlich 
meistens den internen RC-Oszillator der AVRs verwende. - Abgesehen von 
Anwendungen zur Kommunikation mit einem PC oder ähnlichem (UART).
Ich habe lediglich Warte-Takte/Schleifen eingefügt, damit der jeweils 
andere rechtzeitig reagieren kann.

Beide Teilnehmer "synchronisieren" sich über einen Daten-Takt. - Aber 
mehr dazu in ein paar Stunden. ;)

In diesem Sinne: erst einmal gute Nacht.

Gruß,

Marcel

von M. P. (phpmysqlfreak)


Lesenswert?

Hallo,

hier ist die funktionale Erklärung bzw. die Beschreibung dessen, was ich 
geplant habe.

Es handelt sich um eine serielle Schnittstelle, die nicht mit den bisher 
bekannten kompatibel ist. Mein Ziel dabei ist es, aus Fehlern zu lernen. 
Seien es logische Fehler oder versteckte Fehler, weil ich an manchen 
Stellen nicht zu ende Gedacht habe. Die Übertragung findet dabei NICHT 
im Voll-Duplex-Betrieb statt.

Hardware-Technisch gibt es 4 Leitungen:
Takt-Leitung
Handshake-Leitung
Daten-Eingang
Daten-Ausgang

Initial soll das Takt-Signal auf LOW gehalten werden. (Pull-Down, da 
beide Teilnehmer den Takt als Eingang sehen, dieser aber nicht floaten 
soll.)
Die Handshake-Leitung wird mithilfe eines Pull-Ups auf HIGH gehalten.
Daten-Eingang ist als Eingang konfiguriert, welcher Aufgrund der 
direkten Verbindung mit dem Daten-Ausgang des Gegenübers keinen Pull-Up 
oder Pull-Down benötigt (abgesehen von galvanischer Trennung).
Der Daten-Ausgang ist fest als Ausgang konfiguriert.

In einem Rutsch sollen immer 8 Bit übertragen werden, welches ich so zu 
realisieren versucht habe:

Aus Sicht des Senders:
Initial-Zustand:

Der Takt ist LOW, Handshake ist HIGH. - Daten sind irrelevant.
Wenn nun ein Teilnehmer etwas senden möchte, prüft er den korrekten 
Zustand von Takt und Handshake (CLK: 0 / HS: 1). Sollte das nicht der 
Fall sein, bricht er die Übertragung ab, und setzt ein Error-Flag, dass 
es ein Problem VOR der Übertragung gab.
Danach wird der Handshake vom Sender selbst auf 0 gezogen, welches der 
Empfänger via Pin-Change Interrupt oder entsprechend schnellem Polling 
erkennen kann.

(Wiederholung für jedes Bit:)
Nun wird das zu sendende Bit auf den Ausgang gelegt. Sobald das 
geschehen ist, wird der Takt auf Ausgang geschaltet, und auf HIGH 
gezogen. Unmittelbar nach dem Anheben des Takt-Pegels wird der Handshake 
zum Eingang umgeschaltet.
Der Handshake-Pegel wird nun (für einstellbare Zeit) überwacht, da der 
Empfänger durch ein kurzes LOW an dieser Leitung den Empfang des Bits 
bestätigen soll. (Auf Ausgang schalten, LOW ausgeben, etwas warten, auf 
Eingang schalten)
Wenn der Empfang bestätigt wurde, oder eine maximale Wartezeit 
überschritten ist, wird der Takt wieder auf LOW geschaltet und als 
Eingang konfiguriert.
(Ende Wiederholung für jedes Bit!)

Danach ist das Byte gesendet.
Sollte ein Fehler auftreten, wird das durch ein entsprechend gesetztes 
Bit im Fehler-Register "DERR" gekennzeichnet. - Zur Zeit werden 'nur' 
Handshake-Fehler eingetragen: Fehler vor oder Fehler während des 
Sendens.

Aus Sicht des Empfängers:

Der Takt ist LOW, Handshake ist HIGH. - Daten sind irrelevant.
Im Empfänger wird das normale Programm abgearbeitet.
Ein Wechsel der Handshake-Leitung auf LOW wird erkannt, und die 
Interrupt-Vektor-Routine wird ausgeführt:

(Wiederholung für jedes Bit:)
Warten auf HIGH-Pegel auf der Takt-Leitung. Dauert das Warten zu lange, 
Fehler melden und abbrechen.
Wenn ein HIGH-Pegel auf der Takt-Leitung erkannt ist, wird ein Bit am 
Eingang eingelesen. Das Einlesen wird durch ein "kurzes" LOW an der 
Handshake-Leitung bestätigt (mindestens 8 CPU-Takte des Senders).
Nun das entsprechende Bit "extrahieren" und an die richtige Stelle im
DATAIN-Register speichern. Dort befinden sich nach dieser Schleife die
Empfangenen Daten.
(Ende Wiederholung für jedes Bit!)

Danach gilt das Byte als empfangen.
Sollte ein Fehler auftreten, wird das durch ein entsprechend gesetztes 
Bit im Fehler-Register "DERR" gekennzeichnet. - Zur Zeit wird 'nur' ein 
Fehler eingetragen und erkannt: Das Taktsignal erscheint "zu spät".

Keine Gedanken gemacht habe ich mir über Prüfsummen oder ähnliches.
Als "Zähler" der Schleife für 8 Bit habe ich folgendes genutzt:

Vorladen eines Registers mit 0x80 (0b 1 0 0 0 0 0 0 0).
Damit habe ich gleich die richtige Position des ersten übertragenen Bits 
(MSB First). Vor der Wiederholung für das nächste Bit wird dieses 
Register um ein Bit nach rechts geschoben (0b 0 1 0 0 0 0 0 0) und ich 
habe wieder die Maske für das "richtige" Bit.
Wenn alle 8 Bit durchlaufen sind, wird 0b00000001 wieder OHNE Carry nach 
rechts geschoben und wird damit 0.
Mit der Hilfe von TST erfahre ich, ob das Register 0 ist, oder nicht. 
Hat es 0 erreicht, sind alle Bits gesendet, und die Routine/Interrupt 
kann Ordnungsgemäß beendet werden.


Ich hoffe, dass es ausreichend erklärt ist. Sollten noch Fragen 
aufkommen, werde ich Sie natürlich beantworten. Ich möchte die Hilfe 
schließlich von euch haben, und liefere dementsprechend so gut wie 
möglich die "geforderten" Informationen.

/OFFTOPIC:
Im Angesicht mancher Antworten auf nicht ausreichend konkrete Fragen 
versuche ich mein bestes. Herumtrollen oder beleidigen ist ja nicht Sinn 
solcher Foren.

Gruß,

Marcel

von Konrad S. (maybee)


Lesenswert?

Wenn der Sender aufgrund einer Störung den vom Empfänger gesendeten 
Handshake-Impuls nicht sieht, kann der Sender das Senden abbrechen. Der 
Empfänger wartet jetzt auf den nächsten Takt-Impuls und läuft in einen 
Timeout und bricht ebenfalls ab. So weit, so gut. Passiert das aber beim 
letzten Bit ist für den Empfänger alles OK, der Sender hingegen denkt, 
dass ein Problem vorliegt.
Diese Art von Übertragungsfehler kann man (vermutlich erst) auf der 
nächsthöheren Übertragungsschicht behandeln (Sequenznummern, Quittungen, 
Wiederholungen).

von M. P. (phpmysqlfreak)


Lesenswert?

Konrad S. schrieb:
> Passiert das aber beim
> letzten Bit ist für den Empfänger alles OK, der Sender hingegen denkt,
> dass ein Problem vorliegt.

Das heißt, ich müsste noch ein weiteres Bit nach dem Byte übertragen, 
welches Signalisiert, dass der Sende-Vorgang nicht unterbrochen wurde. 
- Danke für diese Rückmeldung, diesen Fall hatte ich nicht betrachtet.

von Konrad S. (maybee)


Lesenswert?

Marcel Papst schrieb:
> noch ein weiteres Bit

Da kann das gleiche Problem auftreten. Deswegen der Satz mit der 
nächsthöheren Übertragungsschicht.

von M. P. (phpmysqlfreak)


Lesenswert?

Ja, du hast recht. :D

Ich werde es trotzdem als Option einbauen. Damit kann man selbst 
entscheiden, ob der Sender einfach nochmal sendet, oder der Empfänger 
das "Paket" neu anfordert. Denn dann geht es darum, wer den "Fehler" 
bearbeitet, oder ist da wieder ein Fehler drin? ;)

Gruß,

Marcel

von spess53 (Gast)


Lesenswert?

Hi

Du kannst übrigens deinen Code kürzen, in dem du die unnötigen 'tst' 
Befehle weg lässt. 'dec', 'andi und 'and' setzen das Z-Flag bereits.

MfG Spess

von Konrad S. (maybee)


Lesenswert?

Marcel Papst schrieb:
> geht es darum, wer den "Fehler" bearbeitet

Hmmmm. In der Situation "A hört B aber B hört A nicht" kommt B zur 
Erkenntnis, dass er seine Nachricht wiederholen muss - was aber falsch 
ist. A könnte - eine gewisse Intelligenz vorausgesetzt - erkennen, dass 
B ihn nicht hört, weil er ständig die gleiche Nachricht erhält. Die 
Sequenznummer bleibt bei einer Wiederholung gleich, bei einer neuen 
Nachricht wird sie hochgezählt.
... und irgendwann landest du bei TCP/IP und einem x-GHz-Prozessor für 
eine simple Messwert-Übertragung. ;-)
Es kommt eben immer darauf an, welche Folgen Übertragungsfehler nach 
sich ziehen. Daran sollte sich der Aufwand für Gegenmaßnahmen 
orientieren.

von Marcel Papst (Gast)


Lesenswert?

spess53 schrieb:
> Hi
>
> Du kannst übrigens deinen Code kürzen, in dem du die unnötigen 'tst'
> Befehle weg lässt. 'dec', 'andi und 'and' setzen das Z-Flag bereits.
>
> MfG Spess

Das hört sich gut an. Dann weiß ich das für die Zukunft. Ich war mir 
einfach nicht sicher und - schande über mich - zu faul, es nach zu 
schauen. Ich habe daher das TST einfach gesetzt.

Konrad S. schrieb:
> Es kommt eben immer darauf an, welche Folgen Übertragungsfehler nach
> sich ziehen. Daran sollte sich der Aufwand für Gegenmaßnahmen
> orientieren.

Ich würde es zur Zeit nur einsetzen, um wirklich langsame und zeit 
unkritische Signale zu übertragen. (Maximal 4Hz)
Gesendet werden soll bei Zustandswechsel von einem Pin eines Kompletten 
8-Bit-Ports. Der Sender soll noch ein LCD bekommen, dessen Inhalt 2 von 
8 Texten anzeigt. Dabei sollen noch 2 Tasten entprellt werden, um diese 
Texte umzuschalten. - Das wäre zur Zeit mein erster Versuch mit dieser 
Schnittstelle.
Dabei wäre es aber unkritisch, wenn eine Fehl-Übertragung vorkommt. Es 
gibt es keine Fehler-Kontrolle, die Daten sollen AsTheyAre mit einem 
Timestamp auf einer SD-Karte gespeichert werden.

PS: Schreibe gerade nicht von zu hause.

von Abdul K. (ehydra) Benutzerseite


Lesenswert?

Ich kann immer noch nicht einen wirklichen Vorteil deines Verfahrens 
erkennen. Durch das Statement 'bitte keinen Vergleich', darf ich 
allerdings auch nicht mehr fragen, oder? Klingt irgendwie dogmatisch.

Das Thema ist etwas ausgelutscht. Man sollte die gängigen Busse kennen: 
i2c/smBUS/TWI usw., SPI in den vier Formen, UART, 1-wire und vielleicht 
noch die spezielleren aus Audio und Netzwerktechnik. Nicht unbedingt die 
Details, aber genug um die richtige Entscheidung für eine Anwendung zu 
treffen.

Dann die nächste Übertragungsschicht: HDLC, TCP/IP

und natürlich auf dem low-level Strom, Spannung und Timing, Fehlerschutz 
ESD, EMV usw. Damit einhergehend welche Chips verfügbar sind.

Was die Fehlererkennung und das Problem der Hidden Stations angeht: MACA 
von Phil Karn lesen!!!!! Mit diesem Stichwort findet man dann auch viel 
weiteres per Google.

von M. P. (phpmysqlfreak)


Lesenswert?

Abdul K. schrieb:
> Ich kann immer noch nicht einen wirklichen Vorteil deines Verfahrens
> erkennen. Durch das Statement 'bitte keinen Vergleich', darf ich
> allerdings auch nicht mehr fragen, oder?

Doch, das darfst du. Es sollte nur nicht von Anfang ungehemmt auf die 
Vielzahl der seriellen Schnittstellen verwiesen werden. - Konstruktiv 
ist dies kein Problem, doch leider kenne ich eine Großzahl von Themen, 
in denen ein paar Antworten später keine richtige Diskussion mehr zu 
finden ist.

Zu dem Punkt mit den Vorteilen:
Marcel Papst schrieb:
> Es handelt sich um eine serielle Schnittstelle, die nicht mit den bisher
> bekannten kompatibel ist. Mein Ziel dabei ist es, aus Fehlern zu lernen.
> Seien es logische Fehler oder versteckte Fehler, weil ich an manchen
> Stellen nicht zu ende Gedacht habe. Die Übertragung findet dabei NICHT
> im Voll-Duplex-Betrieb statt.

Dabei möchte ich keine Vorteile erlangen, sondern lediglich für mich 
feststellen, in wiefern ich das Gedachte umgesetzt habe, und welche 
Fehler ich dabei gemacht habe.

Gruß,
Marcel

von Peter D. (peda)


Lesenswert?

Marcel Papst schrieb:
> Hardware-Technisch gibt es 4 Leitungen:
> Takt-Leitung
> Handshake-Leitung
> Daten-Eingang
> Daten-Ausgang

Sind mir zuviel Leitungen.
Dann kann ich ja gleich das SPI nehmen.


Peter

von M. P. (phpmysqlfreak)


Lesenswert?

Peter Dannegger schrieb:
> Sind mir zuviel Leitungen.
> Dann kann ich ja gleich das SPI nehmen.

Ja, das ist korrekt. Da kann ich Daten auch gleichzeitig einlesen, 
während ich sende. ;)

von Purzel H. (hacky)


Lesenswert?

Bitte den Gnd nicht vergessen. Dann waeren's dann 5 Leitungen

von Purzel H. (hacky)


Lesenswert?

Ohne mir den ASM code angeschaut zu haben... sollte man erstmal mit 
einem Konzept un den Anforderungen kommen. Wieviele Stationen sollten 
teilnehmen? Sind die Stationen statisch, oder dynamisch adressiert? Sind 
die Packete gleich oder verscieden lang? Muss eine Meldung quittiert 
werden? Sind die Stationengleichwertig, oder gibt es einen Chef? Was 
soll bei einem Uebertragungsfehler geschehen? Liegt die Prioritaet auf 
Durchsatz oder auf Sicherheit?

.. usw

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.