Hallo, ich stehe momentan vor einem Problem, bei dem ich einfach den Durchblick verloren habe. Ich denke in diesem Forum kann mir am besten geholfen werden da ihr was von der Hard- und Software versteht. Also: Ich bin gerade dabei eine RS232 Schnitstelle zu programmieren. Dazu habe ich ein Frame definiert das aus Header, Nutzdaten und EoF (Eond of Frame) besteht. Die Nutzdaten sollen 50 Pakete aus jeweils 8 bit also 1 byte sein. Ich programmiere mit C++ und habe meine Nutzdaten durch eine sehr einfache Zufallszahlengeneration erstellt. Es kommt ein bistream mit 300 bit heraus. Also einfach eine Zahlenfolge von Nullen und Einsen in zufälliger Reihenfolge und davon dann 300 hintereinander. Momentan speichere ich das in ein int Array. Jetzt sind meine Nutzdaten ja aber ein char Array[50]. Das heisst ich habe 400 bit zur Verfügung in diesem Array. Mein problem dabei ist denke ich die Konvertierung. Also wie bekomme ich es jetzt hin dass 8 int Werte sich zu einem char Wert zusammentun und ich sie somit einfach in das char Array speichern kann. Konkret: int Array[16] = {0,0,1,1,1,1,0,1,0,0,1,1,0,1,0,1}; char Array[2] = ???? Ich hoffe irgendjemand versteht meine wirren ausführungen, ich weis nicht wie ich das anders erklären soll. Kann mir jemand helfen?
Du weißt aber schon, daß eine UART eine Hardwarekomponente ist, die sowohl in PCs als auch in µCs Dir diese gesamte Arbeit abnimmt? In die UART steckt man die zu übertragenden Nutzdaten hinein, und aus der UART kommen die übertragenen Nutzdaten auch wieder heraus. Framing, Start- und Stopbits kümmern nur die UART, nicht aber deren Nutzer. Was genau hast Du vor?
Also ich schreibe eine GUI mit MFC in der dann beim Start die Daten generiert und über die RS232 gesendet werden sollen. Die Daten werden eben mit rand() %2; generiert und in ein int Array[300] geschrieben. Also habe ich sozusagen einen Bitstream mit 300 bit. Diese UART müsste ich ja irgendwie ansprechen, oder? Also eigentlich geht es mir nur darum, dass ich die Nullen und Einsen in das char Array bekomme und zwar so dass eine Null nur 1 bit Platz braucht und eine 1 auch nur 1 bit Platz braucht. Weil momentan sind sie ja als int gespeichert und jedes int brauch ja 32 bit Platz. Und wenn ich schreibe char a = "01001100"; dann hat das ja nicht nur 8 bit, oder liege ich da falsch. Außerdem wüsst ich nicht wie ich das nachher wieder auseinander klamüsern müsste. Hat denn jemand Erfahrung mit der Schnittstellenprogramierung von RS232? Ich nutze eine freie Bibliothek von CodeProject - nennt sich CSerial von Ramon de Klein. Ich versteh halt einfach nicht wie ich das mit den Nutzdaten hinbekomme. Vielleicht bin ich einfach zu doof dafür oder sitz aufm Schlauch. :(
Du musst Dich überhaupt nicht um den Bitstrom kümmern. Dafür ist die Hardware in Form der seriellen Schnittstelle Deines PCs da. Die muss initialisiert werden (Datenformat und Baudrate), und überträgt ab da jedes ihr übergebene Byte. Und das tut auch CSerial, sieh Dir einfach das Codebeispiel auf http://www.codeproject.com/KB/system/serial.aspx im Abschnitt "Sending Data" an. Das initialisiert die Schnittstelle und sendet dann die Zeichenfolge "Hello world". Das sind bereits die Nutzdaten, mehr Aufwand ist nicht erforderlich.
Ja das habe ich so eigentlich auch verstanden. Aber wenn ich anstatt "Hello World" z.B. "11001100" übertrage sind das ja nicht wirklich 8bit die ich da übertrage, oder? Es geht mir eigentlich darum dass ich wirklich 8 bit übertrage wenn ich 8 Einser und Nuller übertrage. Immerhin richtet man im Header ja auch ein STX und nach den Nutzdaten ein ETX ein damit gemerkt wird wann die Daten zu ende sind. Die bit sollen halt eigentlich nicht als String sonder wirklich als bit übergeben werden.
> Die bit sollen halt eigentlich nicht als String sonder wirklich als bit > übergeben werden. Dann wäre eine achtfache Shiftoperation mit jeweiligem Verordern aber besser. Ein UART arbeitet byte- und nicht bit-orientiert. Oben hast du geschrieben, dass du die Bits mit
1 | rand() %2; |
generierst. Warum machst du das nicht direkt so, dass dir ein zufälliges Byte rausfällt? Das Byte schickst du dann und gut ist =) Ralf
Ich verstehe jetzt was du meintest mit "CSerial macht das". Weil man nach dem Öffnen des COM mit Open() ja das Setup() aufruft und da alles einstellt. Man stellt einfach ein welche Baudrate, wie viele Bits, ob ein Parity Bit und wie viele Stop Bits gesetzt werden sollen. Ja, ich verstehe, man muss eigentlich kein eigenes Frame aufsetzten. Jetzt ist es aber so, ich habe zwei Dokus von Programmen die diese Bibliothek nutzen um Daten zu senden und in beiden ist erklärt wie man ein Frame aufsetzt. Warum sollten die das dann machen? Werden dann die selber gebastelten Frames in die von der Bibliothek erstellten Frames eingefügt?
Ralf schrieb: > Dann wäre eine achtfache Shiftoperation mit jeweiligem Verordern aber > besser. Ein UART arbeitet byte- und nicht bit-orientiert. > > Oben hast du geschrieben, dass du die Bits mitrand() %2;generierst. Warum machst du das nicht direkt so, dass dir ein zufälliges > Byte rausfällt? Das Byte schickst du dann und gut ist =) Wie sieht denn so eine Shiftoperation aus? Das hab ich noch nie gemacht. Es geht halt darum dass ich beim Empfangen wieder genau rauslesen kann wann eine 0 oder eine 1 kam, damit ich die dann wieder in ein int Array schreiben kann und damit weiter arbeiten. Also die Reihenfolge ist zwar eigentlich zufällig, aber nach den 300 bit soll dann wieder die selbe "zufällige" Reihenfolge kommen. Damit sie immer gleich ist, benutze ich srand(1); Außerdem wenn ich immer nur ein Byte schicke würde das die Geschwindigkeit ja runter ziehen.
> Jetzt ist es aber so, ich habe zwei Dokus von Programmen die diese > Bibliothek nutzen um Daten zu senden und in beiden ist erklärt wie man > ein Frame aufsetzt. Warum sollten die das dann machen? Werden dann die > selber gebastelten Frames in die von der Bibliothek erstellten Frames > eingefügt? Das wird wohl so sein, daß es sich bei diesen Frames um aus mehreren Bytes zusammengesetzte Frames handelt, also eine Protokollebene oberhalb der durch die UART-Hardware vorgenommenen Byte-Übertragung.
Da du ja einen Header fuer deinen Datenframe konstruiert hast hast du nicht mehr alle Kombinationen in deinen 8Bit Zeichen frei. Ich wuerde jetzt immer 4 deiner "Bits" zu einem Hexzeichen zusammenfassen und das uebertragen. char SendByte; // Bits zusammen fassen SendByte = Array[0+p] | (Array[1+p] << 1) | (Array[2+p] << 2) | (Array[3+p] << 3); // Den Arrayindex hochzaehlen p+=4; // Nach HEX wandlen '0123456789ABCDEF' if(SendByte > 9) SendByte += ('A'-10); else SendByte += '0'; // Und ausgeben SendByte ausgeben Gruss Helmi
Hallo, malzu schrieb: > Hallo, > ich stehe momentan vor einem Problem, bei dem ich einfach den Durchblick > verloren habe. Ich denke in diesem Forum kann mir am besten geholfen > werden da ihr was von der Hard- und Software versteht. > Also: Ich bin gerade dabei eine RS232 Schnitstelle zu programmieren. > Dazu habe ich ein Frame definiert das aus Header, Nutzdaten und EoF > (Eond of Frame) besteht. Die Nutzdaten sollen 50 Pakete aus jeweils 8 > bit also 1 byte sein. Ich programmiere mit C++ und habe meine Nutzdaten > durch eine sehr einfache Zufallszahlengeneration erstellt. Es kommt ein > bistream mit 300 bit heraus. Also einfach eine Zahlenfolge von Nullen > und Einsen in zufälliger Reihenfolge und davon dann 300 hintereinander. Du willst also seriell einen Header, 50 Byte Nutzdaten und EOF senden. Warum erzeugts Du also als Zufallsdaten nicht einfach 50 Zufallszahlen im Bereich 0...255 und legst diese in einem Byte-Array ab? Das sind dann 50 zufällige 8er Gruppen mit zufälliger 0-1 Verteilung, also das, was Du haen willst. Den Kram schickst Du dann in einer Schleife raus (Header davor natürlich und EOF dahinter) und fertig. Ich kann kein C++ und kenne auch Dein System nicht. Welcher Datentyp 8Bit breit ist, weiß ich also nicht. Das Array kann natürlich auch int oder sonstwas binäres gräßeres sein, dann mußt Du eben beim Senden auf Byte casten/maskieren/was-auch-immer. > int Array[16] = {0,0,1,1,1,1,0,1,0,0,1,1,0,1,0,1}; > char Array[2] = ???? Ob char auf Deinem System 8Bit ist weiß ich nicht, in meinem uralten VB6 ist das z.B. 16Bit. Gruß aus Berlin Michael
malzu schrieb: > Also ich schreibe eine GUI mit MFC in der dann beim Start die Daten > generiert und über die RS232 gesendet werden sollen. Die Daten werden > eben mit rand() %2; generiert und in ein int Array[300] geschrieben. > Also habe ich sozusagen einen Bitstream mit 300 bit. Nein. Hast du nicht. Du hast 300 Bytes Auch wenn jedes der Bytes bei dir momentan nur den Wert 0 oder 1 haben kann, sind es immer noch Bytes und keine Bits. > Diese UART müsste ich ja irgendwie ansprechen, oder? Also eigentlich > geht es mir nur darum, dass ich die Nullen und Einsen in das char Array > bekomme und zwar so dass eine Null nur 1 bit Platz braucht und eine 1 > auch nur 1 bit Platz braucht. Das hört sich jetzt schon ganz anders an, als der Kauderwelsch von vorher. > Weil momentan sind sie ja als int > gespeichert und jedes int brauch ja 32 bit Platz. Und wenn ich schreibe > char a = "01001100"; Das kannst du so gar nicht schreiben, weil es Unsinn ist. > dann hat das ja nicht nur 8 bit, oder liege ich da > falsch. Außerdem wüsst ich nicht wie ich das nachher wieder auseinander > klamüsern müsste. Du bist auf der Suche nach >> Schiebeoperation nach links << Schiebeoperation nach rechts & binäres Verunden | binäres Verodern mit diesen Operationen setzt du dir eine Funktion zusammen, die jeweils 8 char nimmt und daraus ein Gesamtbyte generiert, welche genau die Bits gesetzt hat, die in den 8 Eingangswerten als 1 markiert sind. Hilfe dazu findest zb hier http://www.mikrocontroller.net/articles/Bitmanipulation Aber wie schon aufgeführt: Eigentlich ist es Schwachsinn, sich zunächst mühsam 8 einzelne 'Bits' zu erzeugen, nur um die dann mühsam zu einem Byte zusammenzustoppeln. Da kannst du dir auch gleich ein Byte mit einem Wert von 0 bis 255 erzeugen lassen. Macht genau das gleiche. > Hat denn jemand Erfahrung mit der Schnittstellenprogramierung von RS232? Das hat damit nichts zu tun. Über eine RS232 gehen Bytes raus. Wo die Bytes herkommen interessiert die Schnittstellenprogrammierung nicht. > Ich nutze eine freie Bibliothek von CodeProject - nennt sich CSerial von > Ramon de Klein. Ich versteh halt einfach nicht wie ich das mit den > Nutzdaten hinbekomme. Vielleicht bin ich einfach zu doof dafür oder sitz > aufm Schlauch. :( Du versteifst dich zu sehr auf Bits. Die interessieren niemanden auf dieser Ebene. Die kleinste Einheit ist ein Byte.
Hallo alle zusammen, vielen Dank für eure Antworten. Ich werde mir das alles nochmal durch den Kopf gehen lassen und mir eure Antworten nochmal genauer anschauen. Ich danke euch auf jeden Fall schonmal vielmals. Grüße malzu
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.