繁体   English   中英

C ++中串行通信的奇怪行为

[英]Strange behavior for serial communication in C++

我用C语言编写了用于USB通信的代码,所有代码都没有问题。 现在,我想用C ++迁移代码,但是当我编译并运行它时,输出结果非常奇怪,并且通信无法开始。 我并不真正理解原因。 有人可以帮助我吗? 以下是我的主要代码:

#include <unistd.h>
#include <arpa/inet.h>
#include <errno.h>
#include "UARTcom.h"

/**********************************************************
 *DEFINES
 **********************************************************/

// Define controll marker for serial transmission
#define SOH 0x01
#define STX 0x02
#define ETX 0x03

// Define dimensions
#define COMMAND_SIZE 16
#define DATA_SIZE 21

// Define imu data structure
typedef struct
{
  signed short x;
  signed short y;
  signed short z;
}
  data_sensor;

typedef struct
{
  data_sensor acc;
  data_sensor gyr;
  data_sensor mag;
}
  imu_data;

/**********************************************************
 *GLOBAL VARIABLES
 **********************************************************/

// Define global variables shared between process
int tcp_port, frame_ready, imu_ready;
char* serial_device;

/**********************************************************
 *FUNCTIONS DECLARATION
 **********************************************************/

void check_arg(int, char**);

int main(int argc, char **argv)
{
  imu_ready = 0;

  // Arguments controll and set tcp_port/serial_device variables
  check_arg(argc,argv);

  unsigned char command[COMMAND_SIZE];
  command[0] = SOH;
  command[1] = STX;
  command[3] = 0x80;
  command[15] = ETX;

  unsigned char temp_imu_data[DATA_SIZE];
  imu_data imu_xyz_data;
  memset(temp_imu_data, 0, sizeof(temp_imu_data));
  memset(&imu_xyz_data, 0, sizeof(imu_xyz_data));

  // Setup serial communication
  UARTcom *serial = new UARTcom(argv[2]);

  std::cout<<"=== SERIAL USB ==="<<std::endl;

  while(1)
    {
      if(command[0]==SOH && command[1]==STX && command[COMMAND_SIZE-1]==ETX)
        {
          if(serial->sendData(command, COMMAND_SIZE) < 0)
            {
              std::cout<<"controller(): Failed to send command to controller"<<std::endl;
            }
        }
          else
        {
          std::cout<<"controller(): Command to send corrupted"<<std::endl;
        }

      usleep(1000);

      if(serial->receiveData(temp_imu_data, DATA_SIZE) < 0)
    {
      std::cout<<"controller(): Failed to receive IMU data"<<std::endl;
    }

      usleep(1000);

      if(temp_imu_data[0]==SOH && temp_imu_data[1]==STX && temp_imu_data[DATA_SIZE-1]==ETX)
    {
      imu_xyz_data.acc.x = htons((short)(temp_imu_data[3] << 8) | temp_imu_data[2]);
      imu_xyz_data.acc.y = htons((short)(temp_imu_data[5] << 8) | temp_imu_data[4]);
      imu_xyz_data.acc.z = htons((short)(temp_imu_data[7] << 8) | temp_imu_data[6]);
      imu_xyz_data.gyr.x = htons((short)(temp_imu_data[9] << 8) | temp_imu_data[8]);
      imu_xyz_data.gyr.y = htons((short)(temp_imu_data[11] << 8) | temp_imu_data[10]);
      imu_xyz_data.gyr.z = htons((short)(temp_imu_data[13] << 8) | temp_imu_data[12]);
      imu_xyz_data.mag.x = htons((short)(temp_imu_data[15] << 8) | temp_imu_data[14]);
      imu_xyz_data.mag.y = htons((short)(temp_imu_data[17] << 8) | temp_imu_data[16]);
      imu_xyz_data.mag.z = htons((short)(temp_imu_data[19] << 8) | temp_imu_data[18]);

      std::cout<<"  "<<imu_xyz_data.acc.x<<"  "<<imu_xyz_data.acc.y<<"  "<<imu_xyz_data.acc.z<<std::endl;
      std::cout<<"  "<<imu_xyz_data.gyr.x<<"  "<<imu_xyz_data.gyr.y<<"  "<<imu_xyz_data.gyr.z<<std::endl;
      std::cout<<"  "<<imu_xyz_data.mag.x<<"  "<<imu_xyz_data.mag.y<<"  "<<imu_xyz_data.mag.z<<std::endl;
    }
      else
    {
      std::cout<<"controller(): IMU data corrupted"<<std::endl;
    }
    }
}

我的串行类定义,头文件

#include <unistd.h>
#include <stdlib.h>
#include <errno.h>

class UARTcom
{
 private:
  int serialFD;

 public:
  UARTcom(char *);
  ~UARTcom(void);
  int receiveData(unsigned char *, int);
  int sendData(unsigned char *, int); 
};

#endif

和cpp文件

#include "UARTcom.h"

/**********************************************************************
 *CONSTRUCTOR: Create a new connection to serial device and set the
 *communication to 8-bit, no parity, 1 stop bit
 *********************************************************************/
UARTcom::UARTcom(char *serialdevice) 
{
  if(serialFD = open(serialdevice, O_RDWR | O_NDELAY) < 0) 
    {
      std::cerr<<"UARTcom(): Open serial device failed";
      exit(1);
    }

  // Flush of input e output and setting blocking read mode
  tcflush(serialFD, TCIOFLUSH);
  fcntl(serialFD, F_SETFL, 0);

  // Create options structure and clear it
  struct termios options;
  memset(&options, 0, sizeof(struct termios));

  // Set input and output speed
  cfsetispeed(&options, (speed_t)B19200);
  cfsetospeed(&options, (speed_t)B19200);

  // CS8 = 8 data bits CREAD = enable receiver CLOCAL = local line, do not change owner of port
  options.c_cflag |= (CREAD | CS8 | CLOCAL);

  // After clear all option structure, CSTOPB and PARENB are already set properly
  options.c_iflag = IGNBRK;

  // Setting blocking read: at least 21 characters (dim. of package), timeout disabled
  options.c_cc[VMIN] = 21; 
  options.c_cc[VTIME] = 0;

  // Set options to serialSock
  tcsetattr(serialFD, TCSANOW, &options);

  std::cout<<"UARTcom(): Serial port open on "<<serialdevice<<std::endl;
}


/**********************************************************************
 *DESTRUCTOR: Close serial communication.
 *********************************************************************/
UARTcom::~UARTcom(void) 
{
  if(close(serialFD) < 0)
    {
      std::cerr<<"UARTcom(): Close serial failed";
      exit(1);
    }
  std::cout<<"Serial connection closed"<<std::endl;
}


/**********************************************************************
 *UARTcom::receiveData() receive data from serial device. 
 *********************************************************************/
int UARTcom::receiveData(unsigned char *data, int len)
{ 
  return read(serialFD, data, len);
} 


/**********************************************************************
 *UARTcom::sendData() send data to serial device. 
 *********************************************************************/
int UARTcom::sendData(unsigned char* data, int len)
{
  return write(serialFD, data, len);
}

当我编译并运行程序时,结果如下:

odroid@odroid:~/NistaGlass/SERIALE$ ./NGC1_SER 8080 /dev/ttyUSB0
UARTcom(): Serial port open on /dev/ttyUSB0
                                           === SERIAL USB ===
                                                             ����o�Killed

该程序除了不开始通信外,还会冻结并强迫我杀死它。

谁能解释为什么?

问题是此代码:

if(serialFD = open(serialdevice, O_RDWR | O_NDELAY) < 0)

<运算符比=运算符具有更高的优先级,因此serialFD设置为0 ,即比较的值,而不是open的返回值。 一些编译器会对此发出警告,因为在将赋值放入if语句时这是一个常见错误。 正确的行是:

if((serialFD = open(serialdevice, O_RDWR | O_NDELAY)) < 0)

但是,我建议将其分为两行,以使其更具可读性:

serialFD = open(serialdevice, O_RDWR | O_NDELAY);
if(serialFD < 0) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM