RS232 - Übertragung



  • Hallo Gemeinde,

    ich bin auf der Suche nach C oder C++ Quellcode, welcher auf Daten zwischen zwei RS232-Schnittstellen transferiert.

    Mein Ziel ist eine Art Konsole, bei der ich auf beiden Computern ein paar Eingaben machen kann, und diese danach auf der Konsole des anderen Rechners sehe.
    Es ist sicherlich Standard, aber ich finde nichts im Internet.

    Ich bin Java-Programmierer, aber leider noch nicht ganz so tief in der C/C++-Programmierung, dass ich das Programm nun auf Hardwareebene ohne weiteres hinbekomme.

    Habt Ihr Beispiele oder Quellcode-Snipplets, die ich mir anschauen kann und damit zum Endergebnis komme?

    Vielen Dank

    Michael

    P.S.: Sry. Das Ding muss später in DOS laufen (16-Bit).
    P.P.S.:Entwicklungsumgebung ist Microsoft Visual C++ und OpenWatcom als 16-Bit-Kompiler



  • DOS macht das selber

    empfangen:

    mov ah,3
    int 21h
    ; al = empfangenes Zeichen
    

    senden:

    mov ah,4
    mov al,zeichen
    int 21h
    


  • keksekekse schrieb:

    DOS macht das selber

    und was ist mit baudrate und anderen rs232 settings?



  • Hi,

    wirf doch mal einen Blick in die FAQ 😉

    MfG mikey.



  • Hi,

    ich bin gerade dabei, das Beispiel aus der FAQ auszuprobieren.
    Hier der Link zum Beispiel: http://www.c-plusplus.net/forum/viewtopic-var-t-is-45173.html

    Allerdings fehlt die main-routine, so dass ich sie mir selber proggen muss. Soweit kein Thema. Allerdings ist die Doku leider nicht ganz ausreichend.

    Ich möchte erst einmal in der Main-Routine den Port initialisieren und rufe aus diesem Grunde die folgende Funktion auf:

    int initcomport(char port, long baudrate, char paritaet, char wortlaenge, char stopbits, char handshake, char irq, int bufferlaenge)

    Port ist klar: com[0] => 0x3f8
    Baudrate ist auch klar: 19200
    Parity ist auch klar: 'E'

    Aber was verbirgt sich hinter Wortlänge?
    Stopbits ist wieder klar: '2'
    Was ist Handshake? Wenn damit die Flusskontrolle gemeint ist, super. Aber was muss ich für "keine Flusssteuerung" eintragen? ''?
    Und was meint der Author mit IRQ?

    Die Bufferlänge stelle ich einfach mal auf 1600000

    Vielen Dank für Eure Hilfe.

    Michael



  • psYkomaN schrieb:

    Aber was verbirgt sich hinter Wortlänge?

    bei rs232 kann man aussuchen zwischen 8bits und 7bits pro wort. ersteres wird am häufigsten verwendet (passt ein ganzes byte rein), letzteres ist für textdaten gedacht...

    psYkomaN schrieb:

    Was ist Handshake? Wenn damit die Flusskontrolle gemeint ist, super. Aber was muss ich für "keine Flusssteuerung" eintragen? ''?

    bei rs232 gibts 2 methoden der flusskontrolle, softwaremässig (XON/XOFF) und über steuerleitungen (RTS/CTS oder DSR/DTR). ersteres verwendet zwei steuerzeichen und ist daher nur für textdaten geeignet. RTS/CTS wird am häufigsten verwendet. oder eben 'keine flusskontrolle', aber dabei können daten verloren gehen...

    psYkomaN schrieb:

    Und was meint der Author mit IRQ?

    der UART löst einen interrupt der CPU aus, wenn z.b. ein zeichen empfangen wurde oder wenn der sendebuffer leer ist. anhand dieser IRQ-nummer kann der PC erkennen, dass der interrupt von der RS232 kam.

    psYkomaN schrieb:

    Die Bufferlänge stelle ich einfach mal auf 1600000

    etwas viel, ne? 😉
    ich glaub' nicht, das 'DOS' damit klar kommt...



  • Hallo vista,

    vielen Dank für die wirklich schnelle Antwort.

    vista schrieb:

    bei rs232 gibts 2 methoden der flusskontrolle, softwaremässig (XON/XOFF) und über steuerleitungen (RTS/CTS oder DSR/DTR). ersteres verwendet zwei steuerzeichen und ist daher nur für textdaten geeignet. RTS/CTS wird am häufigsten verwendet. oder eben 'keine flusskontrolle', aber dabei können daten verloren gehen...

    Und was muss ich jetzt für "keine Flusskontrolle" eintragen?

    vista schrieb:

    der UART löst einen interrupt der CPU aus, wenn z.b. ein zeichen empfangen wurde oder wenn der sendebuffer leer ist. anhand dieser IRQ-nummer kann der PC erkennen, dass der interrupt von der RS232 kam.

    Und was gehört hier jetzt hin? Wo bekomme ich den IRQ von einem UART 16550 her?

    vista schrieb:

    etwas viel, ne? 😉
    ich glaub' nicht, das 'DOS' damit klar kommt...

    O.K. Hast ja recht. Steht jetzt auf 16000. Ungefähr 16Kb.

    Grüße

    Michael



  • psYkomaN schrieb:

    Und was gehört hier jetzt hin? Wo bekomme ich den IRQ von einem UART 16550 her?

    guck mal in die systemsteuerung (hardware-manager oder wie das heisst) unter windoofs. da kannste sehen, mit welcher IRQ-nummer die RS232 verbunden ist...
    🙂



  • vista schrieb:

    guck mal in die systemsteuerung (hardware-manager oder wie das heisst) unter windoofs. da kannste sehen, mit welcher IRQ-nummer die RS232 verbunden ist...
    🙂

    Unter DOS???

    Aber ich kann mir unter WinXP mal einen Wert raussuchen und diesen auf der DOS-Maschine ausprobieren.

    Danke für die Hilfe



  • Hilfe!!

    Ich bekomme das Beispiel nicht ans laufen.
    Beim Kompilieren innerhalb von MS Visual C++ erhalte ich folgende Meldungen:

    --------------------Configuration: UART_CHECK - Win32 Debug--------------------
    Compiling...
    main.c
    c:\temp\Rs232\main.c(44) : error C4226: nonstandard extension used : '__far' is an obsolete keyword
    c:\temp\Rs232\main.c(44) : error C2061: syntax error : identifier 'neu_int_com1'
    c:\temp\Rs232\main.c(44) : error C2059: syntax error : ';'
    c:\temp\Rs232\main.c(44) : error C2059: syntax error : ')'
    c:\temp\Rs232\main.c(45) : error C4226: nonstandard extension used : '__far' is an obsolete keyword
    c:\temp\Rs232\main.c(45) : error C2061: syntax error : identifier 'neu_int_com2'
    c:\temp\Rs232\main.c(45) : error C2059: syntax error : ';'
    c:\temp\Rs232\main.c(45) : error C2059: syntax error : ')'
    c:\temp\Rs232\main.c(46) : error C4226: nonstandard extension used : '__far' is an obsolete keyword
    c:\temp\Rs232\main.c(46) : error C2061: syntax error : identifier 'neu_int_com3'
    c:\temp\Rs232\main.c(46) : error C2059: syntax error : ';'
    c:\temp\Rs232\main.c(46) : error C2059: syntax error : ')'
    c:\temp\Rs232\main.c(47) : error C4226: nonstandard extension used : '__far' is an obsolete keyword
    c:\temp\Rs232\main.c(47) : error C2061: syntax error : identifier 'neu_int_com4'
    c:\temp\Rs232\main.c(47) : error C2059: syntax error : ';'
    c:\temp\Rs232\main.c(47) : error C2059: syntax error : ')'
    c:\temp\Rs232\main.c(49) : error C4226: nonstandard extension used : '__far' is an obsolete keyword
    c:\temp\Rs232\main.c(49) : error C2143: syntax error : missing ')' before ''
    c:\temp\Rs232\main.c(49) : error C2143: syntax error : missing '{' before '
    '
    c:\temp\Rs232\main.c(49) : error C2059: syntax error : ')'
    c:\temp\Rs232\main.c(50) : error C4226: nonstandard extension used : '__far' is an obsolete keyword
    c:\temp\Rs232\main.c(50) : error C2143: syntax error : missing ')' before ''
    c:\temp\Rs232\main.c(50) : error C2143: syntax error : missing '{' before '
    '
    c:\temp\Rs232\main.c(50) : error C2059: syntax error : ')'
    c:\temp\Rs232\main.c(51) : error C4226: nonstandard extension used : '__far' is an obsolete keyword
    c:\temp\Rs232\main.c(51) : error C2143: syntax error : missing ')' before ''
    c:\temp\Rs232\main.c(51) : error C2143: syntax error : missing '{' before '
    '
    c:\temp\Rs232\main.c(51) : error C2059: syntax error : ')'
    c:\temp\Rs232\main.c(52) : error C4226: nonstandard extension used : '__far' is an obsolete keyword
    c:\temp\Rs232\main.c(52) : error C2143: syntax error : missing ')' before ''
    c:\temp\Rs232\main.c(52) : error C2143: syntax error : missing '{' before '
    '
    c:\temp\Rs232\main.c(52) : error C2059: syntax error : ')'
    c:\temp\Rs232\main.c(59) : error C2137: empty character constant
    c:\temp\Rs232\main.c(113) : warning C4013: 'outp' undefined; assuming extern returning int
    c:\temp\Rs232\main.c(136) : warning C4013: 'malloc' undefined; assuming extern returning int
    c:\temp\Rs232\main.c(165) : warning C4013: '_dos_getvect' undefined; assuming extern returning int
    c:\temp\Rs232\main.c(165) : warning C4047: '=' : 'int *(__cdecl *)()' differs in levels of indirection from 'int '
    c:\temp\Rs232\main.c(165) : error C2106: '=' : left operand must be l-value
    c:\temp\Rs232\main.c(165) : warning C4550: expression evaluates to a function which is missing an argument list
    c:\temp\Rs232\main.c(166) : warning C4013: '_dos_setvect' undefined; assuming extern returning int
    c:\temp\Rs232\main.c(166) : error C2065: 'neu_int_com1' : undeclared identifier
    c:\temp\Rs232\main.c(169) : warning C4047: '=' : 'int *(__cdecl *)()' differs in levels of indirection from 'int '
    c:\temp\Rs232\main.c(169) : error C2106: '=' : left operand must be l-value
    c:\temp\Rs232\main.c(169) : warning C4550: expression evaluates to a function which is missing an argument list
    c:\temp\Rs232\main.c(170) : error C2065: 'neu_int_com2' : undeclared identifier
    c:\temp\Rs232\main.c(173) : warning C4047: '=' : 'int *(__cdecl *)()' differs in levels of indirection from 'int '
    c:\temp\Rs232\main.c(173) : error C2106: '=' : left operand must be l-value
    c:\temp\Rs232\main.c(173) : warning C4550: expression evaluates to a function which is missing an argument list
    c:\temp\Rs232\main.c(174) : error C2065: 'neu_int_com3' : undeclared identifier
    c:\temp\Rs232\main.c(177) : warning C4047: '=' : 'int *(__cdecl *)()' differs in levels of indirection from 'int '
    c:\temp\Rs232\main.c(177) : error C2106: '=' : left operand must be l-value
    c:\temp\Rs232\main.c(177) : warning C4550: expression evaluates to a function which is missing an argument list
    c:\temp\Rs232\main.c(178) : error C2065: 'neu_int_com4' : undeclared identifier
    c:\temp\Rs232\main.c(187) : warning C4013: 'inp' undefined; assuming extern returning int
    c:\temp\Rs232\main.c(308) : warning C4013: 'free' undefined; assuming extern returning int
    c:\temp\Rs232\main.c(453) : error C4226: nonstandard extension used : '__far' is an obsolete keyword
    c:\temp\Rs232\main.c(453) : error C2061: syntax error : identifier 'neu_int_com1'
    c:\temp\Rs232\main.c(453) : error C2059: syntax error : ';'
    c:\temp\Rs232\main.c(453) : error C2059: syntax error : ')'
    c:\temp\Rs232\main.c(469) : error C4226: nonstandard extension used : '__far' is an obsolete keyword
    c:\temp\Rs232\main.c(469) : error C2061: syntax error : identifier 'neu_int_com2'
    c:\temp\Rs232\main.c(469) : error C2059: syntax error : ';'
    c:\temp\Rs232\main.c(469) : error C2059: syntax error : ')'
    c:\temp\Rs232\main.c(485) : error C4226: nonstandard extension used : '__far' is an obsolete keyword
    c:\temp\Rs232\main.c(485) : error C2061: syntax error : identifier 'neu_int_com3'
    c:\temp\Rs232\main.c(485) : error C2059: syntax error : ';'
    c:\temp\Rs232\main.c(485) : error C2059: syntax error : ')'
    c:\temp\Rs232\main.c(501) : error C4226: nonstandard extension used : '__far' is an obsolete keyword
    c:\temp\Rs232\main.c(501) : error C2061: syntax error : identifier 'neu_int_com4'
    c:\temp\Rs232\main.c(501) : error C2059: syntax error : ';'
    c:\temp\Rs232\main.c(501) : error C2059: syntax error : ')'
    Error executing cl.exe.

    main.obj - 57 error(s), 14 warning(s)

    Ich musste übrigens für dieses Beispiel in der Header-Datei den Import (#include <alloc.h>) herausnehmen, weil er genau darüber gestolpert ist.

    Wer kann mir weiter helfen?

    Ist sicherlich nur ein Anfänger-Fehler, aber ich will es schaffen.

    Vielen Dank

    Michael



  • 16bit-Code für DOS <-> MSVC wird nie durchgehen. Kann nicht funktionieren.

    MfG SideWinder



  • tja. Und in OpenWatcom (16-Bit Kompilierung) erhalte ich folgende Meldung:

    cd C:\temp\Rs232
    wmake -f "C:\temp\Rs232\Rs232.mk" -h -e
    wcc main.c -i=C:\WATCOM\h -w4 -e25 -zq -od -d2 -bt=dos -ml
    comports.h(43): Warning! W138: No newline at end of file
    main.c(59): Error! E1065: Invalid character constant
    main.c(59): Warning! W106: Constant out of range - truncated
    main.c(59): Note! N2003: source conversion type is 'int '
    main.c(59): Note! N2004: target conversion type is 'char '
    main.c(59): Note! N2002: 'initcomport' defined in: comports.h(26)
    main.c(59): Error! E1151: Parameter count does not agree with previous definition
    main.c(88): Warning! W124: Comparison result always 0
    main.c(96): Warning! W124: Comparison result always 0
    main.c(229): Warning! W124: Comparison result always 1
    main.c(261): Warning! W124: Comparison result always 1
    main.c(513): Warning! W138: No newline at end of file
    main.c(113): Warning! W131: No prototype found for function 'outp'
    main.c(187): Warning! W131: No prototype found for function 'inp'
    main.c(136): Warning! W131: No prototype found for function 'malloc'
    main.c(308): Warning! W131: No prototype found for function 'free'
    Error(E42): Last command making (C:\temp\Rs232\main.obj) returned a bad status
    Error(E02): Make execution terminated
    Execution complete



  • Invalid character constant:

    'c oder 'cccc'
    Lösung: 'c'
    


  • Hi,

    sorry. Aber ich habe selber das Gefühl als wenn ich von C++ plötzlich kaum noch etwas verstehe, obwohl ich 1 Jahr nichts anderes gemacht habe.

    keksekekse schrieb:

    Invalid character constant:

    'c oder 'cccc'
    Lösung: 'c'
    

    Das ist nicht der Fehler. Aber schaut selbst.

    Hier meine main-Methode:

    #include "comports.h"
    
    #define EOI 0x20
    #define MIN_BUFSIZE 100
    
    //*** Strukturen
    //Datenstruktur für den Interrupt eines COM-Ports
    struct comport
    {
         int buffsize; //Speichert die Größe des Buffers
         int head; //Index zum Einlesen der Daten vom COM-Port in den Buffer
         int tail; //Index zum Einlesen der Daten aus dem Buffer für das Programm
         char handshake;
         unsigned int buffer[MIN_BUFSIZE];   //Zeiger auf den reservierten Bereich für den Buffer
    };
    
    //*** "versteckte" Funktionen
    void initinterrupt(char port);
    int holintadresse(char port);
    void deinitinterrupt(char port);
    
    //*** Variablen
    //Speichert die Daten für die COM-Ports
    struct comport *cport[MAX_COM]={0};
    //Speichert die Adressen der COM-Ports für inp und outp
    int com[MAX_COM]={0x3f8, 0x2f8, 0x3e8, 0x2e8, 0x2f8, 0x2f8, 0x2f8, 0x2f8};
    //Speichert die Interruptnummer für die COM-Ports
    int intnr[MAX_COM]={4, 3, 15, 5, 3, 3, 3, 3};
    
    //*** Funktionsdeklarationen für die Interrupts
    short int_lescomport(char port);
    
    void __interrupt __far neu_int_com1();
    void __interrupt __far neu_int_com2();
    void __interrupt __far neu_int_com3();
    void __interrupt __far neu_int_com4();
    
    void (__interrupt __far *alt_int_com1)();
    void (__interrupt __far *alt_int_com2)();
    void (__interrupt __far *alt_int_com3)();
    void (__interrupt __far *alt_int_com4)();
    
    main.c
    
    // Main-Function
    void main(void){
    
    	// Initialisiert den Com-Port
    	int res = initcomport('0', 19200.0, 'E', '7', '2', '', '4', 1600);
    	printf("Rückgabe: %d", res);
    
    	return;
    }
    
    //Initialisiert den angegebenen COM-Port
    /*
    Parameter:
            port = Nummer des COM-Ports - 1 (wegen den Arrays com, cport und intnr) -> Interruptnummer je nach COM-Port
            paritaet
            wortlaenge
            stopbits = Anzahl der Stopbits 1 oder 2
            handshake
            bufferlaenge = Länge des Buffers für die einkommenden Daten
    Rückgabewert: Kennzeichen, ob die Initialisierung erfolgreich war
            < 0 => Fehlerkennzeichen
    
    Fehlerkennzeichen:
       -1 = COM-Port wird nicht unterstützt
       -2 = Interrupt wird nicht unterstützt
    
    Setzt die Baudrate, Parität, Wortlänge, Stopbits, Handshake, Interrupt (initinterrupt())
     und bufferlänge für den angegebenen COM-Port.
    */
    
    int initcomport(char port, long baudrate, char paritaet, char wortlaenge, char stopbits, char handshake, char irq, int bufferlaenge){
        int tmp=0;
    
        if(port<0||port>=MAX_COM)
         {
            return(-1);
         }
         if(irq>15)
         {
            return(-2);
         }
         if(irq<0)
         {
            irq=intnr[port];
         }
    
         if(bufferlaenge<MIN_BUFSIZE)
         {
            bufferlaenge=MIN_BUFSIZE;
         }
    
         handshake&=0xF;
    
         if(!cport[port])
        {
            deinitcomport(port);
         }
    
        outp(com[port] + IER,0x00); //Interrupts deaktivieren
        outp(com[port] + LCR,0x80); //BRDL (niedriger Baudteiler) und BRDH (hoher Baudteiler) zur Verfügung stellen
    
        outp(com[port], (int)(115200L/baudrate)&0xFF); //Einstellen des BRDL
        outp(com[port] + IER, (int)(115200L/baudrate)>>8); //Einstellen des BRDH
    
        outp(com[port] + MCR, 0x0);
        outp(com[port] + MCR, 0x08 | handshake);                    // Set MCR user output 2 to enable ints and DTR line
    
        if((toupper(paritaet) == 'E')||(paritaet==3))
            tmp =  0x18;
        if((toupper(paritaet) == 'O')||(paritaet==1))
            tmp =  0x08;
    
        tmp |= (wortlaenge-5);
        tmp |= (stopbits-1) << 2;
    
        outp(com[port] + LCR, tmp & 0x1F);            // Reset Bit 7 to zero for TXR and RDR
    
         intnr[port]=irq;
    
        initinterrupt(port);
    
        cport[port]=(struct comport *)malloc(sizeof(struct comport)+(bufferlaenge-MIN_BUFSIZE)*sizeof(unsigned int));
    
         cport[port]->buffsize=bufferlaenge;
         cport[port]->head=0;
         cport[port]->tail=0;
         cport[port]->handshake=handshake;
    
         return port;
    }
    
    //Initialisiert den Interrupt zum angegebenen COM-Port
    void initinterrupt(char port)
    /*
    Parameter: port = Nummer des COM-Ports -1 (wegen den Arrays com, cport und intnr)
    
    Speichert die alte Funktion des angegebenen Interrupts und ersetzt diese durch eine neue,
    eigene Funktion. Kennzeichnet den Interrupt als benutzt in der Interrupttabelle.
    */
    {
        int tmp=0;
    
        if(intnr[port]<0||intnr[port]>15)
        {
            return;
        }
    
        switch(port)
         {
            case 0:
                alt_int_com1=_dos_getvect(holintadresse(port));
                 _dos_setvect(holintadresse(port), neu_int_com1);
                break;
            case 1:
                alt_int_com2=_dos_getvect(holintadresse(port));
                 _dos_setvect(holintadresse(port), neu_int_com2);
                break;
            case 2:
                alt_int_com3=_dos_getvect(holintadresse(port));
                _dos_setvect(holintadresse(port), neu_int_com3);
                break;
            case 3:
                alt_int_com4=_dos_getvect(holintadresse(port));
                 _dos_setvect(holintadresse(port), neu_int_com4);
                break;
            default:
                 return;
         }
         outp(com[port]+IER,0x01); //Interrupts aktivieren
    
         _disable();
    
         tmp = inp(0x21); //Aktuelle Interrupts holen
         tmp &=  ~(0x01 << intnr[port]); //Interrupt aktivieren
         outp(0x21,tmp); //Interrupts setzen
    
         _enable();
    }
    
    //ermittelt die Speicheradresse eines Interrupts
    int holintadresse(char port)
    /*
    Parameter: port = Nummer des COM-Ports -1 (wegen den Arrays com, cport und intnr)
    Rückgabewert: Speicheradresse des Interrupts
    
    ermittelt zur Interruptnummer des angegebenen COM-Ports die Speicheradresse und
    gibt diese zurück
    */
    {
        if(intnr[port]>7)
        {
               return(intnr[port]+0x68);
        }
        else
        {
            return(intnr[port]+0x8);
        }
    }
    
    //Holt ein Byte aus dem Buffer
    int holbyte(char port)
    /*
    Parameter: port = Nummer des COM-Ports - 1 (wegen den Arrays com, cport und intnr)
    Rückgabewert: Byte, das gelesen wurde. Bei keinem neuen Byte -> -1
    
    Holt ein Byte aus dem Buffer des angegebenen Ports, wenn ein neues Zeichen
    vorhanden ist.  Setzt dabei tail auf den nächsthöheren Wert für das nächste
    einzulesende Zeichen. Ist tail am Ende des Buffers wird tail wieder auf den
    Anfang des Buffers gesetzt. Das neue Zeichen wird zurückgegeben. Ansonsten wird
    -1 zurückgegeben als Kennzeichen, dass kein neues Zeichen vorhanden ist.
    */
    {
        int rueck=0;
    
         if(port>-1&&port<MAX_COM)
         {
            if(cport[port])
            {
                 if(cport[port]->head==cport[port]->tail)
                 {
                    return(-1);
                 }
    
                 rueck=cport[port]->buffer[cport[port]->tail++];
    
                 if(cport[port]->tail>=cport[port]->buffsize)
                 {
                    cport[port]->tail=0;
                 }
    
                 return(rueck);
            }
        }
        return(-2);
    }
    
    //Sendet ein Byte
    void sendebyte(char port, int byte)
    /*
    Parameter: port = Nummer des COM-Ports - 1 (wegen den Arrays com, cport und intnr)
    
    Sendet ein Byte an den angegebenen Port.
    */
    {
        int status = 0;
    
         if(port>-1&&port<MAX_COM)
         {
            if(cport[port])
            {
                do
                 {
                    status = (inp(com[port]+LSR)) & 0x60;
                    if(status == 0x60)
                    {
                        outp(com[port], byte);
                    }
                }while(status != 0x60);
            }
        }
    }
    
    //Sendet einen String
    void sendestring(char port, const char *zeichen)
    /*
    Parameter: port = Nummer des COM-Ports - 1 (wegen den Arrays com, cport und intnr)
    
    Sendet einen String an den angegebenen Port. Benutzt dabei die Funktion sendebyte().
    
    */
    {
        while(*zeichen)
        {
            sendebyte(port, *zeichen++);
        }
    }
    
    //Deinitialisiert den angegebenen COM-Port
    void deinitcomport(char port)
    /*
    Parameter: port = Nummer des COM-Ports -1 (wegen den Arrays com, cport und intnr)
    */
    {
        if(!cport[port])
        {
               return;
         }
    
         deinitinterrupt(port);
    
         outp(com[port] + IER,0x00);
        outp(com[port] + MCR,0x00);
    
         free(cport[port]);
         cport[port]=NULL;
    }
    
    //Deinitialisiert den angegebenen Interrupt
    void deinitinterrupt(char port)
    /*
    Parameter: port = Nummer des COM-Ports -1 (wegen den Arrays com, cport und intnr)
    
    Überschreibt die eigene Funktion für den Interrupt mit der alten Funktion. Kennzeichnet
    den Interrupt als frei in der Interrupttabelle.
    */
    {
        int tmp;
    
        _disable();
    
        tmp = inp(0x21);              // Get current 8259 state
        tmp |=  0x01 << intnr[port];
        outp(0x21,tmp);
    
        _enable();
    
       switch(port)
       {
            case 0:
           _dos_setvect(holintadresse(port), alt_int_com1);
             break;
          case 1:
         _dos_setvect(holintadresse(port), alt_int_com2);
             break;
          case 2:
           _dos_setvect(holintadresse(port), alt_int_com3);
             break;
        case 3:
           _dos_setvect(holintadresse(port), alt_int_com4);
         break;
       }
    }
    
    void setzrts(char port, int kz)
    //aj
    //Setzt die RTS-Leitung des Ports port auf kz (1=AN; 0=AUS)
    {
        int hilf;
    
         if(cport[port])
        {
             hilf=inp(com[port]+MCR);
           if(kz)
          {
             hilf|=1;
          }
          else
          {
              hilf&=0xfe;
          }
        outp(com[port]+MCR, hilf);
       }
    }
    
    void setzdtr(char port, int kz)
    //aj
    //Setzt die DTR-Leitung des Ports port auf kz (1=AN; 0=AUS)
    {
        int hilf;
    
       if(cport[port])
         {
             hilf=inp(com[port]+MCR);
            if(kz)
          {
             hilf|=2;
          }
        else
          {
              hilf&=0xfd;
          }
          outp(com[port]+MCR, hilf);
       }
    }
    
    int holcts(char port)
    //aj
    //gibt zurück, ob die CTS-Leitung des Ports port aktiv ist
    {
        if(cport[port])
        {
            return(inp(com[port]+MSR)&0x10);
        }
        else
        {
            return(0);
        }
    }
    
    int holdcd(char port)
    //aj
    //gibt zurück, ob die DCD-Leitung des Ports port aktiv ist
    {
        if(cport[port])
         {
            return(inp(com[port]+MSR)&0x80);
         }
        else
         {
            return(0);
        }
    }
    
    //liest Daten aus dem angegebenen COM-Port
    short int_lescomport(char port)
    /*
    Parameter: port = Nummer des COM-Ports - 1 (wegen den Arrays com, cport und intnr)
    Rückgabewert: gibt den Status des COM-Ports zurück
    
    Liest neue Daten vom angegebenen COM-Port und überprüft den aktuellen Status. Schreibt
    das neue Zeichen in den zugehörigen Buffer des COM-Ports an der Stelle von head.
    Überschreitet head die Buffergröße, dann wird head auf 0 gesetzt, um am Anfang
    des Buffers wieder zu beginnen.
    */
    {
        short status = 0;
    
        status = inp(com[port]+IIR);
        status&=6;
        if(status & 4)
            cport[port]->buffer[cport[port]->head++]=inp(com[port]);
        if(status & 2)
        {
            inp(com[port]+LSR); //Löscht Fehler (?)
        }
        if(status == 0)
        {
            inp(com[port]+MSR);
        }
        if(cport[port]->head >= cport[port]->buffsize)
            cport[port]->head=0;
    
        return(status);
    }
    
    //neue Interruptfunktion für COM-Port 1
    void __interrupt __far neu_int_com1()
    /*
    schreibt eingehende Daten in den Buffer
    */
    {
        short status;
    
        do
         {
            status=int_lescomport(0);
        }while(status&4);
    
        outp(0x20,EOI);
    }
    
    //neue Interruptfunktion für COM-Port 2
    void __interrupt __far neu_int_com2()
    /*
    schreibt eingehende Daten in den Buffer
    */
    {
        short status;
    
        do
        {
            status=int_lescomport(1);
         }while(status&4);
    
        outp(0x20,EOI);
    }
    
    //neue Interruptfunktion für COM-Port 3
    void __interrupt __far neu_int_com3()
    /*
    schreibt eingehende Daten in den Buffer
    */
    {
        short status;
    
        do
        {
            status=int_lescomport(2);
        }while(status&4);
    
        outp(0x20,EOI);
    }
    
    //neue Interruptfunktion für COM-Port 4
    void __interrupt __far neu_int_com4()
    /*
    schreibt eingehende Daten in den Buffer
    */
    {
        short status;
    
        do
        {
            status=int_lescomport(3);
         }while(status&4);
    
        outp(0x20,EOI);
    }
    

    Die Header-Datei habe ich ja inkludiert und brauche sie hier nicht zu posten. Ist exakt identisch mit der aus der FAQ.

    Und das hier ist meine Fehlermeldung im Kompiler. Ich weiss momentan überhaupt nicht wo der Haken sein könnte. Was ist falsch?

    cd C:\temp\rs232
    wmake -f "C:\temp\rs232\rs232.mk" -h -e -a "C:\temp\rs232\main.obj"
    wcc main.c -i=C:\WATCOM\h -w4 -e25 -zq -od -d2 -bt=dos -ml
    comports.h(43): Warning! W138: No newline at end of file
    main.c(59): Error! E1065: Invalid character constant
    main.c(59): Warning! W106: Constant out of range - truncated
    main.c(59): Note! N2003: source conversion type is 'int '
    main.c(59): Note! N2004: target conversion type is 'char '
    main.c(59): Note! N2002: 'initcomport' defined in: comports.h(26)
    main.c(59): Error! E1151: Parameter count does not agree with previous definition
    main.c(88): Warning! W124: Comparison result always 0
    main.c(96): Warning! W124: Comparison result always 0
    main.c(229): Warning! W124: Comparison result always 1
    main.c(261): Warning! W124: Comparison result always 1
    main.c(513): Warning! W138: No newline at end of file
    main.c(113): Warning! W131: No prototype found for function 'outp'
    main.c(187): Warning! W131: No prototype found for function 'inp'
    main.c(136): Warning! W131: No prototype found for function 'malloc'
    main.c(308): Warning! W131: No prototype found for function 'free'
    Error(E42): Last command making (C:\temp\rs232\main.obj) returned a bad status
    Error(E02): Make execution terminated
    Execution complete

    Wer kann mir weiterhelfen?

    Viele Grüße und einen ganz großen Dank

    Michael



  • #include <malloc.h> // wegen malloc() und free()
    
    //Startfunktion muß heißen:
    int main()
    {
      ...
      // '' ist die Fehlerquelle aus Zeile 59
      // '8' -> 0x38 hex
      // 'A' -> 0x41 hex
      // 8   -> 0x08 hex
      ...
      return 0;
    }
    


  • Hallo,

    keksekekse schrieb:

    #include <malloc.h> // wegen malloc() und free()
    
    //Startfunktion muß heißen:
    int main()
    {
      ...
      // '' ist die Fehlerquelle aus Zeile 59
      // '8' -> 0x38 hex
      // 'A' -> 0x41 hex
      // 8   -> 0x08 hex
      ...
      return 0;
    }
    

    vielen Dank für die Antwort.
    Allerdings läuft es leider immer noch ganz.

    Hier mein Code:

    int res = initcomport('0', 19200.0, 'E', '7', '2', '0', '4', 1600);
            printf("Rückgabe: %d", res);
    

    Als Rückgabe, erhalte ich immer -1. Warum?

    Welche Verbindungsdaten?

    19200
    7 Bits
    Gerade
    2 Stoppbits
    Flusssteuerung: "Kein"

    Irgendwie komme ich überhaupt nicht weiter.

    Vielleicht ist jemand so nett. Hier das Handbuch zum Mainboard:

    http://www.purematic.de/JUMPtec_Manual_PC104_MOPSplus_181004.pdf

    Was ist falsch? Wo könnte der Fehler liegen?
    Irgendwie fühle ich mich gerade als purer Anfänger. 😉

    Vielen Dank für Eure bisherige Hilfe!!!

    Michael



  • psYkomaN schrieb:

    int initcomport(char port, long baudrate, char paritaet, char wortlaenge, char stopbits, char handshake, char irq, int bufferlaenge){
        int tmp=0;
    
        if(port<0||port>=MAX_COM)
         {
            return(-1);
         }
         if(irq>15)
         {
            return(-2);
         }
         if(irq<0)
         {
            irq=intnr[port];
         }
    
    int res = initcomport('0', 19200.0, 'E', '7', '2', '0', '4', 1600);
            printf("Rückgabe: %d", res);
    

    Da hast Du was in ganz falscher Erinnerung: char bedeutet 8 Bit Breite, d.h. Zahl von 0-255, eigentlich -128 bis +127, aber das ist Ansichtssache.

    Dementspechend wird '0' als "char constant" mit dem Hexwert 0x30, dez 48 interpretiert. Was Du übergeben mußt, ist die Zahl 0, ohne irgendwas davor oder dahinter. 19200.0 ist eine Fließkommazahl (float), die vom Compiler selbständig in den geforderten Typ long verwandelt (gecastet) wird (also keine Fehlermeldung, soweit ich das gesehen habe).

    Fazit: Das Ergebnis -1 wird bereits beim ersten if der Funktion initcomport() zurückgeliefert, weil die Konstante MAX_COM aller Wahrscheinlichkeit 2 ist und '0' = 48 eben deutlich darüber liegt.

    Richtiger müßte der Aufruf so aussehen:

    int res;
    res = initcomport(0, 19200, 0xE/*?*/, 7, 2, 0, 4, 1600);
    


  • Hallo,

    vielen Dank. Aber jetzt bekomme ich das einlesen und absenden nicht hin.
    Kann doch nicht so schwer sein, oder?

    Hier meine Routine

    void main(void){
        int comportResult;	// Result of COM-Initialisation
    	int comport = 0;	// Comport
    	int receivedByte;	// Received byte
    	int sendByte;		// Received byte
    	int received_i=0;			// Iterator
    	// Zeige die IRQ-Adresse
    //	printf("IRQ-Adresse ist: %d", holintadresse(0));
    
    	// Initialisiere den COM-Port
    	comportResult = initcomport(comport, 19200, 0xE, 7, 2, 0, 4, 1600);
    	printf("Initialisierung: %d\n", comportResult);
    
    	// Setze DTR
    	setzdtr(comport, 1);
    
    	// Status DCD
    	printf("Status DCD: %d\n", holdcd(comport));
    
    	// Status CTS
    	printf("Status CTS: %d\n", holcts(comport));
    /*
    	// Hole Byte	
    	printf("Lese Zeichen aus Buffer\n");
    	while(1){
    		receivedByte=holbyte(comport);
    		if (receivedByte != -1){
    			printf("%d", receivedByte);
    		}
    		received_i++;
    	}
    
    	printf("Einlesen beendet!\n");
    */
    
    	// Setze RTS
    	setzrts(comport, 1);
    	// Sende Zeichen 'a'
    	printf("Sende Zeichen %d", 'a');
    	sendebyte(comport, 'a');
    
        return;
    }
    

    Ich musste in der FAQ noch den Rückgabewert von holbyte auf -1 ändern, da dieser -2 zurück gegeben hat. Habe den Author der FAQ schon informiert.

    Michael



  • Ich weiß zwar nicht, ob es zielführend ist, aber die Parität wird nicht auf 0x18 oder 0x08 gesetzt.

    psYkomaN schrieb:

    if((toupper(paritaet) == 'E')||(paritaet==3))
            tmp =  0x18;
        if((toupper(paritaet) == 'O')||(paritaet==1))
            tmp =  0x08;
    

    Anstatt 0xE sind gemäß dem Code 'E', 'e', 3 (für tmp = 0x18), '0', 0 oder 1 (für tmp = 0x08) gültige Werte.



  • Hallo Keksekekse,

    vielen Dank für Deine zahlreiche Hilfe.

    keksekekse schrieb:

    Ich weiß zwar nicht, ob es zielführend ist, aber die Parität wird nicht auf 0x18 oder 0x08 gesetzt.

    psYkomaN schrieb:

    if((toupper(paritaet) == 'E')||(paritaet==3))
            tmp =  0x18;
        if((toupper(paritaet) == 'O')||(paritaet==1))
            tmp =  0x08;
    

    Anstatt 0xE sind gemäß dem Code 'E', 'e', 3 (für tmp = 0x18), '0', 0 oder 1 (für tmp = 0x08) gültige Werte.

    // Main-Function
    void main(void){
        int comportResult;	// Result of COM-Initialisation
    	int comport = com[0];	// Comport
    	int receivedByte;	// Received byte
    	int sendByte;		// Received byte
    	int received_i=0;			// Iterator
    
    	// Initialisiere den COM-Port
    	comportResult = initcomport(0, 19200, 'E', 7, 2, 0, 4, 1600);
    	printf("Initialise: %d\n", comportResult);
    
    	// Setze DTR
    //	printf("Set DTR to 1\n");
    //	setzdtr(comport, 1);
    
    	// Status DCD
    	printf("Get Status DCD\n");
    	printf("Status DCD: %d\n", holdcd(comport));
    
    	// Status CTS
    	printf("Get Status CTS\n");
    	printf("Status CTS: %d\n", holcts(comport));
    
    /*
    	// Hole Byte	
    	printf("Lese Zeichen aus Buffer\n");
    	while(1){
    		receivedByte=holbyte(comport);
    		if (receivedByte != -1){
    			printf("%d", receivedByte);
    		}
    		received_i++;
    	}
    
    	printf("Einlesen beendet!\n");
    */
    
    	// Setze RTS
    	printf("Set RTS to 1\n");
    	setzrts(comport, 1);
    
    	// Sende Zeichen 'a'
    	printf("Send char %d to comport %d\n", 'a', comport);
    	sendebyte(comport, 'a');
    
    	// Setze RTS
    //	printf("Set RTS to 0\n");
    //	setzrts(comport, 0);
    
        return;
    

    Aber obiges funktioniert leider immer noch nicht.
    Das mit dem 'E' hatte ich ja früher richtig. Hatte es dann wegen Deinem vorletzen Beitrag wieder rausgenommen.

    Wo könnte der Fehler liegen?

    Viele Grüße

    Michael


Anmelden zum Antworten