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,
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.htmlAllerdings 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 completeWer 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