Linux C ++ Serial Writing:只写一个字符

时间:2014-08-12 13:32:52

标签: c++ linux serial-port usb

我正在尝试修改此处写的代码:Linux C Serial Port Reading/Writing以便我可以通过串行(使用USB适配器)连接控制LED闪光灯单元。但是,当我尝试将12个命令写入设备,然后我用GTKterm和示波器检查LED状态时,看起来好像设备只接收第一个术语,即它正在接收命令( “百亿”)。我相信端口设置是正确的(虽然我可能完全错误)并且正确地附加了以下GTKterm中运行的命令图像!http://oi59.tinypic.com/27wrexx.jpg。是否有人知道为什么会发生这种情况? 非常感谢 萨姆

我的代码:

int flasher::allon(){
  int USB = open( "/dev/ttyUSB0", O_RDWR| O_NOCTTY );
  struct termios tty;
  struct termios tty_old;
  memset (&tty, 0, sizeof tty);

  /* Error Handling */
  if ( tcgetattr ( USB, &tty ) != 0 )
    {
      cout << "Error " << errno << " from tcgetattr: " << strerror(errno) << endl;
    }

  /* Save old tty parameters */
  tty_old = tty;

  /* Set Baud Rate */
  cfsetospeed (&tty, (speed_t)B9600);
  cfsetispeed (&tty, (speed_t)B9600);

  /* Setting other Port Stuff */
  tty.c_cflag     &=  ~PARENB;        // Make 8n1
  tty.c_cflag     &=  ~CSTOPB;
  tty.c_cflag     &=  ~CSIZE;
  tty.c_cflag     |=  CS8;  
  tty.c_cflag     &=  ~CRTSCTS;       // no flow control
  tty.c_cc[VMIN]      =   1;                  // read doesn't block
  tty.c_cc[VTIME]     =   5;                  // 0.5 seconds read timeout
  tty.c_cflag     |=  CREAD | CLOCAL;     // turn on READ & ignore ctrl lines

  /* Make raw */
  cfmakeraw(&tty);

  /* Flush Port, then applies attributes */
  tcflush( USB, TCIFLUSH );
  if ( tcsetattr ( USB, TCSANOW, &tty ) != 0)
     {
       cout << "Error " << errno << " from tcsetattr" << endl;
     }

  unsigned char cmd[] = "111111111111 \r\n";
  int n_written = 0;

  do {
    n_written += write( USB, &cmd[n_written], 1 );
  }
  while (cmd[n_written-1] != '\r' && n_written > 0);
  int n = 0;
  char buf = '\0';

  /* Whole response*/
  std::string response;

  do
    {
      n = read( USB, &buf, 1 );
      response.append( &buf );
    }
  while( buf != '\r' && n > 0);

  if (n < 0)
    {
      cout << "Error reading: " << strerror(errno) << endl;
    }
  else if (n == 0)
    {
      cout << "Read nothing!" << endl;
    }
  else
    {
      cout << "Response: " << response<<endl;
    }
  return 0;
}

1 个答案:

答案 0 :(得分:0)

由于这个原因,您的代码无法正常运行

string有一个append函数,它接受一个char *,但它需要一个以null结尾的字符串。你的buf只是一个字符,所以如果read()确实在其中放入了一个字符,则无法保证在内存中跟随它的内容,因此你没有一个正确的以空字符结尾的字符串但是未定义的行为。

你应该提供一个超过1个字符的缓冲区,然后使用一个长度为append的版本,传入n。

否则替换

response.append( &buf );

response.push_back( buf );

可能有效,但可能比使用多字符缓冲区效率低。在添加read之前,您应该检查read的结果。正如代码所代表的那样,如果while (cmd[n_written-1] != '\r' && n_written > 0); 失败,您无论如何都要追加。

该陈述如果有效,应该改变while子句的顺序

while ( n_written > 0 && cmd[n_written-1] != '\r');

如果n_written不是&gt; 0然后LHS是未定义的行为。所以

\r

你确定这是终止循环的正确条件吗?我认为write()是某种“消息结束”字符。

如果n_written返回-1,则不一定会将{{1}}推到或低于0.