gps信息,以字符$开始,以字符\n结尾。
你的代码问题处在对结尾的判断上。
每次读到数据后,首先应该放入一个缓冲区的后面。之后从缓冲区的第一个字节开始扫描,找到一对$和\n,然后打印该信息,并将后面的内容拷贝到前面。
读串口的误区:
读出来的信息是完整的。 串口的信息只是代表当时有多少数据,不保证数据是帧对其的。
即使第一次读到了$,不代表第二次读到的恰好是末尾的字符串。有可能更长(包含下一条信息的一部分)或者更短。
open(dev, O_NONBLOCK|O_RDWR)..... 非阻塞------解决方案--------------------
C/C++ codefd = open( Dev, O_RDWR | O_NOCTTY)
options.c_cc[VTIME] = 0/* 等待100ms* 该值等待时间就返回 */
options.c_cc[VMIN] = 1/* 接收到该值数量字节就返回 */
/* 上面两个条件为非零时才有效,两个都为非零时任意一个条件达到都返回,如果两个条件都为零,则马上返回 */
tcflush(fd,TCIFLUSH) /* Update the options and do it NOW */
if (tcsetattr(fd,TCSANOW,&options) != 0){
return ERRCOM_SETATTR
}
return ERRCOM_OK
------解决方案--------------------
两个都为非零时任意一个条件达到都返回
如果两个条件都为零,则马上返回
如果一个为非零,则仅仅关注该非零条件
int con=atoi(portstr)unsigned char Port_file_name[30]
int fd0,rc
struct termios ts0
switch (con)
{ //选项O_NOCTTY 表示不能把本串口当成控制终端,否则用户的键盘输入信息将影响程序的执行
//O_NDELAY表示打开串口的时候,程序并不关心另一端的串口是否在使用中
case 1: fd0=open("/dev/ttyM0",O_RDWR | O_NOCTTY | O_NDELAY)break
case 2: fd0=open("/dev/ttyM1",O_RDWR | O_NOCTTY | O_NDELAY)break
case 3: fd0=open("/dev/ttyM2",O_RDWR | O_NOCTTY | O_NDELAY)break
case 4: fd0=open("/dev/ttyM3",O_RDWR | O_NOCTTY | O_NDELAY)break
case 5: fd0=open("/dev/ttyM4",O_RDWR | O_NOCTTY | O_NDELAY)break
case 6: fd0=open("/dev/ttyM5",O_RDWR | O_NOCTTY | O_NDELAY)break
case 7: fd0=open("/dev/ttyM6",O_RDWR | O_NOCTTY | O_NDELAY)break
case 8: fd0=open("/dev/ttyM7",O_RDWR | O_NOCTTY | O_NDELAY)break
default : fd0=open("/dev/ttyM0",O_RDWR | O_NOCTTY | O_NDELAY)break
}
tcgetattr(fd0,&ts0)
bzero(&ts0,sizeof(struct termios))
switch (gytype)
{
case 1:{ts0.c_cflag |= B300 | CS7 | CLOCAL | CREAD | PARENB
ts0.c_cflag &= ~PARODD// 转换为偶效验
ts0.c_iflag |= INPCK// Disnable parity checking
break}
case 2:{ts0.c_cflag |= B1200 | CS8 | CLOCAL | CREAD | PARENB
ts0.c_cflag &= ~PARODD// 转换为偶效验
ts0.c_iflag |= INPCK// Disnable parity checking
break
}
case 3:{
ts0.c_cflag |= B9600 | CS8 | CLOCAL | CREAD
ts0.c_cflag &= ~PARENB// Clear parity enable
ts0.c_iflag &= ~INPCK// Enable parity checking
break
}
case 4:{ts0.c_cflag |= B9600 | CS8 | CLOCAL | CREAD | PARENB
ts0.c_cflag &= ~PARODD// 转换为偶效验
ts0.c_iflag |= INPCK// Disnable parity checking
break
}
}
ts0.c_lflag &= ~ECHO
ts0.c_lflag &= ~ECHONL
ts0.c_iflag &= ~IXOFF
ts0.c_iflag &= ~IXON
ts0.c_cflag &= ~CSIZE
switch (gytype)
{
case 1:{ts0.c_cflag |= CS7 break}
case 2:{ts0.c_cflag |= CS8 break}
case 3:{ts0.c_cflag |= CS8 break}
case 4:{ts0.c_cflag |= CS8 break}
}
ts0.c_lflag &= ~ICANON//如果设置使能规范输入,否则使用原始数据(本文使用)
ts0.c_oflag &= ~ONLCR//如果设置将NL转换成CR-NL后输出
ts0.c_iflag &= ~INLCR//如果设置将接收到的NL(换行)转换成CR(回车)。
ts0.c_cc[VMIN] = 0//最少可读数据
ts0.c_cc[VTIME] = 0//等待数据时间(10秒的倍数)
ts0.c_cflag &= ~CSTOPB//如果设置则使用两个停止位 ,如果取消则使用一个停止位
ts0.c_iflag |= IGNBRK//如果设置则忽略接收到的break信号
ts0.c_lflag &= ~IEXTEN//如果设置则启用实现自定义的输入处理
ts0.c_lflag |= NOFLSH//如果设置则禁止产生SIGINT,SIGQUIT和SIGSUSP信号时刷新输入和输出队列
switch (gytype)
{
case 1:{rc = cfsetospeed(&ts0,B300)break}
case 2:{rc = cfsetospeed(&ts0,B1200)break}
case 3:{rc = cfsetospeed(&ts0,B9600)break}
case 4:{rc = cfsetospeed(&ts0,B9600)break}
}
rc = tcsetattr(fd0,TCSAFLUSH,&ts0)
return fd0
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)