【问题标题】:Read from serial port when data available数据可用时从串口读取
【发布时间】:2015-04-13 13:02:21
【问题描述】:

我正在尝试编写一个与连接到 GSM 调制解调器的串行端口通信的程序。使用 AT 命令与调制解调器通信。这是我的代码。从http://tldp.org/HOWTO/Serial-Programming-HOWTO/x115.html 得到它 - 规范输入处理。

当输出返回单行时它工作正常。例如:

AT 返回OK

我的问题是如果我发送AT+CPIN?,它会返回几行,例如:
+CPIN: SIM PIN
OK

但我的程序只读取+CPIN: SIM PIN 并且会中断。如何修复它?

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>

#define BAUDRATE B38400            
#define dev "/dev/ttyUSB0"
#define _POSIX_SOURCE 1

#define FALSE 0
#define TRUE 1

volatile int STOP=FALSE; 

main()
{
  char pinn[20];
  char buf[255];
  int fd,res=0;
  printf("%s\n", dev);
  struct termios oldtio,newtio;
  fd = open(dev, O_RDWR | O_NOCTTY ); 
  if (fd <0) {perror(dev); exit(-1); }
  bzero(&newtio, sizeof(newtio));
  newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;
  newtio.c_iflag = IGNPAR | ICRNL;
  newtio.c_oflag = 0;
  newtio.c_lflag = ICANON;
  newtio.c_cc[VMIN]     = 1;
  tcflush(fd, TCIFLUSH);
  tcsetattr(fd,TCSANOW,&newtio);


  if (fd < 0)
  {
      printf("Error opening serial port\n");
      exit(1);
  }
  while(1){

    scanf("%s",pinn);
    strcat(pinn,"\r");

    if (write(fd, pinn, strlen(pinn)) < strlen(pinn)) printf("Write error - %s \n", strerror(errno));
    pinn[strlen(pinn)-1]=0;
    while(1){
      res = read(fd,buf,255);
      buf[res]=0;
      buf[res-1]=0;
      if (res>1&&NULL==strstr(buf,pinn)) break;
    }
    printf("\"%s\"\n", buf);
  }
  close(fd);
}

代码更新删除重复读取

【问题讨论】:

  • 如果read 返回 0(EOF)或 -1(错误),您的代码将中断。

标签: c port at-command


【解决方案1】:

除了代码的其他小缺陷之外,如果返回的字符串不包含您最初发送的命令(NULL==strstr(buff, pinn)),您的接收while() 循环将终止。

当您收到多行结果时显然不满足此条件(因为只有第一行包含您发送的AT命令)。

如果你不想要,你需要改变它。

【讨论】:

  • 我实际上不明白那部分。原始代码是if (buf[0]=='z') STOP=TRUE;(在 url 中)。我应该如何更改它以接收多行结果?
  • 如果看不懂,为什么要改呢?你为什么要改变它现在的样子?无论如何,将该行更改为if (res == 0) break;。当您使用它时,将buf[res - 1] = 0; 更改为if (res &gt; 0) buf[res - 1] = '\0'。不好,但修复了可能的崩溃。
  • 您的 termios 设置将串行端口设置为阻塞(等到数据到达)。这就是您的read() 呼叫现在卡住的地方。尝试将newtio.c_cc[VMIN] = 0;newtio.c_cc[VTIME] = 5; 添加到您的终端设置中。这会将端口设置为非阻塞(等待半秒等待数据到达,然后返回)。但是,您必须为 read() 返回 0 做好准备。
  • newtio.c_cc[VMIN] = 1; 更改为 newtio.c_cc[VMIN] = 0; newtio.c_cc[VTIME] = 5; 但相同:(顺便说一句,当我发送任何内容时,它会返回下一行。这意味着返回 OK+CPIN: SIM PIN OK 。以防万一你可能需要这个:)
  • 这很清楚 - 我告诉过你,不是吗?关于阻止:将| O_NONBLOCK 添加到顶部的open() 选项中。之前忘记了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-24
相关资源
最近更新 更多