moin, wollte mal nachfragen wie das bei der verbindung eines µC mit PC durch die serielle schnittstelle funktioniert. macht man eine software zur sicheren bzw. quittierten (handshake) übertragung auf der µC seite (assambler) oder kann man z.b. mit visual basic den port auslesen und die handshake methode anwenden? man könnte dann evtuell im vb code eine active x (dll) eines auswerte programms anbinden und diese werte quasi sofort darstellen. mfg florian
Handshake ist i.a. nicht erforderlich, es sei denn, der MC hat sowohl viele Daten zu empfangen kann durch andere zeitkritische Sachen fast völlig blockiert sein. Bei hohen Datenraten ist das auch kritischer als bei den meist üblichen 9600/19200 Baud. MC-Schnittstelle im Interrupt-Betrieb mit entsprechend ausgelegten Datenpuffern, dann gibts i.a. keine Probleme.
Hallo, da ich mich auch für dieses Thema interessiere, wollt ich mal anfragen, ob jemand ein Tutorial oder eine Dokumentation diesbezüglich empfehlen kann. Ich programmiere in Dev-C++ und CodeVision. Die Google Suche hat leider nur jede Menge Offtopic hervorgebracht. Gruß und Dank Gregor
hallo, bei mir ist das der fall das es viele daten sind. möchte messen und die signalwerte sicher an pc schicken, deshalb brauche ich diesen handshake. aber wo programmiere ich das ganze????? am besten, hat nicht jemand schon sowas gemacht vielleicht fällt mir das leichter wenn ich ein beispiel gesehen habe. mfg florian
Wenn Du wirklich sicherstellen willst, daß die Daten am PC ankommen, helfen die Handshake-Leitungen auch nicht. Dazu würde ich die Daten blockweise vom µC zum PC senden. Jeder Block bekommt eine fortlaufende Nummer und eine Prüfsumme. So kann der PC feststellen, ob er alle Blöcke richtig empfangen hat. Fehlerhafte oder verlorene Blöcke kann der PC dann beim µC nochmal anfordern. Gruß, Markus_8051
hallo, ja genau so habe ich es vor. wie meine blöcke aussehen sollen weiss ich auch schon. nur kann ich mir das softwaretechnisch nicht so richtig vorstellen. das senden programmiere ich im µC aber die quittung muss mir der PC geben! und wenn ich diese geschichte im µC programmiere, wocher weiss der PC das er antworten soll und vorallem wie??????? wie macht er das genau? muss ich am PC auch noch eine software programmieren, das die daten die am port liegen gelesen werden sollen usw.?????????? mfg florian
hat keiner mal so was gemacht oder ist das das einfachste auf dieser welt und nur ich verstehe es nicht??? mfg flo
Du solltest etwas intensiver "auf dem Problem rumdenken". Wichtig ist erst mal daß du dir da Gedanken machst wie das ablaufen kann. Guckst du z..B. mal hier, da hatte ich schon mal sowas skizziert: http://www.mikrocontroller.net/forum/read-1-170527.html#171387
Hi Flo, ja, Du müßt auf der PC-Seite auch noch ein Programm haben, welches die Daten vom µC entgegennimmt und entsprechend antwortet. Aber so wie ich das verstanden habe, waren es ja eh irgendwelche Meßdaten, die noch weiter verarbeitet werden sollen. In welcher Sprache programmierst Du auf dem PC? Gruß, Markus_8051
Zur Ergänzung: SICHERLICH mußt du auf beiden Seiten das Hände-Schütteln programmieren. UC will (viele) Daten los werden, und PC will die Daten (vollständig) empfangen. Eine sicher(er)e Übertragung kann man abbilden, indem einzelne Blöcke mit Prüfsummen versehen werden. UC ermittelt eine Prüfsumme und sendet deise (inclusive der Nutzdaten) zu PC. PC wendet auf die uebersandten Nutzdaten den gleichen Prüfsummen-Algorithmus an udn vergleicht die übermittelten mit den selber errechneten Werten. Bei Abweichung wird gemeckert. eine vollständige Übertragung kann man abbilden, indem einzelne Blöcke mit einer fortlaufenden Paketnummer versehen werden. UC hat eine gewisse Puffergröße (z.B. für 10 Datenblöcke). PC quittiert dem UC den erfolgreichen Empfang (bzw. auch den nicht erfolgreichen Empfang) jedes einzelnen Datenblocks incl. dessen Blocknummer. Die sich ergebenden Aktionen sind ziemlich offensichtlich: Wenn Block entsprechend übermittelt werden konnte, dann kann der betreffende Sendepuffer freigeräumt / wiederverwendet werden, ansonsten bleiben die Daten da drin (für späteren neu angeforderten Versand) Gehen Daten kaputt, dann kann der PC das dem UC melden, und UC schickt einfach den betroffenen Block noch mal rüber. Was d nun noch machen must is dir etwas zur eigentlichen Flusskontrolle zu überlegen. Zuerst mußt du überlegen welches Verfahren du haben möchtest, wer also "der Treibende" ist: Da gibts 2 Mitspieler: UC und/oder PC. Es ergeben sich folgende Möglichkeiten: A) UC sendet (unaufgefordert) immmer von sich aus Daten, sobald ihm danach ist. PC schickt Rückmeldung an UC, wenn es ihm zu viel wird. UC berücksichtigt dies und hält erst mal inne mit seiner Senderei. Nach einer gewissen Zeit fragt UC beim PC an, ob dieser wieder Lust zum Datenempfang hat. B) PC ist die treibende Kraft und fordert vom UC "immer neue Datenpakete". UC befriedigt die Datenanfragen (so er welche hat), bzw. teilt dem PC mit "hab grad nix" C) eine Kombination aus A) und B) Ich hoffe nun hast du schon mal ein paar globale Ideen. In welcher Programmiersprache du das codierst (Basic oder C oder Assembler) ist dann für die weitere Betrachtung deinem persönlichen Geschmack / Geschick überlassen
@Markus_8051 "Aber so wie ich das verstanden habe, waren es ja eh irgendwelche Meßdaten, die noch weiter verarbeitet werden sollen." Grundsätzlich richtig, aber man solte trennen: UC: Datensammlung / Aufbereitung UC: Datentransport / Handshake PC: Datentransport / Handshake PC: Aufbereitung / Präsentation
Hallo, danke für eure hilfe. auf der UC seite programmiere ich mit assambler und PC seite mit VB. meine probleme sind das ich noch nicht viel programmiert habe mit schnittstellen und vorallem nicht in assambler (bin aber fleissig dabei). habe mir das auch schon so überlegt mit diesen blöcken bzw. davon gelesen und versucht in meine applikation zu binden. vielleicht erkläre ich mal was ich mir vorstelle, was ich weiss und wo der knotten sitzt: 1. die daten im UC in diese Blöcke zu packen und z.b. eine crc drüber und die checksumme dran. so dann wäre mein block quasi fertig, wie man das genau in assambler machen soll mit crc und die startkennung&blocknr&status&daten&crc zusammenpacken????was weiss ich????bitte um beispiele am besten. 2.das packet in den ausgangsport und weg damit. 3.mit VB den COM port auszulesen wird schon irgendwie hinhauen. dann daten lesen und den Block zerpflücken, da ich weiss was was ist, über die nutzdaten mein generatorpoly drüberjagen und schauen ob fehlerhaft oder nicht. wenn ok dann daten speichern. aber wo und wie werden die daten zwischengespeichert? sofort in eine datei???? wenn die daten ok sind, was könnte ich am besten zurück schicken? ein ok? und wie würde mein UC das am besten verarbeiten?? denke das reicht erstmal. also das packen ,crc und auf der PC seite das datenhandling sind wohl meine hauptprobleme. danke für eure hilfe im vorraus mfg flo
Es sind 2 verschiendene Dinge die da "hin und her" gehen: Zum einen Steuerinformationen, zum anderen "Nutzlast" (die eigentlichen zu übermittelnden Meß-Daten oder andere Art von Info) Das folgende ist einfach mal so "frei fantasiert", die Richtung (wer wem was sendet) ist ziemlich offensichtlich. CMDxx: ist eine frei von mir erfundene Kurzbezeichnung für die einzelnen Kommandos. Das könnte z.B. durch eine 1-Byte-Variable abgebildet werden. CMD00: "Gib mir das nächte dir bekannte Datenpaket" [PC an UC] CMD01: "Gib mir mal das Datenpaket Nr. xxx" [PC an UC] CMD02: "Halt erst mal, ich kann nicht mehr" [PC an UC, sowie UC an PC] CMD03: "darf ich ein neues Datenpaket schicken ?" [UC an PC] CMD04: "ich habe kein Daten mehr zum übermitteln" [UC an PC] CMD05: "Schmeiss alle deine Daten aus all deinen Puffern weg und fange ganz von vorne an" [PC an UC] CMD06: "Dieses Datenpaket steht nicht zur Verfügung" [UC an PC] CMD07: "Dies ist das Datenpaket xxx" [UC an PC] CMD08: "Die folgenden Datenpakete sind noch in meinem Ausgangspuffer" [UC an PC] (da fallen dir bestimmt noch mehr ein. Du mußt auch nicht alle und nicht alle sofort implementieren.) Ein Päckchen könnte dann z.B. so aussehen: CMDxx | Info bzw. CMDxx | Länge von Nutzdaten | Nutzdaten | CRC CRC ist angenommene 2 bytes, und wird auf Meßdaten angewendet Und nun gehts los mit dem Gequassel: Nach dem Einschalten fallen beide in Starre und UC wartet drauf, daß PC ihn anspricht. Irgendwann passierts: PC an UC: CMD05 UC an PC: CMD03 PC an UC: CMD00 UC an PC: CMD07 0010 01 2B FC A3 86 8A 9B C4 31 BF 99 64 A3 01 61 9D 4711 PC an UC: CMD00 UC an PC: CMD07 0003 A8 65 2A 761A Bei Variabler Blockgröße wie hier skizziert muß du halt auf Sender- udn Empfangsseite die Blockgröße jedes einzelnen Blocks mit protokollieren. Oder du nimmst feste Blockgrößen, dann mußt du aber entsprechend Speicher vorhalten.
Hupps, ich seh grade: Bei Meinem Befehl "CMD07" im Beispiel fehlt die Blocknummer. Denk sie dir einfach dazu an passender Stelle
moin, danke martin. werde versuchen es so hinzubekommen und die anweisungen in code umzusetzen, falls ich fragen habe melde ich mich nochmal. hast du vielleicht schon was mit crc gemacht??? geht das so einfach das man sich irgendein generatorpolynom nimmt, der UC und PC bekannt ist und eine polynomdivision durch die nutzdaten macht. den rest an die nutzdaten hängt und schickt. am PC dann nochmal polynomdivision mit den selben divisor durch nutz+checksumme und wenn das gleich 0 ist, dann ist alles ok?????????????? flo
Für die PC-Seite gibt es das Serial Programming Howto; da kann man nachlesen, wie man nach dem Posix-Standard serielle Schnittstellen anspricht. Um alle Parameter richtig einzustellen (blocking/nonblocking mode, bits/byte, Parity, rate, usw.) braucht man einige Zeilen und zum Empfangen braucht man eine Funktion wie select, damit man auch ein Timeout hat. An Leitungen wird zu 99 % nicht mehr als RxD und TxD (+Masse) verwendet, denn die Daten werden von der Hardware bidirektional autonom eingelesen/ausgesendet und dann (wenn der Buffer leer bzw. voll ist) ein IRQ ausgelöst; da ist kein Handshake nötig und viele serielle Kaben haben die Adern dafür überhaupt nicht (d. h. nur RxD, TxD u. Masse sind in dem seriellen Kabel). Es gibt verschiedenste Prüfsummen, aber mehr als ein Byte bläht den Traffic unnötig auf, denn schließlich kann eine Prüfsumme selber fehlerhaft übertragen werden und mehr als einige (nich alle) Fehler feststellen kann man damit nicht. Üblich ist beispielsweise das EXOR von Byte0, Byte1 usw. als ein-Byte-Prüfsumme zu übertragen. Wenn man genügend Bandbreite hat, kann man auch ECC nehmen. Im einfachsten Fall werden die Daten dreimal übertragen und ausgegeben wird dann die 2-von-3-Funktion, also (in ANSI-C): (x0 bitand x1) bitor (x1 bitand x2) bitor (x2 bitand x0) Damit werden alle 1-Bit-Fehler automatisch korrigiert. Meist werden platzsparendere Codes verwendet, die auch 1-Bit-Fehler korrigieren, aber zusätzlich 2-Bit-Fehler erkennen. Beim Mikrocontroller sollte natürlich sowas wie ein Mutex oder Semaphor verwendet werden, damit nicht aus erst halb gefüllten Buffern gelesen wird oder in noch halb gefüllten Buffern der benötigte Inhalt überschrieben wird. Aus der Betriebssytem-Theorie sollte das aber so ziemlich jedem MC-Programmierer bekannt sein. Zum Timing kann es auch nötig sein Wartezyklen zwischen den ausgetauschen Datenpaketen einzufügen, denn für eine Antwort wird ja einige Zeit benötigt und meist kann nur jeweils eine Antwort erzeugt werden.
Zur Erläuterung für Florian > und dann (wenn der Buffer leer bzw. voll ist) ein IRQ ausgelöst; Damit ist der Baustein-Puffer gemeint, welcher serielle Daten in parallele Daten wandelt, der ist ca. 1-16 bytes groß. Den Sende- bzw. Empfangspuffer auf UC bzw PC Seite "schöpft" aus diesem Daten-Eingangspuffer sein Daten. Diese Puffer (also Sende- und Empfangspuffer) mußt du bzw. dein Programm verwalten, während die Baustein-Puffer und einiuge Steuerleitungen (so Sachen wie RTS, CTS, DTR, DSR, DCD etc) großteils von der Baustein-HArdware selbst verwaltet werden. > Beim Mikrocontroller sollte natürlich sowas wie ein Mutex oder Semaphor verwendet werden, damit nicht aus erst halb gefüllten Buffern gelesen wird oder in noch halb gefüllten Buffern der benötigte Inhalt überschrieben wird. Diese Aussage ist sachlich vollkommen korrekt, aber .... > Aus der Betriebssytem-Theorie sollte das aber so ziemlich jedem MC-Programmierer bekannt sein. ... ich hatte nicht den Eindruck, daß Florian (schon) Betriebssystem-Theorie-Vorlesungen besucht hat. Zur Erläuterung für Florian: Das sind definierte Synchrionisationsmechanismen "Innerhalb" eines Programmablaufs. Ergoogle dir das einfach mal. > Zum Timing kann es auch nötig sein Wartezyklen zwischen den ausgetauschen Datenpaketen einzufügen, denn für eine Antwort wird ja einige Zeit benötigt und meist kann nur jeweils eine Antwort erzeugt werden. Das wird meines Erachtens besser mit request/response gelöst werden, anstelle daß der eine oder andere Beteiligte zwangsweise Däumchen dreht.
> Das wird meines Erachtens besser mit request/response gelöst werden, > anstelle daß der eine oder andere Beteiligte zwangsweise Däumchen > dreht. Das geht nur, wenn man das Protokoll ganz einfach halten kann, also z. B. der MC nur auf Anfragen vom PC antwortet, aber aber auch dann muß man ein Timing festlegen, damit der MC nicht überfordert wird. Über Funktionen wie gettimeofday kann man das beim PC ja millisekundengenau einhalten. Außerdem sollte die Verarbeitung im MC nicht blockierend realisiert sein, beispielsweise mit Zustands-Flags. Ich habe nämlich schon öfters mit quick and dirty-Software arbeiten müssen, die für irgendwelche Eingaben über Tasten in kleinen Schleifen so lange loopt, bis die Eingabe abgeschlossen ist, so daß in dieser Zeit (typischerweise einige Sekunden bis Minuten; beim Stehenlassen auch Monate) dann Anfragen von Außen nicht bearbeitet werden, obwohl der MC zu 99,999 % nichts zu tun hat. Und so ein Unsinn muß ja nicht sein.
@Rolf, "Aus der Betriebssytem-Theorie sollte das aber so ziemlich jedem MC-Programmierer bekannt sein." Das beißt sich aber. Die meisten MCs haben kein OS und die meisten MC-Programmierer (ich auch) kommen aus der Hardware. Mit "Mutex oder Semaphor" kann ich daher überhaupt nichts anfangen. Ich nehme relativ einfach gestrickte Protokolle: Die Kommandos werden als Text übertragen, d.h. jedes Kommando endet mit 0x0A und/oder 0x0D. Damit ist sichergestellt, daß keine Synchronisationsprobleme auftreten. Jedes Kommando wird vom MC mit einem Byte quittiert (ob falsch oder richtig). Anfragen an den MC erhalten zusätzlich noch den Antworttext (wieder mit 0x0A und/oder 0x0D abgeschlossen). In meinem Bootloader (Codesammlung) findest Du dazu ein Beispiel, da ist sogar eine 16-Bit CRC mit drin, die mit einem Kommando überprüft werden kann. Peter
@Peter, > "Aus der Betriebssytem-Theorie sollte das aber so > ziemlich jedem MC-Programmierer bekannt sein." > > Das beißt sich aber. > Die meisten MCs haben kein OS und die meisten MC-Programmierer (ich > auch) kommen aus der Hardware. Wenn da kein OS drauf ist, dann ist dein Programm quasi das OS. Deshalb muß man sich ja darum kümmern. Mit einem richtigen OS kann man ja Posix- und Kernel-Threads mit den üblichen Synchronisationmechanismen verwenden; beim MC muß man sowas minimalisiert selber machen. > Mit "Mutex oder Semaphor" kann ich daher überhaupt nichts anfangen. Ein Mutex ist ein Flag (Bit einer volatile Variablen) das z. B. bedeutet "Buffer0815 wird verwendet; nix mehr hineinschreiben"; ganz einfach. > Ich nehme relativ einfach gestrickte Protokolle: > > Die Kommandos werden als Text übertragen, d.h. jedes Kommando endet mit > 0x0A und/oder 0x0D. > Damit ist sichergestellt, daß keine Synchronisationsprobleme > auftreten. Naja, fehlertolerant ist das nicht und als Text sind die Datenpakete größer als binär. Deshalb verwende ich zur Synchronisation als Erstes die Timings, also z. B. mindestens 10 ms zwischen dem Ende den letzten Datenpaketes und dem Anfang den neuen (ansonsten wird verworfen) und zwischen Datenpaket-Anfang (erstes Byte) und -Ende müssen zwischen 1 und 20 ms vergehen. Das ist auch auf PC-Seite mit select und gettimeofday ganz einfach machbar (auf MC-Seite noch einfacher). Bei langsamen Übertragungen checke ich auch noch die Zeit zwischen zwei Bytes eines Datenpaketes, denn da die Pakete über eine ISR versendet werden, gibt es keine oder sehr kleine Pausen zwischen den Bytes eines Paketes. > Jedes Kommando wird vom MC mit einem Byte quittiert (ob falsch oder > richtig). > Anfragen an den MC erhalten zusätzlich noch den Antworttext (wieder mit > 0x0A und/oder 0x0D abgeschlossen). So eine Master-Slave-Kommunikation ist nicht schlecht, aber ich checke auch a) ob die Antwort zu der Anfrage paßt (i. d. R. nur erstes Byte von Anfrage und Antwort checken), b) wird ein timeout gesetzt (mittels select) und c) wird die Datenpaket-Länge überprüft; wenn es zu kurz oder zu lang ist, wird es ebenfalls verworfen.
hallo, danke erstmal für eure postings, werde mich am wochenend hinsetzen und versuchen alles zu verstehen und melde mich dann. mfg flo
moin, habe erst jetzt gerade zeit gefunden weiter zu forschen. erstmal danke nochmal für die tipps, ist viel auf einmal wenn man neu in diesem gebiet ist. das mit den mutex usw. habe ich nachgelesen, verstanden habe ich es wie ich es im code genau anwende weiss ich noch nicht, aber ich empfange ja daten und schicke sie durch die serielle schnittstelle an den pc und so laufen auch zwei sachen ab, die sich bei einem parallelen abarbeiten evtl. stören würden. also erst einlesen und dann senden. nicht parallel. was ich noch nicht ganz verstanden habe ist mit den timern bzw. den pausen zwischen packeten usw. also so wie ich das verstehe wendet man das zur synchrosation und kontrolle (ob daten korrekt transferiert sind)an. werden in den pausen andere befehle abgearbeitet wie z.B. packete packen oder weiss der teufel was??? das mit den timer für die übertragung ist eine gute zusatz kontrolle bzw. sicherung finde ich, da ich immer die selbe datenmende senden möchte. im moment beschäftigt mich auch noch zum verständnis das mit den datenpacketen packen, nicht der inhalt aber das zusammen führen der ganzen bytes. wie läuft das ab? ok habe variable für blocknr die ich inkrementiere + weitere infos. aber das mit den daten, habe mir gedacht das ich sie entweder aus dem sram nehme (wenn der speicher reicht und ich sie da ablege) oder anderen speichern , auf die man schnell zugreifen kann, vielleicht habt ihr da auch noch ein guten bzw. besseren tip zum schnellen grossen speicher für analog digitalisierte werte. das problem ist ich weiss nicht wie ich diese ganzen daten dan nehme, crc check mache und sie in das packet lege und dann nochmals zur sicherung irgendwo hinterlege oder im speicher lasse bis die daten drüben sind und dann erst aus dem speicher entferne. tips und hilfen würden mich sehr freuen. @peter habe dein Bootloader prog angeschaut aber die routine bzw. code für den crc16 nicht gefunden, kannst du mir sagen wo ich genau suchen soll???? mfg flo
Ich verwende eine Mainloop (keine nested Interrupts) und warte an deren Ende, wenn weniger als 100 ms seit dem letzten Durchlauf vergangen sind. Weil an nur einer Stelle der Mainloop gesendet wird, ist so zwischen den Datenpakete jeweils mindestens 100 ms Pause. Für dieses kooperative Multitasking dürfen die Funktionen natürlich nicht blockiernen, aber das ist nicht schwer und spart auch den Aufwand für einen Scheduler und zugehörigen Timer.
hallo, wollte nur nochmal nach fragen ob meine gedanken so richtig waren mit den timern usw.???? das mit dem crc16 wäre für mich auch wichtig, falls jemand weiss wo ich das bei peters bootloader code finde, bitte her damit. mfg flo
Also in den Pausen ist Pause; da ist nichts. Ansonsten hat man ja einen kontinuierlichen Datenstrom, aus dem man die Daten rausfischen muß. Da aber fast immer einzelne Datenpakete lückenlos per Interrupts rausgeschickt werden, hat man deshalb automatisch lückenlose Pakete und Pausen dazwischen. Statt CRC reicht auch das exor (aller Daten-Bytes); das braucht nur 1 Byte und funktioniert z. B. bei der Relaiskarte 8fa von Conrad ganz gut und ist einfacher.
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.