串行端口读/写返回过早 不相关,但即使C++有函数重载,我也不会建议将一个全局函数命名为与平台系统调用之一相同。例如写入或读取。这将使读者感到困惑,使代码更难维护。可能更相关的是,请记住串行通信在很大程度上是流式的,没有数据的开头或结尾。这意味着单个rea
串行端口读/写返回过早串行端口读/写返回过早 不相关,但即使C++有函数重载,我也不会建议将一个全局函数命名为与平台系统调用之一相同。例如写入或读取。这将使读者感到困惑,使代码更难维护。可能更相关的是,请记住串行通信在很大程度上是流式的,没有数据的开头或结尾。这意味着单个rea,c++,serial-port,at-command,C++,Serial Port,At Command,串行端口读/写返回过早 不相关,但即使C++有函数重载,我也不会建议将一个全局函数命名为与平台系统调用之一相同。例如写入或读取。这将使读者感到困惑,使代码更难维护。可能更相关的是,请记住串行通信在很大程度上是流式的,没有数据的开头或结尾。这意味着单个read调用将检索系统缓冲区中的内容,但它可能不是串行连接另一端发送的完整“消息”。如果你有什么特别的东西,你想作为一个消息“终结者”,那么你需要在一个循环中阅读,直到你收到它。消息以“确定”或“错误”终止。但是,未启用任何未经请求的消息。因此,无论
不相关,但即使C++有函数重载,我也不会建议将一个全局函数命名为与平台系统调用之一相同。例如
写入
或读取
。这将使读者感到困惑,使代码更难维护。可能更相关的是,请记住串行通信在很大程度上是流式的,没有数据的开头或结尾。这意味着单个read
调用将检索系统缓冲区中的内容,但它可能不是串行连接另一端发送的完整“消息”。如果你有什么特别的东西,你想作为一个消息“终结者”,那么你需要在一个循环中阅读,直到你收到它。消息以“确定”或“错误”终止。但是,未启用任何未经请求的消息。因此,无论我向端口写入什么,我都应该得到一个答案,仅此而已。但是,有些命令需要更长的时间来响应,有些则需要更少的时间。我不知道提前发出了什么。read()调用也不会生成字符串,因为memset()调用,它有点意外地工作。但如果它返回1024个字符,你就完蛋了。您必须一直调用read,直到得到\n
,将响应粘在一起,然后零终止它以生成字符串。最容易通过传递&response[len]和sizeof(response)-1来完成,其中len跟踪接收数据的累积大小。我不确定它是如何“有点”意外地工作的。如果你能帮我理解这一点。我预计数据字节的范围仅为16-32字节,因此缓冲区对于它所需要的东西来说太大了。我用以下命令打开端口:fd=open(“/dev/ttyUSB2”,O|RDWR | O|NOCTTY);我设置了cfmakeraw(&tty)。。。发布开放部分和配置部分对我有用吗?
I have written a small and simple serial port read/write application to connect to my modem and to run commands. There is a problem. The program works perfectly for the most part but when the command takes a bit of time to execute and respond, the program acts strangely. Here is my code:
void write (char cmd[256]) {
int n_written = 0;
char atcmd [259];
sprintf (atcmd, "%s\r\n", cmd);
n_written = write( fd, &atcmd, strlen(atcmd) );
printf ("WROTE: %d\n", n_written);
}
void read (char * cmdresp) {
int n = 0;
char response[1024];
memset(response, 0 , sizeof response);
n = read( fd, &response, sizeof (response) );
if (n < 0) {
printf ("ERROR=%d - %s\n", errno, strerror(errno));
} else if (n == 0) {
printf ("Read nothing!\n");
} else {
printf ("READ: %s\n", response);
strcpy (cmdresp, response);
}
}
void manage_transaction (char * message, char * response) {
tv.tv_sec = 5;
tv.tv_usec = 0;
write (message);
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
int retval = select(fd+1, &rfds, NULL, NULL, &tv);
if (retval == -1) {
perror("select()");
} else if (retval) {
if (FD_ISSET(fd, &rfds) ) {
usleep(200000);
read(response);
}
} else {
printf("No data within five seconds.\n");
}
}
Successful:
AT> AT+CGSN
Client ConnectedHere is the message: AT+CGSN
WROTE: 11
READ: AT+CGSN
123456789012345
OK
AT+CGSN
123456789012345
OK
FAILED:
AT> ATD11234567890;
Here is the message: ATD11234567890;
WROTE: 19
READ: ATD11234567890;
AT> 1234567890;
Here is the message:
WROTE: 4
READ:
OK
OK
AT>
int open_port(void)
{
fd = open("/dev/ttyUSB2", O_RDWR | O_NOCTTY);
if(fd == -1) {
perror("open_port: Unable to open /dev/ttyUSB2");
}
else {
fcntl(fd, F_SETFL, 0);
printf("port is open.\n");
}
tcflush(fd, TCIFLUSH);
tcflush(fd, TCOFLUSH);
return fd;
}
void config () {
struct termios tty;
struct termios tty_old;
memset (&tty, 0, sizeof tty);
if ( tcgetattr ( fd, &tty ) != 0 ) {
printf ("ERROR=%d - %s\n", errno, strerror(errno));
}
tty_old = tty;
/* Set Baud Rate */
cfsetospeed (&tty, (speed_t)B115200);
cfsetispeed (&tty, (speed_t)B115200);
tty.c_cflag &= ~PARENB; // Make 8n1
tty.c_cflag &= ~CSTOPB;
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8;
tty.c_iflag &= ~INPCK;
tty.c_iflag |= (IGNBRK | BRKINT);
tty.c_iflag |= IGNPAR;
tty.c_iflag &= ~ICRNL;
tty.c_iflag &= ~IXON;
tty.c_iflag &= ~ISTRIP;
tty.c_iflag &= ~INLCR;
tty.c_iflag &= ~IGNCR;
tty.c_cflag &= ~CRTSCTS; // no flow control
tty.c_cc[VMIN] = 0; // read doesn't block
tty.c_cc[VTIME] = 0; // 5 seconds read timeout
tty.c_cflag |= CREAD | CLOCAL; // turn on READ & ignore ctrl lines
tty.c_iflag &= ~(IXON |IXOFF|IXANY); /* no XON/XOFF flow control */
tty.c_oflag &= ~(IXON |IXOFF|IXANY); /* no XON/XOFF flow control */
tty.c_oflag &= ~(OPOST | ONLCR );
/* Make raw */
cfmakeraw(&tty);
/* Flush Port, then applies attributes */
tcflush(fd, TCIFLUSH );
tcflush(fd, TCIOFLUSH );
int reuse = 1;
setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse));
if ( (tcsetattr(fd,TCSANOW,&tty) < 0) ) {
printf ("ERROR=%d - %s\n", errno, strerror(errno));
}
}