我正在尝试修改此处写的代码: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;
}
答案 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.