M
Michael Post
Hello members,
i have a (time-(?))-problem with the serial-communication with an ms-
dos 6.2 and the rs232-interface with an rs485-adapter behind the
interface.
I program in C. As compiler, i am using Open Watcom to build a DOS 16-
bit executable.
When i send the telegram to the device, the device answers very fast
(<1 millisecond).
After complete sending, i set the rts to 0x0 and wait for the answer,
but i got no answer, or i am to slow.
Somewhere is the error.
Maybe someone has some ideas or can give me some tips for better
coding?
Thanks for your help.
Here is my complete code:
#include <stdio.h>
//#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <time.h>
/*
* Define some program keys
*/
// Exit-States
#define EXIT_SUCCESS 1
#define EXIT_UNSUCCESS 0
/**
* Define some information which should be outsourced to a config file
*/
// Sum of devices at COM1
#define SUM_DEVICES_COM1 1
/**
* Constants for serial port
*/
// Return values / Error codes
#define SERIAL_OK 1
#define SERIAL_E_COMPORT_NOT_DEFINED -1
#define SERIAL_E_WRONG_COMPT -2
#define SERIAL_E_WRONG_COMORT -3
// Serial mode for register 3
#define SERIAL_MODE_5BIT 0x00 // Bit
0-1: 00
#define SERIAL_MODE_6BIT 0x01 // Bit
0-1: 01
#define SERIAL_MODE_7BIT 0x02 // Bit
0-1: 10
#define SERIAL_MODE_8BIT 0x03 // Bit
0-1: 11
#define SERIAL_MODE_1STOPBIT 0x00 // Bit 2: 0
#define SERIAL_MODE_2STOPBIT 0x04 // Bit 2: 1
#define SERIAL_MODE_PARITY_NON 0x00 // Bit 3-5: 000
#define SERIAL_MODE_PARITY_ODD 0x08 // Bit 3-5: 001
#define SERIAL_MODE_PARITY_EVEN 0x18 // Bit 3-5: 011
#define SERIAL_MODE_PARITY_MARK 0x28 // Bit 3-5: 101
#define SERIAL_MODE_PARITY_SPACE 0x38 // Bit 3-5: 111
#define SERIAL_MODE_BREAK_CONTROL 0x40 // Bit 6: 0 or
1 Break control;
sends the receiver a break condition
#define SERIAL_MODE_ENABLE_DLR 0x80 // Bit 7: 0 or
1 DLR access
enable; if set, registers 0 and 1 become one big word register (the
DLR)
/**
* Function-Prototypes
*/
int serialInterfaceConnect(int nComPort, const int nBaud, const int
nMode);
void serialInterfaceSetBaudrate(int nComPort, const int nBaud);
char serialInterfaceGetRegister(int nComPort, int nRegister);
void serialInterfaceSendData(int nComPort, char *cString, int nLen);
int serialInterfaceConnect(int nComPort, const int nBaud, const int
nMode);
int serialInterfaceGetPort(int nComPort);
void serialInterfaceSendTelegram(int nCom, char cCommand, int
nSensor);
char vaseGenerateChecksum(const char *cTelegram);
/**
* Functions / Routines
*/
int main(){
int i=1;
int c1=0,c2=0;
int input;
int ii=0, rts_delay=20000;
/* Connect to COM2 */
if(serialInterfaceConnect(serialInterfaceGetPort(2), 1200,
SERIAL_MODE_7BIT | SERIAL_MODE_2STOPBIT | SERIAL_MODE_PARITY_EVEN)){
printf("Connected to COM2.\n");
saveToLog(DEBUG, "Connect to COM2.");
/* Connect to COM1 */
if(serialInterfaceConnect(serialInterfaceGetPort(1),
19200,
SERIAL_MODE_7BIT | SERIAL_MODE_2STOPBIT | SERIAL_MODE_PARITY_EVEN)){
printf("Connected to COM1.\n");
saveToLog(DEBUG, "Connect to COM1.");
/**
* Initialise all devices
*/
printf("*** Initialise devices ***\n");
for(i=1;i<=SUM_DEVICES_COM1; i++){
// for every device at com1
// Initialise sensor
printf("Activate sensor %d.\n",i);
saveToLog(INFO, "Activate sensor " +
i);
serialInterfaceSendTelegram(serialInterfaceGetPort(1), 'T', i);
// Receive result
c1 = 0;
c1 = inp(serialInterfaceGetPort(1) +
5);
// If so, then get Char
while(c1 & 1){
c2 =
inp(serialInterfaceGetPort(1) + 0);
printf("IN %c
\n",c2); // Print Char to Screen
c1 =
inp(serialInterfaceGetPort(1) + 5);
}// end while
// wait 500 milliseconds
delay(500);
// Get Version
printf("Get Version from sensor %d.
\n", i);
saveToLog(INFO, "Get Version from
sensor.");
saveToLog(INFO, i);
serialInterfaceSendTelegram(serialInterfaceGetPort(1), 'V', i);
// Receive result
c1 = 0;
c1 = inp(serialInterfaceGetPort(1) +
5);
// If so, then get Char
while(c1 & 1){
c2 =
inp(serialInterfaceGetPort(1) + 0);
printf("IN %c
\n",c2); // Print Char to Screen
c1 =
inp(serialInterfaceGetPort(1) + 5);
}// end while
}// end initialise for every device
}
else {
printf("Error: Could not connect to COM1.\n");
saveToLog(ERROR, "Could not connect to
COM1.");
return EXIT_UNSUCCESS;
}
}
else {
printf("Error: Could not connect to COM2.\n");
saveToLog(ERROR, "Could not connect to COM2.");
return EXIT_UNSUCCESS;
}
return EXIT_SUCCESS;
}// end function main
int serialInterfaceConnect(int nCom, const int nBaud, const int nMode)
{
/*
* This function connect to an specified serial-port
*/
int nTmp = 0;
outp(nCom + 1, 0); // Turn off interrupts
outp(nCom + 3, 0x80); // SET DLAB ON
serialInterfaceSetBaudrate(nCom, nBaud); // Set
baud rate
nTmp = nMode & 0x03;
if(nTmp == SERIAL_MODE_5BIT)
saveToLog(DEBUG, " SERIAL_MODE_5BIT");
if(nTmp == SERIAL_MODE_6BIT)
saveToLog(DEBUG, " SERIAL_MODE_6BIT");
if(nTmp == SERIAL_MODE_7BIT)
saveToLog(DEBUG, " SERIAL_MODE_7BIT");
if(nTmp == SERIAL_MODE_8BIT)
saveToLog(DEBUG, " SERIAL_MODE_8BIT");
nTmp = nMode & 0x04;
if(nTmp == SERIAL_MODE_1STOPBIT)
saveToLog(DEBUG, " SERIAL_MODE_1STOPBIT");
if(nTmp == SERIAL_MODE_2STOPBIT)
saveToLog(DEBUG, " SERIAL_MODE_2STOPBIT");
nTmp = nMode & 0x38;
if(nTmp == SERIAL_MODE_PARITY_NON)
saveToLog(DEBUG, " SERIAL_MODE_PARITY_NON");
if(nTmp == SERIAL_MODE_PARITY_ODD)
saveToLog(DEBUG, " SERIAL_MODE_PARITY_ODD");
if(nTmp == SERIAL_MODE_PARITY_EVEN)
saveToLog(DEBUG, " SERIAL_MODE_PARITY_EVEN");
if(nTmp == SERIAL_MODE_PARITY_MARK)
saveToLog(DEBUG, " SERIAL_MODE_PARITY_MARK");
if(nTmp == SERIAL_MODE_PARITY_SPACE)
saveToLog(DEBUG, " SERIAL_MODE_PARITY_SPACE");
nTmp = nMode & SERIAL_MODE_BREAK_CONTROL;
if(nTmp == SERIAL_MODE_BREAK_CONTROL)
saveToLog(DEBUG, " SERIAL_MODE_BREAK_CONTROL");
nTmp = nMode & SERIAL_MODE_ENABLE_DLR;
if(nTmp == SERIAL_MODE_ENABLE_DLR)
saveToLog(DEBUG, " SERIAL_MODE_ENABLE_DLR");
outp(nCom + 3, nMode);
outp(nCom + 2, 0xC7); // FIFO Control Register
saveToLog(DEBUG, "Turn off RTS.");
outp(nCom + 4, 0x0); // Turn off DTR, RTS, and OUT2
return SERIAL_OK;
}
void serialInterfaceSetBaudrate(int nCom, const int nBaud){
int nDivisor = 115200 / nBaud; // 0x1c200 / nBaud
// nDivisor defaults:
// ------------------
// 0x03 = 38,400 BPS
// 0x01 = 115,200 BPS
// 0x02 = 57,600 BPS
// 0x06 = 19,200 BPS
// 0x0C = 9,600 BPS
// 0x18 = 4,800 BPS
// 0x30 = 2,400 BPS
// 0x60 = 1,200 BPS
outp(nCom + 0, nDivisor); // Set Baud rate - Divisor
Latch Low Byte
outp(nCom + 1, 0x00); // Set Baud rate - Divisor
Latch High Byte
}
void serialInterfaceSendData(int nCom, char *cString, int nLen){
int i=0;
for(; i<nLen; i++){
outp(nCom + 0, cString);
}// end for
}
int serialInterfaceGetPort(int nComPort){
/**
* This functions get the adress for the port
*/
int nPort = 0;
switch(nComPort){
case 1:
nPort = 0x3F8;
break;
case 2:
nPort = 0x2F8;
break;
case 3:
nPort = 0x3E8;
break;
case 4:
nPort = 0x2E8;
break;
default:
return SERIAL_E_COMPORT_NOT_DEFINED;
}
printf("Return for %d comPort %d.\n", nComPort, nPort);
return nPort;
}
void serialInterfaceSendTelegram(int nCom, char cCommand, int nSensor)
{
/*
* This function sends a defined telegram over register 4
* to the sensor
*/
char cBuf[10];
char cChecksum;
char cTelegram[5];
int nLen;
int i = 0;
int c1, c2;
printf("Send Telegram for %d.\n", nCom);
// Build telegram data
cTelegram[0] = 'b';
cTelegram[1] = cCommand;
cTelegram[2] = nSensor + 48; // + '0'
cTelegram[3] = '\r';
cTelegram[4] = 0x0;
// Generate checksum
cChecksum = baseGenerateChecksum((char*) &cTelegram[0]);
// Data to send
strcpy(cBuf, cTelegram);
nLen = strlen(cTelegram);
cBuf[4] = cChecksum;
nLen++;
cBuf[5] = 0x0;
nLen++;
/*
* Send telegram to COM
*/
printf("Send telegram manually to OUT: %s\n", cBuf);
// printf("Telegram is %d characters long.\n",nLen);
// Open RTS
outp(nCom + 4, 0x0B); // Turn on RTS
for(i=0;i<nLen;i++){
// Send data
printf("Data %c\n.", cBuf);
outp(nCom + 0, cBuf);
}
// Close RTS
outp(nCom + 4, 0x0); // Turn off RTS
} // end function
char baseGenerateChecksum(const char *cTelegram){
int nChecksum = 0;
unsigned int i=0;
for(; i<strlen(cTelegram); i++) {
nChecksum = nChecksum ^ cTelegram; // Jedes Zeichen
mit XOR
verknüpfen
}
// Letztes Zeichen muss ein \r (ASCII 13) sein.
if(cTelegram[strlen(cTelegram) - 1] != '\r')
nChecksum = nChecksum ^ '\r';
nChecksum = nChecksum ^ 0xFF; // invertieren
nChecksum = nChecksum & 0x7F; // auf 7 Bit beschneiden
return (char) nChecksum;
i have a (time-(?))-problem with the serial-communication with an ms-
dos 6.2 and the rs232-interface with an rs485-adapter behind the
interface.
I program in C. As compiler, i am using Open Watcom to build a DOS 16-
bit executable.
When i send the telegram to the device, the device answers very fast
(<1 millisecond).
After complete sending, i set the rts to 0x0 and wait for the answer,
but i got no answer, or i am to slow.
Somewhere is the error.
Maybe someone has some ideas or can give me some tips for better
coding?
Thanks for your help.
Here is my complete code:
#include <stdio.h>
//#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <time.h>
/*
* Define some program keys
*/
// Exit-States
#define EXIT_SUCCESS 1
#define EXIT_UNSUCCESS 0
/**
* Define some information which should be outsourced to a config file
*/
// Sum of devices at COM1
#define SUM_DEVICES_COM1 1
/**
* Constants for serial port
*/
// Return values / Error codes
#define SERIAL_OK 1
#define SERIAL_E_COMPORT_NOT_DEFINED -1
#define SERIAL_E_WRONG_COMPT -2
#define SERIAL_E_WRONG_COMORT -3
// Serial mode for register 3
#define SERIAL_MODE_5BIT 0x00 // Bit
0-1: 00
#define SERIAL_MODE_6BIT 0x01 // Bit
0-1: 01
#define SERIAL_MODE_7BIT 0x02 // Bit
0-1: 10
#define SERIAL_MODE_8BIT 0x03 // Bit
0-1: 11
#define SERIAL_MODE_1STOPBIT 0x00 // Bit 2: 0
#define SERIAL_MODE_2STOPBIT 0x04 // Bit 2: 1
#define SERIAL_MODE_PARITY_NON 0x00 // Bit 3-5: 000
#define SERIAL_MODE_PARITY_ODD 0x08 // Bit 3-5: 001
#define SERIAL_MODE_PARITY_EVEN 0x18 // Bit 3-5: 011
#define SERIAL_MODE_PARITY_MARK 0x28 // Bit 3-5: 101
#define SERIAL_MODE_PARITY_SPACE 0x38 // Bit 3-5: 111
#define SERIAL_MODE_BREAK_CONTROL 0x40 // Bit 6: 0 or
1 Break control;
sends the receiver a break condition
#define SERIAL_MODE_ENABLE_DLR 0x80 // Bit 7: 0 or
1 DLR access
enable; if set, registers 0 and 1 become one big word register (the
DLR)
/**
* Function-Prototypes
*/
int serialInterfaceConnect(int nComPort, const int nBaud, const int
nMode);
void serialInterfaceSetBaudrate(int nComPort, const int nBaud);
char serialInterfaceGetRegister(int nComPort, int nRegister);
void serialInterfaceSendData(int nComPort, char *cString, int nLen);
int serialInterfaceConnect(int nComPort, const int nBaud, const int
nMode);
int serialInterfaceGetPort(int nComPort);
void serialInterfaceSendTelegram(int nCom, char cCommand, int
nSensor);
char vaseGenerateChecksum(const char *cTelegram);
/**
* Functions / Routines
*/
int main(){
int i=1;
int c1=0,c2=0;
int input;
int ii=0, rts_delay=20000;
/* Connect to COM2 */
if(serialInterfaceConnect(serialInterfaceGetPort(2), 1200,
SERIAL_MODE_7BIT | SERIAL_MODE_2STOPBIT | SERIAL_MODE_PARITY_EVEN)){
printf("Connected to COM2.\n");
saveToLog(DEBUG, "Connect to COM2.");
/* Connect to COM1 */
if(serialInterfaceConnect(serialInterfaceGetPort(1),
19200,
SERIAL_MODE_7BIT | SERIAL_MODE_2STOPBIT | SERIAL_MODE_PARITY_EVEN)){
printf("Connected to COM1.\n");
saveToLog(DEBUG, "Connect to COM1.");
/**
* Initialise all devices
*/
printf("*** Initialise devices ***\n");
for(i=1;i<=SUM_DEVICES_COM1; i++){
// for every device at com1
// Initialise sensor
printf("Activate sensor %d.\n",i);
saveToLog(INFO, "Activate sensor " +
i);
serialInterfaceSendTelegram(serialInterfaceGetPort(1), 'T', i);
// Receive result
c1 = 0;
c1 = inp(serialInterfaceGetPort(1) +
5);
// If so, then get Char
while(c1 & 1){
c2 =
inp(serialInterfaceGetPort(1) + 0);
printf("IN %c
\n",c2); // Print Char to Screen
c1 =
inp(serialInterfaceGetPort(1) + 5);
}// end while
// wait 500 milliseconds
delay(500);
// Get Version
printf("Get Version from sensor %d.
\n", i);
saveToLog(INFO, "Get Version from
sensor.");
saveToLog(INFO, i);
serialInterfaceSendTelegram(serialInterfaceGetPort(1), 'V', i);
// Receive result
c1 = 0;
c1 = inp(serialInterfaceGetPort(1) +
5);
// If so, then get Char
while(c1 & 1){
c2 =
inp(serialInterfaceGetPort(1) + 0);
printf("IN %c
\n",c2); // Print Char to Screen
c1 =
inp(serialInterfaceGetPort(1) + 5);
}// end while
}// end initialise for every device
}
else {
printf("Error: Could not connect to COM1.\n");
saveToLog(ERROR, "Could not connect to
COM1.");
return EXIT_UNSUCCESS;
}
}
else {
printf("Error: Could not connect to COM2.\n");
saveToLog(ERROR, "Could not connect to COM2.");
return EXIT_UNSUCCESS;
}
return EXIT_SUCCESS;
}// end function main
int serialInterfaceConnect(int nCom, const int nBaud, const int nMode)
{
/*
* This function connect to an specified serial-port
*/
int nTmp = 0;
outp(nCom + 1, 0); // Turn off interrupts
outp(nCom + 3, 0x80); // SET DLAB ON
serialInterfaceSetBaudrate(nCom, nBaud); // Set
baud rate
nTmp = nMode & 0x03;
if(nTmp == SERIAL_MODE_5BIT)
saveToLog(DEBUG, " SERIAL_MODE_5BIT");
if(nTmp == SERIAL_MODE_6BIT)
saveToLog(DEBUG, " SERIAL_MODE_6BIT");
if(nTmp == SERIAL_MODE_7BIT)
saveToLog(DEBUG, " SERIAL_MODE_7BIT");
if(nTmp == SERIAL_MODE_8BIT)
saveToLog(DEBUG, " SERIAL_MODE_8BIT");
nTmp = nMode & 0x04;
if(nTmp == SERIAL_MODE_1STOPBIT)
saveToLog(DEBUG, " SERIAL_MODE_1STOPBIT");
if(nTmp == SERIAL_MODE_2STOPBIT)
saveToLog(DEBUG, " SERIAL_MODE_2STOPBIT");
nTmp = nMode & 0x38;
if(nTmp == SERIAL_MODE_PARITY_NON)
saveToLog(DEBUG, " SERIAL_MODE_PARITY_NON");
if(nTmp == SERIAL_MODE_PARITY_ODD)
saveToLog(DEBUG, " SERIAL_MODE_PARITY_ODD");
if(nTmp == SERIAL_MODE_PARITY_EVEN)
saveToLog(DEBUG, " SERIAL_MODE_PARITY_EVEN");
if(nTmp == SERIAL_MODE_PARITY_MARK)
saveToLog(DEBUG, " SERIAL_MODE_PARITY_MARK");
if(nTmp == SERIAL_MODE_PARITY_SPACE)
saveToLog(DEBUG, " SERIAL_MODE_PARITY_SPACE");
nTmp = nMode & SERIAL_MODE_BREAK_CONTROL;
if(nTmp == SERIAL_MODE_BREAK_CONTROL)
saveToLog(DEBUG, " SERIAL_MODE_BREAK_CONTROL");
nTmp = nMode & SERIAL_MODE_ENABLE_DLR;
if(nTmp == SERIAL_MODE_ENABLE_DLR)
saveToLog(DEBUG, " SERIAL_MODE_ENABLE_DLR");
outp(nCom + 3, nMode);
outp(nCom + 2, 0xC7); // FIFO Control Register
saveToLog(DEBUG, "Turn off RTS.");
outp(nCom + 4, 0x0); // Turn off DTR, RTS, and OUT2
return SERIAL_OK;
}
void serialInterfaceSetBaudrate(int nCom, const int nBaud){
int nDivisor = 115200 / nBaud; // 0x1c200 / nBaud
// nDivisor defaults:
// ------------------
// 0x03 = 38,400 BPS
// 0x01 = 115,200 BPS
// 0x02 = 57,600 BPS
// 0x06 = 19,200 BPS
// 0x0C = 9,600 BPS
// 0x18 = 4,800 BPS
// 0x30 = 2,400 BPS
// 0x60 = 1,200 BPS
outp(nCom + 0, nDivisor); // Set Baud rate - Divisor
Latch Low Byte
outp(nCom + 1, 0x00); // Set Baud rate - Divisor
Latch High Byte
}
void serialInterfaceSendData(int nCom, char *cString, int nLen){
int i=0;
for(; i<nLen; i++){
outp(nCom + 0, cString);
}// end for
}
int serialInterfaceGetPort(int nComPort){
/**
* This functions get the adress for the port
*/
int nPort = 0;
switch(nComPort){
case 1:
nPort = 0x3F8;
break;
case 2:
nPort = 0x2F8;
break;
case 3:
nPort = 0x3E8;
break;
case 4:
nPort = 0x2E8;
break;
default:
return SERIAL_E_COMPORT_NOT_DEFINED;
}
printf("Return for %d comPort %d.\n", nComPort, nPort);
return nPort;
}
void serialInterfaceSendTelegram(int nCom, char cCommand, int nSensor)
{
/*
* This function sends a defined telegram over register 4
* to the sensor
*/
char cBuf[10];
char cChecksum;
char cTelegram[5];
int nLen;
int i = 0;
int c1, c2;
printf("Send Telegram for %d.\n", nCom);
// Build telegram data
cTelegram[0] = 'b';
cTelegram[1] = cCommand;
cTelegram[2] = nSensor + 48; // + '0'
cTelegram[3] = '\r';
cTelegram[4] = 0x0;
// Generate checksum
cChecksum = baseGenerateChecksum((char*) &cTelegram[0]);
// Data to send
strcpy(cBuf, cTelegram);
nLen = strlen(cTelegram);
cBuf[4] = cChecksum;
nLen++;
cBuf[5] = 0x0;
nLen++;
/*
* Send telegram to COM
*/
printf("Send telegram manually to OUT: %s\n", cBuf);
// printf("Telegram is %d characters long.\n",nLen);
// Open RTS
outp(nCom + 4, 0x0B); // Turn on RTS
for(i=0;i<nLen;i++){
// Send data
printf("Data %c\n.", cBuf);
outp(nCom + 0, cBuf);
}
// Close RTS
outp(nCom + 4, 0x0); // Turn off RTS
} // end function
char baseGenerateChecksum(const char *cTelegram){
int nChecksum = 0;
unsigned int i=0;
for(; i<strlen(cTelegram); i++) {
nChecksum = nChecksum ^ cTelegram; // Jedes Zeichen
mit XOR
verknüpfen
}
// Letztes Zeichen muss ein \r (ASCII 13) sein.
if(cTelegram[strlen(cTelegram) - 1] != '\r')
nChecksum = nChecksum ^ '\r';
nChecksum = nChecksum ^ 0xFF; // invertieren
nChecksum = nChecksum & 0x7F; // auf 7 Bit beschneiden
return (char) nChecksum;