RS232 ansprechen, aber wie?

  • C++

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • RS232 ansprechen, aber wie?

    Hi.
    Ich habe folgendes Problem.
    Ich muss unter Visual C++ (.Net) mit einem µ-Controller kommunizieren.

    ICh hab mich schonmal etwas unter codeguru, und der msdn Seite (mehr oder weniger) schlau gemacht. :read: Aber ich bekomm es einfach nicht hin. :depp:

    hat jemand von euch zufällig Ahnung von der Geschichte :confused:
    Achja, ich benutze WinXP ->als keinen direkten Hardwarezugriff mehr wie unter Win98.

    ich bräuchte (nur) ein Programm das die RS232 initialisiert, und ein Befehl für´s schreiben und einen für´s lesen, damit ich sehen kann wie das ganze aufgebaut ist.
    Baudrate =9600
    8Bit
    1 StopBit
    der Rest ist glaub ich Satndart, aber die initialisierung der Schnittstelle umzuschreiben werd ich dann schon schaffen. (//Dokumentation erwünscht :) )

    Ich hoffe mir kann jemand helfen.

    MFG
    Meine Sig war zu lang und wurde deswegen durch einen Moderator gelöscht......
  • Also ich hab mich mal etwas umgeschaut und mein Verdacht wurde bestätigt: Es gibt keine Build-In FUnktionen von C++ .NET um dies zu machen.

    Habe aber trotzdem 3 interessante Links für dich:
    [SIZE=1]"There's no right, there's no wrong, there's only popular opinion." Jeffrey Goines (Brad Pitt) in Twelve Monkeys[/SIZE]

    [SIZE=1]$ killall chico[/SIZE]
  • Das ist sogar ganz einfach: du öffnest die serielle Schnittstelle wie eine gewöhnliche Datei. Und als Dateinamen verwendest du COM1 bzw. COM2.
    Mit den normalen Schreib- und Leseoperationen kannst du dann Daten hin und her schicken.

    Also für C++ (nur die wichtigen Zeilen):

    Quellcode

    1. #include <fstream>
    2. use namespace std;
    3. ...
    4. /* in irgendeinem Unterprogramm: */
    5. fstream dat;
    6. char antwort;
    7. dat.open ("COM1", ios::in | ios::out | ios::binary);
    8. if (dat.fail()) {
    9. cout << "Fehler beim Öffnen der Schnittstelle\n";
    10. return;
    11. }
    12. dat << "Hallo"; /* Schreiben */
    13. dat >> antwort; /* Lesen eines Zeichens*/
    14. dat.close();
    Alles anzeigen


    Sofern ich keine Schreibfehler reingebastelt habe, sollte das gehen.

    Grüße
    Michael
  • @purx

    Danke für die Links, ich werd erstmal den Code von kelzoo probieren, da ich bis her noch nie DLL-Dateien eingebunden habe.

    @kelzoo
    Also wenn das klappen sollte, wäre es natürlich super, aber ich denke mal nicht. (-hab aber leider erst am Sonntag Zeit es zu testen).

    :read: Das Probelm das ich sehe, ist das der PC ja nie weiss ob der µ-Prozessor die Daten schon gelesen hat, und anders herum.
    Ich muss mir das mal durch den Kopf gehen lassen ob das auch reicht wenn ich einfach mit warteschleifen arbeite. (-ich hoff halt mal das es bei der Datenübergabe nicht häufig zu Fehlern kommt.)
    Ich meld mich dann auf jedenfall am Sontag Abend nochmal wenn ich Zeit hatte es zu testen.

    Danke aber auf jedenfall schonmal an euch beide das ihr euch mit dem Problem beschäftigt habt.

    MFG Lyricz
    Meine Sig war zu lang und wurde deswegen durch einen Moderator gelöscht......
  • :( :( :( Wie ich mir gedacht habe, hat das meinem Prof nicht so ganz gefallen :rtfm: da ich keine Möglichkeit habe zu überprüfen ob der µ-Controller die Nachricht gelesen hat. (Hand schake)
    Oder geht das irgenwie mit ner Zusatzfunktion?

    MFG
    Meine Sig war zu lang und wurde deswegen durch einen Moderator gelöscht......
  • Naja wenn es nicht um Geschwindigkeit geht kannst du natürlich jeweils die Ankunft eines Zeichens (oder einer Zeichenkette) bestätigen von der Gegenseite.

    So ähnlich wie das bei TCP-Verbidnungen läuft. Musst evtl. noch eine Message-Id oder sonstwas machen, dass du eindeutig weisst, was alles übertragen wurde.

    Alternativ kannst du Daten schicken, dann warten, sie dir bestätigen lassen, falls keine Bestätigung kommt, schickst du die Daten nochmals, falls bestätigung kommt kannst du neue Daten senden.

    So musst du einfach jeweils eine Verbidnung initialisieren und ein Timeout bestimmen. Evtl. kannst du auch mit Connection-States arbeiten (siehe TCP).

    -purx
    [SIZE=1]"There's no right, there's no wrong, there's only popular opinion." Jeffrey Goines (Brad Pitt) in Twelve Monkeys[/SIZE]

    [SIZE=1]$ killall chico[/SIZE]
  • Hmm......
    Da wär natürlich auch eine Idee.

    Ich muss im Laufe der Woche mal schauen ob ich das mit dem µ-Controller auf die Reihe bekomm.
    Aber ich hab (*leider* noch 2-3 Lobore die Woche, was die Zeit etwas knapp macht.)

    Aber ich meld mich hier wieder wenn ich Zeit hatte mir die Sache etwas genauer anzuschauen.

    MFG
    Meine Sig war zu lang und wurde deswegen durch einen Moderator gelöscht......
  • :( Leider klappt es nicht :(

    Mein Prograämmchen sieht folgender masen aus:

    C-Quellcode

    1. #include <iostream.h>
    2. #include <stdlib.h>
    3. #include <fstream>
    4. using namespace std;
    5. int main()
    6. {
    7. fstream dat;
    8. char antwort;
    9. dat.open ("COM3", ios::in | ios::out | ios::binary);
    10. if (dat.fail())
    11. {
    12. cout << "Fehler beim Öffnen der Schnittstelle\n";
    13. }
    14. else
    15. {
    16. cout<<"Test 1"<<endl;
    17. dat << "Hallo"; /* Schreiben */
    18. cout<<"Test 2"<<endl;
    19. dat >> antwort; /* Lesen eines Zeichens*/
    20. cout<<"Test 3"<<endl;
    21. dat.close();
    22. }
    23. int x; // damit nach der Anzeige eine Pause gemacht wird. getchar()
    24. cin>>x; //geht komischer WEise nicht.
    25. return 0;
    26. }
    Alles anzeigen


    Das Programm wird komplett kompiliert, aber beim Ausführen springt er mir nur bis "Test 2".
    Also die Ausgabe Lautet:

    Quellcode

    1. Test 1
    2. Test 2

    Und dann bleibt er stehen, egal was ich drück. :confused:
    Meine Sig war zu lang und wurde deswegen durch einen Moderator gelöscht......
  • Quellcode

    1. Wenn dein Controller kein Zeichen sendet bleibt er natürlich bei ... hängen


    Aha, da hab ich wohl was komplett falsch verstanden.
    ich dachte ich schreibe mit

    Quellcode

    1. dat << "Hallo"; /* Schreiben */

    etwas in einen Speicher der der Com-Schnitstelle gehört. Das was ich da rein geschrieben hab bleibt so lange da bis ich , oder der µ-
    Controller am andern Ende der Leitung es überschreiben.

    Somit müsste ja in meinem Speicher "Hallo" drin stehen und ich hätte was zum abholen.
    Oder wie läuft das?


    edit:// Ich hab endlich den Zugriff auf den Port :) :) :)

    Aber wie kann ich jetzt den Port richtig einstellen?
    Ich lesse mir vom µ-Controller momentan "123456789" schicken (Als Endlosschleife)

    Ich bekomm als Ausgabe aber leider nur einen Haufen Asci-Zeichen und zwischendrin ein paar Zahlen.
    Das komische ist nur, das es wesentlich mehr unterschiedliche Zeichen sind, als die Zahlen 1-9.
    Meine Sig war zu lang und wurde deswegen durch einen Moderator gelöscht......
  • Hallo,

    alleine schon wenn ich RS232 höre, könnte ich zum weinen anfangen. folgendes: wir haben ein eigenes schulfach (gehe in eine schule für edv), in dem wir jetzt gelernt haben, wie man über serielle schnittstelle und parallele schnittstelle kommuniziert. leider haben wir da so einen lehrer, der überhaupt nichts erklären kann. da wir aber test gehabt haben kann ich dir einiges interessantes zu dem ganzen geben. das ganze ist auf c basierend. leider kann ich nicht c++ :depp: , aber vielleicht hilft dir das ganze trotzdem

    zu beginn einmal etwas sehr sehr hilfreiches: die com.h und im anschluß die funktion des ganzen

    C-Quellcode

    1. // Com.h
    2. #if !defined(_COM_DEF_)
    3. #define _COM_DEF_
    4. #include <dos.h>
    5. #include <stdio.h>
    6. #include <ctype.h>
    7. #include <stdlib.h>
    8. //****************************************************************************
    9. //* I N T E R R U P T C O N T R O L L E R *
    10. //****************************************************************************
    11. typedef void interrupt (*t_intvekt)(void);
    12. #define PIC 0x20
    13. #define IMR 0x21 // Interrupt Mask Register
    14. #define ENABLE_PIC(ir) (outportb(IMR, inportb(IMR) & ~(ir))) // 8259: Interrupt freigeben
    15. #define DISABLE_PIC(ir) (outportb(IMR, inportb(IMR) | (ir))) // 8259: Interrupt sperren
    16. #define PIC_IRET outportb(PIC, 0x20)
    17. //****************************************************************************
    18. //* A D R E S S E N D E R U A R T - R E G I S T E R *
    19. //****************************************************************************
    20. #define COM1 0x3f0
    21. #define COM2 0x2f0
    22. extern int com[] = {0, COM1, COM2};
    23. #define UART_F0 1843200L // 1.84 MHz
    24. #define DATA 0x8 // Datenport
    25. #define IER 0x9 // Interrupt Enable Register
    26. #define IIR 0xA // Interrupt Identification Register
    27. #define LCR 0xB // Line Control Register
    28. #define MCR 0xC // Modem Control Register
    29. #define LSR 0xD // Line Status Register
    30. #define MSR 0xE // Modem Status Register
    31. //****************************************************************************
    32. //* P I N B E L E G U N G *
    33. //****************************************************************************
    34. // D9 D25 Bezeichnung Signalrichtung Adresse(Bit)
    35. // Modem -- PC
    36. //
    37. // 1 8 DCD --> 3FE(7)
    38. // 2 3 RX -->
    39. // 3 2 TX <--
    40. // 4 20 DTR <-- 3FC(0)
    41. // 5 7 GND
    42. // 6 6 DSR --> 3FE(5)
    43. // 7 4 RTS <-- 3FC(1)
    44. // 8 5 CTS --> 3FE(4)
    45. // 9 22 RI --> 3FE(6)
    46. //****************************************************************************
    47. //* M O D E M S T A T U S R E G I S T E R *
    48. //****************************************************************************
    49. union u_msr {
    50. struct {
    51. unsigned DCTS:1, ddsr:1, dri:1, ddcd:1, cts:1, dsr:1, ri:1, dcd:1;
    52. } s;
    53. unsigned char c;
    54. };
    55. #define MS_CTS 16 // Clear to Send
    56. #define MS_DSR 32 // Data Set Ready (Modem eingeschaltet)
    57. #define MS_RI 64 // Ring Indicator (Telefon l„utet)
    58. #define MS_DCD 128 // Data Carrier Detected (Verbindung aufgebaut)
    59. //****************************************************************************
    60. //* M O D E M C O N T R O L R E G I S T E R *
    61. //****************************************************************************
    62. union u_mcr {
    63. struct {
    64. unsigned dtr:1, rts:1, out1:1, out2:1, loop:1;
    65. } s;
    66. unsigned char c;
    67. };
    68. #define MC_DTR 1 // Data Terminal Ready
    69. #define MC_RTS 2 // Request to Send
    70. #define MC_OUT1 4
    71. #define MC_OUT2 8 // Interruptfreigabe
    72. #define MC_LOOP 16
    73. //****************************************************************************
    74. //* L I N E S T A T U S R E G I S T E R *
    75. //****************************************************************************
    76. union u_lsr {
    77. struct {
    78. unsigned rd:1, ov:1, py:1, fr:1, brk:1, th:1, ts:1, to:1;
    79. } s;
    80. unsigned char c;
    81. };
    82. #define LS_RD 1 // Receive Data
    83. #define LS_OV 2 // Overrun Error
    84. #define LS_PY 4 // Parity Error
    85. #define LS_FR 8 // Framing Error
    86. #define LS_BRK 16 // Leitung unterbrochen Fehler
    87. #define LS_TH 32 // Transmitter Hold Register leer
    88. #define LS_TS 64 // Transmitter Shift Register leer
    89. #define LS_TO 128 // Time out
    90. //****************************************************************************
    91. //* L I N E C O N T R O L R E G I S T E R *
    92. //****************************************************************************
    93. union u_lcr {
    94. struct {
    95. unsigned lg:2, stop:1, py:1, even:1, stick:1, setbreak:1, baud:1;
    96. } s;
    97. unsigned char c;
    98. };
    99. #define LC_BAUD 0x80 // Baudrate einstellen
    100. //****************************************************************************
    101. //* I N T E R R U P T E N A B L E R E G I S T E R *
    102. //****************************************************************************
    103. union u_ier {
    104. struct {
    105. unsigned r:1, t:1, lsr:1, msr:1;
    106. } s;
    107. unsigned char c;
    108. };
    109. #define IE_R 1
    110. #define IE_T 2
    111. #define IE_LSR 4
    112. #define IE_MSR 8
    113. //****************************************************************************
    114. //* I N T E R R U P T I D E N T I F I C A T I O N R E G I S T E R *
    115. //****************************************************************************
    116. union u_iir {
    117. struct {
    118. unsigned no_int:1, ii0:1, ii1:1;
    119. } s;
    120. unsigned char c;
    121. };
    122. #define II_MSR 0
    123. #define II_NO_INT 1
    124. #define II_THR 2
    125. #define II_R 4
    126. #define II_LSR 6
    127. char *comparam(int port, float baud, char py, int wortlg, int stoppbits, int stk)
    128. {
    129. static char s[30] = "1200,e,7,1";
    130. //long f0 = UART_F0;
    131. union u_lcr lcr;
    132. unsigned teiler;
    133. if (port < 1 | port > 2) port = 1;
    134. if(baud == 0) { // Einstellung lesen
    135. lcr.c = inportb(com[port] + LCR);
    136. lcr.s.baud = 1;
    137. outportb(com[port] + LCR, lcr.c);
    138. teiler = inport(com[port] + DATA);
    139. lcr.s.baud = 0;
    140. outportb(com[port] + LCR, lcr.c);
    141. }
    142. else { // Einstellung schreiben
    143. lcr.c = 0;
    144. lcr.s.baud = 1;
    145. outportb(com[port] + LCR, lcr.c);
    146. baud = 115200.0 > baud ? baud : 115200.0;
    147. teiler = 0xFFFF > (UART_F0 / baud / 16) ? (UART_F0 / baud / 16) : 0xFFFF;
    148. outport(com[port] + DATA, teiler);
    149. lcr.c = 0;
    150. lcr.s.lg = wortlg - 5;
    151. lcr.s.stop = stoppbits - 1;
    152. lcr.s.py = toupper(py) != 'N';
    153. lcr.s.even = toupper(py) == 'E';
    154. lcr.s.stick = stk;
    155. outportb(com[port] + LCR, lcr.c);
    156. }
    157. sprintf(s, "COM%d:%.*f,%c,%d,%d%s", port,
    158. baud - (long)baud ? 2 : 0, // dez-Stellen
    159. (double)UART_F0 / teiler / 16, // baud
    160. lcr.s.py ? (lcr.s.even ? 'E' : 'O') : 'N', // py ('E', 'O', 'N')
    161. lcr.s.lg + 5, lcr.s.stop + 1, // stop (1,2)
    162. lcr.s.stick ? " Stick" : "");
    163. return s;
    164. }
    165. #define INCOM(pin) ((inportb(COM + MSR) & pin) == pin)
    166. #endif
    Alles anzeigen


    Zusammenfassend: Was ist die com.h?

    Die Com.h beinhaltet alle Adressen der jew. Register und deren Bits. Das Interessanteste für dich ist die comparam(...). diese bekommt zunächst übergeben: int port, float baud, char py, int wortlg, int stoppbits, int stk

    port: entspricht eben 1 oder 2 je nach dem ob com1 oder com2
    baud: entspricht die baudrate
    py: entspricht parität, sprich even oder odd
    wortlg: die wortlänge
    stoppbits: anzahl der stoppbits,
    stk: stick = irgend so was aus der halbduplexzeit oder so, ka. einfach mit 0 initalisieren

    das heißt du mußt die comparam aufrufen um den rs232 zu initalisieren. da ich nicht mehr viel zeit habe kann ich dir die funktion der comparam nicht näher erklären. aber ich bin mir sicher, dass du das ganze irgendwia umschreiben kannst, dass es auch in visual c++ funktioniert.

    also wie schaut jetzt ein empfangeByte in C aus?

    Quellcode

    1. int empfangeByte(){
    2. BYTE c;
    3. while(!(c=inportb(com[PORT]+LSR)&LS_RD)); //solange das Bit ReveiveData des Line Status Registers auf 0 ist, kann nicht gelesen werden, da noch kein Zeichen angekommen ist.
    4. //Fehlerkontrolle
    5. if(c&LS_OV)
    6. printf("Overrun Error");
    7. else if(c&LS_PY)
    8. ...
    9. das selbe auch mit else if(c&(LS_FR, LS_BRK,)
    10. else //Lese aus Datenregister
    11. return inportb(com[PORT]+DATA);
    12. }
    Alles anzeigen


    Quellcode

    1. void sendeByte(char c){
    2. while(!(inportb(com[PORT] + LSR=&LS_TH)); //solange das Bit Transmiter Holding empty nicht gesetzt ist
    3. outportb(com[PORT]+DATA,c);
    4. }


    Das heißt wenn ich irgend etwas von einem Register lesen möchte, dann benötige ich inportb(COM+ REGISTER). Das Register muss durch eine Konstante (=Adresse des Bits) von der COM.h ersetzt werden, je nach dem welches man benötigt. outportb funktioniert genau so.

    Wenn du möchtest kann ich dir umfangreicheres Material zu dem ganzen schicken. Schreib mir einfach ne PN. Mit einem µ-Controller kommunizieren, machen wir leider erst. Haben schon eine Stunde darüber gehabt. Muss doch auch so funktionieren, oder?

    Meld dich einfach mal bei mir!

    Mfg
    The_Upper