Question

I'm using WinCE 6.0 device for serial communication. It has 4 serial ports, of which I'm using 2, one is for RS232 and the other is for RS485. serial port configured with RS232 is working fine but for RS485 communication is not working below is the code,

int MbusSerialSlaveProtocol::startupServer(int slaveAddr,
                                       const TCHAR * const portName,
                                       long baudRate, int dataBits,
                                       int stopBits, int parity)
{
   int result;

   TRACELOG2("Open port: %d \n", portName);
   TRACELOG5("Parameters: %d, %d, %d, %d\n",
             baudRate, dataBits, stopBits, parity);
   TRACELOG2("Configuration: %d\n", timeOut);

   if (isStarted())
      return (FTALK_ILLEGAL_STATE_ERROR);

   if ((slaveAddr <= 0) || (slaveAddr > 255))
      return (FTALK_ILLEGAL_ARGUMENT_ERROR);
   this->slaveAddr = slaveAddr;

   if ((dataBits != SerialPort::SER_DATABITS_7) &&
       (dataBits != SerialPort::SER_DATABITS_8))
      return(FTALK_ILLEGAL_ARGUMENT_ERROR);

   // Close an existing connection
   if (serialPort.isOpen())
      serialPort.closePort();

   result = serialPort.openPort(portName);
   if (result == SerialPort::SER_PORT_NO_ACCESS)
      return(FTALK_PORT_NO_ACCESS);
   if (result == SerialPort::SER_ALREADY_OPEN)
      return(FTALK_PORT_ALREADY_OPEN);
   if (result != SerialPort::SER_SUCCESS)
      return(FTALK_OPEN_ERR);
   result = serialPort.config(baudRate, dataBits,
                              stopBits, parity,
                              SerialPort::SER_HANDSHAKE_NONE);
   if (result != SerialPort::SER_SUCCESS)
   {
      serialPort.closePort();
      return(FTALK_ILLEGAL_ARGUMENT_ERROR);
   }
   if (serialMode == SER_RS485)
      serialPort.clearRts();
   return (FTALK_SUCCESS);
}
int main()
{

    protocol = new ModbusSerialSlave(dataTable);
        int test = atce_uart_set_interface(6, 485);
        //result = 

    ((ModbusSerialSlave*)protocol)->startupServer(01,_T("COM6:"),19200,8,1,0);
            ((ModbusSerialSlave*)protocol)->enableRs485Mode(10);
            result = ((ModbusSerialSlave*)protocol)->startupServer(01,_T("COM6:"),port.nBaudRate,port.nDataBit,port.nStopBit,port.nParity);
while(1)
{
protocol->serverLoop();
}

}

/////////////////////////////////////////////////////////////////////// I changed RTS signal to toggle state, but still it's not working. I increased RTS delay to 1000, tried to send data device but not getting result. there is no error in port opening or parameter settings, I monitored those with writing error messages to files. here is a code for port open and config.

int SerialPort::openPort(const TCHAR * const portName)
{
ofstream config_file(TEST_FILE_NAME3);

   if (isOpen())
   {
       config_file.write("open1",5);
      closePort();
   }
   port = CreateFile(portName, GENERIC_READ | GENERIC_WRITE, 0, NULL,
                     OPEN_EXISTING, 0, NULL);
   if (port == INVALID_HANDLE_VALUE)
   {
      switch (GetLastError())
      {
         case ERROR_FILE_NOT_FOUND:
             {
                 config_file.write("open2",5);
         return (SER_PORT_NOT_FOUND);
             }
         case ERROR_ACCESS_DENIED:
             {
                 config_file.write("open3",5);
         return (SER_ALREADY_OPEN);
             }
         default:
             {
                 config_file.write("open4",5);
         return (SER_API_ERROR);
             }
      }
   }
//  SetupComm(port, 256, 256); //ttt
   // Save current device control block
   if (!GetCommState(port, &savedDevCtrlBlock))
   {
       config_file.write("open5",5);
      return (SER_API_ERROR);
   }
   this->flush(); // Needed on QNX 6 to clear a filled buffer
   config_file.write("open6",5);

   return (config(19200, SER_DATABITS_8, SER_STOPBITS_1,
           SER_PARITY_NONE, SER_HANDSHAKE_NONE));
}



int SerialPort::config(long baudRate, int dataBits,
                       int stopBits, int parity, int flowControl)
{
   DCB devCtrlBlock;
 ofstream config_file(TEST_FILE_NAME);
   if (!isOpen())
   {
        config_file.write("Line1",5);
      return (SER_NOT_OPEN);
   }

   //
   // Retrieve current device control block
   //
   if (!GetCommState(port, &devCtrlBlock))
   {
        config_file.write("Line2",5);
      return (SER_API_ERROR);
   }

   //
   // Modify device control block
   //
   devCtrlBlock.BaudRate = baudRate;
   switch (dataBits)
   {
      case SER_DATABITS_7:
         devCtrlBlock.ByteSize = 7;
      break;
      case SER_DATABITS_8:
         devCtrlBlock.ByteSize = 8;
      break;
      default:
          {
               config_file.write("Line3",5);
                return (SER_INVALID_PARAMETER);
          }
   }
   switch (stopBits)
   {
      case SER_STOPBITS_1:
         devCtrlBlock.StopBits = ONESTOPBIT;
      break;
      case SER_STOPBITS_2:
         devCtrlBlock.StopBits = TWOSTOPBITS;
      break;
      default:
          {
               config_file.write("Line4",5);
      return (SER_INVALID_PARAMETER);
          }
   }
   switch (parity)
   {
      case SER_PARITY_NONE:
         devCtrlBlock.fParity = FALSE;
         devCtrlBlock.Parity = NOPARITY;
      break;
      case SER_PARITY_EVEN:
         devCtrlBlock.fParity = TRUE;
         devCtrlBlock.Parity = EVENPARITY;
      break;
      case SER_PARITY_ODD:
         devCtrlBlock.fParity = TRUE;
         devCtrlBlock.Parity = ODDPARITY;
      break;
      default:
          {
               config_file.write("Line5",5);
      return (SER_INVALID_PARAMETER);
          }
   }
   switch (flowControl)
   {
      case SER_HANDSHAKE_RTS_CTS:
         devCtrlBlock.fOutX = FALSE; // Disable output X-ON/X-OFF
         devCtrlBlock.fInX = FALSE; // Disable input X-ON/X-OFF
         devCtrlBlock.fOutxCtsFlow = TRUE;
         devCtrlBlock.fOutxDsrFlow = FALSE;
         devCtrlBlock.fRtsControl = RTS_CONTROL_HANDSHAKE;
         devCtrlBlock.fDtrControl = DTR_CONTROL_ENABLE;
         devCtrlBlock.fDsrSensitivity = FALSE;
      break;
      case SER_HANDSHAKE_NONE:
         devCtrlBlock.fOutX = FALSE; // Disable output X-ON/X-OFF
         devCtrlBlock.fInX = FALSE; // Disable input X-ON/X-OFF
         devCtrlBlock.fOutxCtsFlow = FALSE;
         devCtrlBlock.fOutxDsrFlow = FALSE;
         devCtrlBlock.fRtsControl = RTS_CONTROL_TOGGLE;
         devCtrlBlock.fDtrControl = DTR_CONTROL_ENABLE;
         devCtrlBlock.fDsrSensitivity = FALSE;
      break;
      default:
          {
               config_file.write("Line6",5);
      return (SER_INVALID_PARAMETER);
          }
   }
   devCtrlBlock.fBinary = TRUE;
   devCtrlBlock.fErrorChar = FALSE;
   devCtrlBlock.fNull = FALSE;
   devCtrlBlock.fAbortOnError = FALSE;

   //
   // Store device control block
   //
   if (!SetCommState(port, &devCtrlBlock))
   {
        config_file.write("Line7",5);
      return (SER_INVALID_PARAMETER);
   }
   this->baudRate = baudRate;
   this->flowControl = flowControl;
config_file.write("Line8",5);

   return (SER_SUCCESS);
}
Was it helpful?

Solution

I see that you clear the RTS signal, I suppose that this is used to enable the RS485 transceiver. RS485 is usually half duplex and you need to enable/disable transmission each time you send data. If you don't you can't transmit or, being always in transmission, you can't receive any data from other devices on the same line. You may need to toggle this signal to make the communication work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top