串行端口读/写返回过早 不相关,但即使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));
}
}