READ()读串口的问题
READ()读串口的问题在RECIEVE()函数里始终读不到READ里的数据啊,快疯了,顺便说一下,我采集的串口数据是GPS模块采集回来的信息.各位大哥,拜托了!!!
#include <termios.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <pthread.h>
#include <stdlib.h>
#include <errno.h>
#include "gps.h"
#define BAUDRATE B4800
#define COM1 "/dev/ttyS0"
#define COM2 "/dev/ttyS1"
#define ENDMINITERM 27 /* ESC to quit miniterm */
#define FALSE 0
#define TRUE 1
volatile int STOP=FALSE;
volatile int fd;
GPS_INFO gps_info;
int GET_GPS_OK=FALSE;
char GPS_BUF[1024];
/*void child_handler(int s)
{
printf("stop!!!\n");
STOP=TRUE;
}*/
/*--------------------------------------------------------*/
void* show_gps_info(void * data)
{
while(1){
if(GET_GPS_OK){
GET_GPS_OK=FALSE;
printf("%s",GPS_BUF);
gps_parse(GPS_BUF,&gps_info);
show_gps(&gps_info);
}
usleep(100);
if(STOP)break;
}
}
/*--------------------------------------------------------*/
void* receive(void * data)
{
int i=0;
char c;
int ss=0;
char buf[1024];
GPS_INFO GPS;
printf("read modem\n");
while (STOP==FALSE)
{printf("read modem\n");
ss=read(fd,&c,1024); /* com port */
printf("%d/n",ss);
printf("read modem\n");
buf[i++] = c;
if(c == '\n'){
strncpy(GPS_BUF,buf,i);
i=0;
GET_GPS_OK=TRUE;
}
//if(STOP)break;
//write(1,&c,1); /* stdout */
}
printf("exit from reading modem\n");
return NULL;
}
/*--------------------------------------------------------*/
int main(int argc,char** argv)
{ int fd;
fd_set rd;
int i;
if((fd=open_port(fd,1))<0)
{
perror("open_port error");
return;
}
if((i=set_opt(fd,4800,8,'N',1))<0)
{
perror("set_opt error");
return;
}
/*struct termios oldtio,newtio,oldstdtio,newstdtio;
struct sigaction sa;
int ok;
void * retval;
fd = open(COM1, O_RDWR );
if (fd <0) {
perror(COM1);
exit(-1);
}
tcgetattr(0,&oldstdtio);
tcgetattr(fd,&oldtio); // save current modem settings
tcgetattr(fd,&newstdtio); // get working stdtio
newtio.c_cflag = BAUDRATE | CRTSCTS | CS8 | CLOCAL | CREAD;//ctrol flag
newtio.c_iflag = IGNPAR; //input flag
newtio.c_oflag = 0; //output flag
newtio.c_lflag = 0;
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
// now clean the modem line and activate the settings for modem
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);//set attrib
*/
while(1)
{
receive(0);
//show_gps_info(0);
//while(!STOP){
//usleep(100000);
//}
}
/*tcsetattr(fd,TCSANOW,&oldtio); // restore old modem setings
tcsetattr(0,TCSANOW,&oldstdtio); // restore old tty setings
close(fd);
exit(0);*/
}
/* 绔彛璁剧疆*/
int set_opt(int fd,int nspeed,int nbits,char nevent,int nstop)
{
struct termios newtio,oldtio;
if(tcgetattr(fd,&oldtio)!=0)
{
perror("setupserial 1");
return (-1);
}
bzero(&newtio,sizeof(newtio));
/*璁剧疆瀛楃澶у皬*/
newtio.c_cflag|=CLOCAL|CREAD;
newtio.c_cflag&=~CSIZE;
/*璁剧疆鏁版嵁浣?/
switch(nbits)
{
case7:
newtio.c_cflag|=CS7;
break;
case8:
newtio.c_cflag|=CS8;
break;
}
/*璁剧疆濂囧伓鏍¢獙浣?/
switch(nevent)
{
case 'O': //濂囨暟
newtio.c_cflag|=PARENB;
newtio.c_cflag|=PARODD;
newtio.c_iflag|=(INPCK|ISTRIP);
break;
case 'E': //鍋舵暟
newtio.c_iflag|=(INPCK|ISTRIP);
newtio.c_cflag|=PARENB;
newtio.c_cflag&=~PARODD;
break;
case 'N': //鏃犲鍋舵牎楠?
newtio.c_cflag&=~PARENB;
break;
}
/*璁剧疆娉㈢壒鐜?/
switch(nspeed)
{
case 2400:
cfsetispeed(&newtio,B2400);
cfsetospeed(&newtio,B2400);
break;
case 4800:
cfsetispeed(&newtio,B4800);
cfsetospeed(&newtio,B4800);
break;
case 9600:
cfsetispeed(&newtio,B9600);
cfsetospeed(&newtio,B9600);
break;
case 19200:
cfsetispeed(&newtio,B19200);
cfsetospeed(&newtio,B19200);
break;
case 115200:
cfsetispeed(&newtio,B115200);
cfsetospeed(&newtio,B115200);
break;
case 57600:
cfsetispeed(&newtio,B57600);
cfsetospeed(&newtio,B57600);
break;
default:
cfsetispeed(&newtio,B19200);
cfsetospeed(&newtio,B19200);
break;
}
/*璁剧疆鍋滄浣?/
if(nstop==1)
newtio.c_cflag&=~CSTOPB;
else if (nstop==2)
newtio.c_cflag|=CSTOPB;
/*璁剧疆绛夊緟鏃堕棿鍜屾渶灏忔帴鏀跺瓧绗?/
newtio.c_cc[VTIME]=0;
newtio.c_cc[VMIN]=0;
/*澶勭悊鏈帴鏀跺瓧绗?/
tcflush(fd,TCIFLUSH);
/*婵 你拷贝上来的这段代码是你真实的代码吗?还是一部分?我没有太明白具体的代码用意,有些还被注释上了。
大致看了一下,那个fd变量到底是全局的?还是局部的变量?你的那个read函数调用的时候,那个fd是多少?可以打印出来看看。
拜托了!
#include <termios.h>#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/signal.h>
#include <pthread.h>
#include <stdlib.h>
#include <errno.h>
#include "gps.h"
volatile int fd;
void* receive(void * data)
{
int i=0;
char c;
char buf[1024];
printf("read modem\n");
while (1)
{printf("%d\n",fd); //这里fd返回的是3,我就想先从串口读GPS模块采集来的数据,什么也没有啊
read(fd,&c,1); /* com port */
printf("read modem\n");
buf[i++] = c;
if(c == '\n') {
i=0;
printf("%s\n",buf);
tcflush(fd, TCIFLUSH);
}
}
}
int main(int argc,char** argv)
{
struct termios oldtio,newtio,oldstdtio,newstdtio;
struct sigaction sa;
int ok;
void * retval;
fd = open("/dev/ttyS0", O_RDWR );
if (fd <0) {
perror("/dev/ttyS0");
exit(-1);
}
printf("open uart1 is ok!\n");
tcgetattr(0,&oldstdtio);
tcgetattr(fd,&oldtio); // save current modem settings
tcgetattr(fd,&newstdtio); // get working stdtio
newtio.c_cflag = B4800 | CRTSCTS | CS8 | CLOCAL | CREAD;//ctrol flag
newtio.c_iflag = IGNPAR; //input flag
newtio.c_oflag = 0; //output flag
newtio.c_lflag = 0;
newtio.c_cc[VMIN]=1;
newtio.c_cc[VTIME]=0;
tcflush(fd, TCIFLUSH);
tcsetattr(fd,TCSANOW,&newtio);//set attrib
while(1)
{
receive(0);
}
/*tcsetattr(fd,TCSANOW,&oldtio); // restore old modem setings
tcsetattr(0,TCSANOW,&oldstdtio); // restore old tty setings
close(fd);
exit(0);*/
} read读不到数据就会堵塞,可以先用select查询一下状态,我看见网上有这样一段代码供你参考:
Linux下用select查询串口数据
Linux下直接用read读串口可能会造成堵塞,或数据读出错误。然而用select先查询com口,再用read去读就可以避免,并且当com口延时时,程序可以退出,这样就不至于由于com口堵塞,程序就死了。我的代码如下:
bool ReadDevice( int hComm, unsigned long uLen, char* pData )
{
int nread = 0;
char inbuf[uLen];
char buff[uLen];
memset( inbuff, '\0', uLen );
memset( buff, '\0', uLen );
fd_set readset;
struct timeval tv;
int MaxFd = 0;
int c = 0;
int z;
do
{
FD_ZERO( &readset );
if( hComm >= 0 )
FD_SET( hComm, &readset );
MaxFd = hComm + 1;
tv.tv_sec = 0;
tv.tv_usec = 500000;
do
{
z = select( MaxFd, &readset, 0, 0, &tv);
}while( z==-1 && errno==EINTR );
if( z == -1 )
printf("select(2)\n");
if( z == 0 )
{
hComm = -1;
}
if( hComm>=0 && FD_ISSET(hComm, &readset) )
{
z = read( hComm, buff, uLen - c );
c += z;
if( z == -1 )
{
hComm = -1;
}
if( z > 0 )
{
buff[ z + 1 ] = '\0';
strcat( inbuff, buff );
memset( buff, 0x00, uLen );
}
else
{
hComm = -1;
}
}
}while( hComm >= 0 );
memcpy( pData, inbuff, c );
return true;
}
页:
[1]