我正在尝试使用 FTDI 通过 USB 端口发送/接收数据,因此我需要使用 C/C++ 处理串行通信。我正在使用Linux(Ubuntu)。
基本上,我连接到一个正在监听传入命令的设备。我需要发送这些命令并读取设备的响应。命令和响应都是ASCII 字符。
使用 GtkTerm 一切正常,但是当我切换到 C 编程时,我遇到了问题。
这是我的代码:
#include <stdio.h> // standard input / output functions
#include <stdlib.h>
#include <string.h> // string function definitions
#include <unistd.h> // UNIX standard function definitions
#include <fcntl.h> // File control definitions
#include <errno.h> // Error number definitions
#include <termios.h> // POSIX terminal control definitions
/* Open File Descriptor */
int USB = open( "/dev/ttyUSB0", O_RDWR| O_NONBLOCK | O_NDELAY );
/* Error Handling */
if ( USB < 0 )
{
cout << "Error " << errno << " opening " << "/dev/ttyUSB0" << ": " << strerror (errno) << endl;
}
/* *** Configure Port *** */
struct termios tty;
memset (&tty, 0, sizeof tty);
/* Error Handling */
if ( tcgetattr ( USB, &tty ) != 0 )
{
cout << "Error " << errno << " from tcgetattr: " << strerror(errno) << endl;
}
/* Set Baud Rate */
cfsetospeed (&tty, B9600);
cfsetispeed (&tty, 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_lflag = 0; // no signaling chars, no echo, no canonical processing
tty.c_oflag = 0; // no remapping, no delays
tty.c_cc[VMIN] = 0; // 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
tty.c_iflag &= ~(IXON | IXOFF | IXANY);// turn off s/w flow ctrl
tty.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); // make raw
tty.c_oflag &= ~OPOST; // make raw
/* Flush Port, then applies attributes */
tcflush( USB, TCIFLUSH );
if ( tcsetattr ( USB, TCSANOW, &tty ) != 0)
{
cout << "Error " << errno << " from tcsetattr" << endl;
}
/* *** WRITE *** */
unsigned char cmd[] = {'I', 'N', 'I', 'T', ' ', '\r', '\0'};
int n_written = write( USB, cmd, sizeof(cmd) -1 );
/* Allocate memory for read buffer */
char buf [256];
memset (&buf, '\0', sizeof buf);
/* *** READ *** */
int n = read( USB, &buf , sizeof buf );
/* Error Handling */
if (n < 0)
{
cout << "Error reading: " << strerror(errno) << endl;
}
/* Print what I read... */
cout << "Read: " << buf << endl;
close(USB);
发生的情况是read()
返回 0(根本没有读取字节)或阻塞直到超时(VTIME
)。我假设发生这种情况是因为write()
不发送任何内容。在这种情况下,设备不会收到命令,我也无法收到响应。事实上,在我的程序被阻止读取时关闭设备实际上成功地获得了响应(设备在关闭时发送了一些东西)。
奇怪的是,添加这个
cout << "I've written: " << n_written << "bytes" << endl;
通话后write()
,我立即收到:
I've written 6 bytes
这正是我所期望的。只有我的程序不能正常工作,就像我的设备无法接收我在端口上实际写入的内容。
我尝试了不同的事情和解决方案,还涉及数据类型(我尝试使用 std::string,例如cmd = "INIT \r"
or const char
),但没有任何效果。
有人能告诉我哪里错了吗?
先感谢您。
编辑: 使用此代码的先前版本
unsigned char cmd[] = "INIT \n"
还有cmd[] = "INIT \r\n"
。我更改了它,因为我的设备的命令 sintax 报告为
<command><SPACE><CR>
.
我也尝试过O_NONBLOCK
在阅读时避免使用标志,但我只会一直阻止。我试过使用select()
但没有任何反应。只是为了尝试,我创建了一个等待循环,直到数据可用,但我的代码永远不会退出循环。顺便说一句,等待或者usleep()
是我需要避免的事情。报告的只是我的代码的摘录。完整的代码需要在实时环境(特别是 OROCOS)中工作,所以我真的不想要类似睡眠的功能。