#include<st
dio.h> /*标准输入
输出定义*/ #include<stdlib.h> /*标准
函数库定义*/ #include<unistd.h> /*Unix 标准
函数定义*/ #include<sys/types.h> #include<sys/stat.h> #include<fcntl.h> /*
文件控制定义*/ #include<termios.h> /*PPSIX 终端控制定义*/ #include<errno.h> /*
错误号定义*/ #include<string.h> #include<math.h> #include <sys/time.h> #include <time.h> #define SERIAL_PORT "/dev/ttyUSB0" //串口地址 // 测试时使用的
文件 #define SRC_FILE_NAME (const char *)"GPS.txt" //
文件头预留64个字节 #define FILE_HEADER_LEN 64 #define uchar unsigned char #define uint unsigned int // timer int gettimeofday(struct timeval *tv,struct timezone *tz); typedef struct{ int year; int month; int day; int hour; int minute; int second; }DATE_TIME; typedef struct{ double latitude; //经度 double longitude; //纬度 int latitude_Degree; //度 int latitude_Cent; //分 int latitude_Second; //秒 int longitude_Degree; //度 int longitude_Cent; //分 int longitude_Second; //秒 float speed; //速度 float direction; //航向 float height_ground; //水平面高度 float height_sea; //海拔高度 uchar NS; uchar EW; DATE_TIME D; uchar status; //接收状态 int GPS_Num; //使用卫星个数 }GPS_INFO; GPS_INFO gps_info;//存储GPS信息变量 static uchar GetComma(uchar num,char* str); static double Get_Double_Number(char *s); static float Get_Float_Number(char *s); static void UTC2BTC(DATE_TIME *GPS); int GPS_RMC_Parse(char *line,GPS_INFO *GPS); int GPS_GGA_Parse(char *line,GPS_INFO *GPS); void Int_To_Str(int x,char *Str); /*============================================================================== 函 数 名 : GetFile 功 能 :
获取文件句柄 算法实现 : 无 参 数 : [in] const char *pFileName -
文件名 返 回 值 : 成功-得到的
文件句柄,失败-NULL 日 期 : 2011/02/11 作 者 : jernymy ==============================================================================*/ static FILE *GetFile(const char *pFileName) { // 使用rt+的方式打开
文件 FILE *fpSrc = fopen(pFileName,"rt+"); if (NULL != fpSrc) { //
文件存在 return fpSrc; } printf("open %s \"rt\" fail,may be create first!/n",pFileName); // 创建
文件 fpSrc = fopen(pFileName,"wt"); if (NULL != fpSrc) { //
文件创建成功 printf("create %s \"wt\" succ,pointer:%p!/n",pFileName,fpSrc); } else { //
文件创建失败 printf("create %s \"wt\" fail,fpSrc); } return fpSrc; } /*============================================================================== 函 数 名 : WriteFile 功 能 : 写
文件操作 算法实现 : 无 参 数 : [in] const char *pFileName -
文件名 [in] const char *pchStr - 写入的字符串buffer 返 回 值 : 成功-0,失败--1 日 期 : 2011/02/11 作 者 : jernymy ==============================================================================*/ static int WriteFile(const char *pFileName,const char *pchStr) { FILE *fpSrc = NULL; int nFileLen; if (NULL == pFileName) { printf("pFileName is NULL,exit!/n"); return -1; } if (NULL == pchStr) { printf("pchStr is NULL,exit!/n"); return -1; } fpSrc = GetFile(pFileName); if (NULL == fpSrc) { printf("get file fail! exit/n"); return -1; } // 得到
文件大小-
文件长度 fseek(fpSrc,0L,SEEK_END); nFileLen = ftell(fpSrc); // 写
文件头后面部分 if (0 == nFileLen) { nFileLen = FILE_HEADER_LEN; } fseek(fpSrc,nFileLen,SEEK_SET); if (FILE_HEADER_LEN == nFileLen) { fprintf(fpSrc,"\n");//用于写
文件头部分 } fprintf(fpSrc,"%s\n",pchStr); // 写
文件头部分 fseek(fpSrc,SEEK_END); nFileLen = ftell(fpSrc); fseek(fpSrc,SEEK_SET); fprintf(fpSrc,"#FavorGPS#File size:%09d",nFileLen); //
关闭文件 if (NULL != fpSrc) { fclose(fpSrc); fpSrc = NULL; } return 0; } void show_gps(GPS_INFO *GPS) { printf("STATUS : %c\n",GPS->status); printf("DATE : %4d-%02d-%02d \n",GPS->D.year,GPS->D.month,GPS->D.day); printf("TIME : %02d:%02d:%02d \n",GPS->D.hour,GPS->D.minute,GPS->D.second); printf("Latitude : %10.8f %c\n",GPS->latitude,GPS->NS); printf("Longitude: %10.8f %c\n",GPS->longitude,GPS->EW); printf("high : %10.4f \n",GPS->height_sea); printf("Speed : %10.4f Km/h\n",GPS->speed); printf("GPS_Num : %2d\n",GPS->GPS_Num); // if(GPS->status=='A') { // char pchStr[1024]; // sprintf(pchStr,"%4d-%02d-%02d %02d:%02d:%02d|%10.8f %c|%10.8f %c|%10.4f",GPS->D.day,GPS->D.second,GPS->NS,GPS->EW,GPS->height_sea); // WriteFile(SRC_FILE_NAME,pchStr); //写GPS信息到
文件 } } //====================================================================// // 语法格式:int GPS_RMC_Parse(char *line,GPS_INFO *GPS) // 实现
功能:把gps模块的GPRMC信息解析为可识别的数据 // 参 数:存放原始信息字符数组、存储可识别数据的结构体 // 返 回 值: // 1: 解析GPRMC完毕 // 0: 没有进行解析,或数据无效 //====================================================================// int GPS_RMC_Parse(char *line,GPS_INFO *GPS) { uchar ch,status,tmp; float lati_cent_tmp,lati_second_tmp; float long_cent_tmp,long_second_tmp; float speed_tmp; char *buf = line; ch = buf[5]; status = buf[GetComma(2,buf)]; GPS->status =status; if (ch == 'C') //如果第五个字符是C,($GPRMC) { if (status == 'A') //如果数据有效,则分析 { GPS -> NS = buf[GetComma(4,buf)]; GPS -> EW = buf[GetComma(6,buf)]; GPS->latitude = Get_Double_Number(&buf[GetComma(3,buf)])*0.01; GPS->longitude = Get_Double_Number(&buf[GetComma( 5,buf)])*0.01; GPS->latitude_Degree = (int)GPS->latitude / 100; //分离纬度 lati_cent_tmp = (GPS->latitude - GPS->latitude_Degree * 100); GPS->latitude_Cent = (int)lati_cent_tmp; lati_second_tmp = (lati_cent_tmp - GPS->latitude_Cent) * 60; GPS->latitude_Second = (int)lati_second_tmp; GPS->longitude_Degree = (int)GPS->longitude / 100; //分离经度 long_cent_tmp = (GPS->longitude - GPS->longitude_Degree * 100); GPS->longitude_Cent = (int)long_cent_tmp; long_second_tmp = (long_cent_tmp - GPS->longitude_Cent) * 60; GPS->longitude_Second = (int)long_second_tmp; speed_tmp = Get_Float_Number(&buf[GetComma(7,buf)]); //速度(单位:海里/时) GPS->speed = speed_tmp * 1.85; //1海里=1.85公里 GPS->direction = Get_Float_Number(&buf[GetComma(8,buf)]); //角度 GPS->D.hour = (buf[7] - '0') * 10 + (buf[8] - '0'); //时间 GPS->D.minute = (buf[9] - '0') * 10 + (buf[10] - '0'); GPS->D.second = (buf[11] - '0') * 10 + (buf[12] - '0'); tmp = GetComma(9,buf); GPS->D.day = (buf[tmp + 0] - '0') * 10 + (buf[tmp + 1] - '0'); //日期 GPS->D.month = (buf[tmp + 2] - '0') * 10 + (buf[tmp + 3] - '0'); GPS->D.year = (buf[tmp + 4] - '0') * 10 + (buf[tmp + 5] - '0')+2000; UTC2BTC(&GPS->D); return 1; } } return 0; } //====================================================================// // 语法格式:int GPS_GGA_Parse(char *line,GPS_INFO *GPS) // 实现
功能:把gps模块的GPGGA信息解析为可识别的数据 // 参 数:存放原始信息字符数组、存储可识别数据的结构体 // 返 回 值: // 1: 解析GPGGA完毕 // 0: 没有进行解析,或数据无效 //====================================================================// int GPS_GGA_Parse(char *line,status; char *buf = line; ch = buf[4]; status = buf[GetComma(2,buf)]; if (ch == 'G') //$GPGGA { if (status != ',') { GPS->height_sea = Get_Float_Number(&buf[GetComma(9,buf)]); GPS->height_ground = Get_Float_Number(&buf[GetComma(11,buf)]); GPS->GPS_Num=(int)Get_Double_Number(&buf[GetComma(7,buf)]); return 1; } } return 0; } //====================================================================// // 语法格式: static float Str_To_Float(char *buf) // 实现
功能: 把一个字符串转化成浮点数 // 参 数:字符串 // 返 回 值:转化后单精度值 //====================================================================// static float Str_To_Float(char *buf) { float rev = 0; float dat; int integer = 1; char *str = buf; int i; while(*str != '\0') { switch(*str) { case '0': dat = 0; break; case '1': dat = 1; break; case '2': dat = 2; break; case '3': dat = 3; break; case '4': dat = 4; break; case '5': dat = 5; break; case '6': dat = 6; break; case '7': dat = 7; break; case '8': dat = 8; break; case '9': dat = 9; break; case '.': dat = '.'; break; } if(dat == '.') { integer = 0; i = 1; str ++; continue; } if( integer == 1 ) { rev = rev * 10 + dat; } else { rev = rev + dat / (10 * i); i = i * 10 ; } str ++; } return rev; } //====================================================================// // 语法格式: static float Get_Float_Number(char *s) // 实现
功能: 把给定字符串第一个逗号之前的字符转化成单精度型 // 参 数:字符串 // 返 回 值:转化后单精度值 //====================================================================// static float Get_Float_Number(char *s) { char buf[10]; uchar i; float rev; i=GetComma(1,s); i = i - 1; strncpy(buf,s,i); buf[i] = 0; rev=Str_To_Float(buf); return rev; } //====================================================================// // 语法格式: static double Str_To_Double(char *buf) // 实现
功能: 把一个字符串转化成浮点数 // 参 数:字符串 // 返 回 值:转化后双精度值 //====================================================================// static double Str_To_Double(char *buf) { double rev = 0; double dat; int integer = 1; char *str = buf; int i; while(*str != '\0') { switch(*str) { case '0': dat = 0; break; case '1': dat = 1; break; case '2': dat = 2; break; case '3': dat = 3; break; case '4': dat = 4; break; case '5': dat = 5; break; case '6': dat = 6; break; case '7': dat = 7; break; case '8': dat = 8; break; case '9': dat = 9; break; case '.': dat = '.'; break; } if(dat == '.') { integer = 0; i = 1; str ++; continue; } if( integer == 1 ) { rev = rev * 10 + dat; } else { rev = rev + dat / (10 * i); i = i * 10 ; } str ++; } return rev; } //====================================================================// // 语法格式: static double Get_Double_Number(char *s) // 实现
功能:把给定字符串第一个逗号之前的字符转化成双精度型 // 参 数:字符串 // 返 回 值:转化后双精度值 //====================================================================// static double Get_Double_Number(char *s) { char buf[10]; uchar i; double rev; i=GetComma(1,i); buf[i] = 0; rev=Str_To_Double(buf); return rev; } //====================================================================// // 语法格式:static uchar GetComma(uchar num,char *str) // 实现
功能:计算字符串中各个逗号的位置 // 参 数:查找的逗号是第几个的个数,需要查找的字符串 // 返 回 值:0 //====================================================================// static uchar GetComma(uchar num,char *str) { uchar i,j = 0; int len=strlen(str); for(i = 0;i < len;i ++) { if(str[i] == ',') j++; if(j == num) return i + 1; } return 0; } //====================================================================// // 语法格式:void UTC2BTC(DATE_TIME *GPS) // 实现
功能:转化时间为北京时区的时间 // 参 数:存放时间的结构体 // 返 回 值:无 //====================================================================// static void UTC2BTC(DATE_TIME *GPS) { GPS->second ++; if(GPS->second > 59) { GPS->second = 0; GPS->minute ++; if(GPS->minute > 59) { GPS->minute = 0; GPS->hour ++; } } GPS->hour = GPS->hour + 8; if(GPS->hour > 23) { GPS->hour -= 24; GPS->day += 1; if(GPS->month == 2 || GPS->month == 4 || GPS->month == 6 || GPS->month == 9 || GPS->month == 11 ) { if(GPS->day > 30) { GPS->day = 1; GPS->month++; } } else { if(GPS->day > 31) { GPS->day = 1; GPS->month ++; } } if(GPS->year % 4 == 0 ) { if(GPS->day > 29 && GPS->month == 2) { GPS->day = 1; GPS->month ++; } } else { if(GPS->day > 28 &&GPS->month == 2) { GPS->day = 1; GPS->month ++; } } if(GPS->month > 12) { GPS->month -= 12; GPS->year ++; } } } //====================================================================// // 语法格式: Int_To_Str(int x,char *Str) // 实现
功能: 转化整型值为字符串形式 // 参数: x: 转化的整数 // Str:转化后的字符串 // 返回值: 无 //====================================================================// void Int_To_Str(int x,char *Str) { int t; char *Ptr,Buf[5]; int i = 0; Ptr = Str; if(x < 10) // 当整数小于10时,转化为"0x"的格式 { *Ptr ++ = '0'; *Ptr ++ = x+0x30; } else { while(x > 0) { t = x % 10; x = x / 10; Buf[i++] = t+0x30; // 通过计算把数字转化成ASCII码形式 } i -- ; for(;i >= 0;i --) // 将得到的字符串倒序 { *(Ptr++) = Buf[i]; } } *Ptr = '\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 ) { case 7: newtio.c_cflag |= CS7; break; case 8: 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 115200: cfsetispeed(&newtio,B115200); cfsetospeed(&newtio,B115200); break; case 460800: cfsetispeed(&newtio,B460800); cfsetospeed(&newtio,B460800); break; default: cfsetispeed(&newtio,B9600); 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] = 100;//返回的最小值 重要 tcflush(fd,TCIFLUSH); if((tcsetattr(fd,TCSANOW,&newtio))!=0) { perror("com set error"); return -1; } // printf("set done!\n\r"); return 0; } int main(void) { //timer struct timeval tv; struct tm *gmt,*area; int buff_num=0;//缓存中字符数为0 int fd1,nset1,nread; char buf[1024]; char buff[100],read_buf[1024]; char comName[30]; char comPath[80]="/dev/"; int index=0; /* printf("please input COM Name:"); scanf("%s",comName); fd1 = open(strcat(comPath,comName),O_RDWR);//打开串口 if (fd1 == -1){ printf("\r\n Open COM Port Falid! \r\n"); exit(1); } nset1 = set_opt(fd1,115200,8,'N',1);//设置串口
属性 if (nset1 == -1){ printf("\r\n Set COM Port Falid! \r\n"); exit(1); } */ int fd; struct termios opt; fd = open(SERIAL_PORT,O_RDWR | O_NOCTTY | O_NDELAY); //默认为阻塞读方式 if (fd == -1) { perror("open serial 0\n"); return 0; } tcgetattr(fd,&opt); cfsetispeed(&opt,B115200); if (tcsetattr(fd,&opt) != 0) { perror("tcsetattr error"); return 0; } opt.c_cflag &= ~CSIZE; opt.c_cflag |= CS8; opt.c_cflag &= ~CSTOPB; opt.c_cflag &= ~PARENB; opt.c_cflag &= ~INPCK; opt.c_cflag |= (CLOCAL | CREAD); opt.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); opt.c_oflag &= ~OPOST; opt.c_oflag &= ~(ONLCR | OCRNL); opt.c_iflag &= ~(ICRNL | INLCR); opt.c_iflag &= ~(IXON | IXOFF | IXANY); opt.c_cc[VTIME] = 0; opt.c_cc[VMIN] = 0; tcflush(fd,TCIOFLUSH); printf("configure complete\n"); if (tcsetattr(fd,&opt) != 0) { perror("serial error"); return 0; } printf("start send and receive data\n"); FILE *fpWrite=fopen("/home/ubuntu/data.txt","w+"); if(fpWrite==NULL) { return 0; } while(1) { nread = read(fd,read_buf,1024);//读串口 if (nread > 0){ printf( "GPS:\n %s\n",read_buf); //
输出所读数据 printf("\r\n++++++++++++++++++++++++++++++++++++++++++\r\n"); /* find "$GPGGA" from raw_buf */ char *wellhandled_stringGPGGA; if((wellhandled_stringGPGGA = strstr(read_buf,"$GPGGA"))!=NULL) { int i; for (i=0; i<strlen(wellhandled_stringGPGGA); i++) { if (wellhandled_stringGPGGA[i] == '\n') { wellhandled_stringGPGGA[i] = '\0'; //replace ‘\n’ with null } } printf("%s\n",wellhandled_stringGPGGA); //解析GPGGA GPS_GGA_Parse(wellhandled_stringGPGGA,&gps_info); } /* find "$GPRMC" from raw_buf */ char *wellhandled_stringGPRMC; if((wellhandled_stringGPRMC = strstr(read_buf,"$GPRMC"))!=NULL) { int i; for (i=0; i<strlen(wellhandled_stringGPRMC); i++) { if (wellhandled_stringGPRMC[i] == '\n') { wellhandled_stringGPRMC[i] = '\0'; //replace ‘\n’ with null } } printf("%s\n",wellhandled_stringGPRMC); //解析GPRMC GPS_RMC_Parse(wellhandled_stringGPRMC,&gps_info); } show_gps(&gps_info); char pchStr[1024]; // show time gettimeofday(&tv,0); area = localtime(&(tv.tv_sec));//以本地时区
显示时间 sprintf(pchStr,"time: %s %u:%u Latitude : %10.8f Longitude: %10.8f",asctime(area),tv.tv_sec,tv.tv_usec,gps_info.latitude,gps_info.longitude); // sprintf(pchStr,"Latitude : %10.8f Longitude: %10.8f",gps_info.longitude); WriteFile(SRC_FILE_NAME,pchStr); //写GPS信息到
文件 index++; printf("index=%d\r\n",index); printf("\r\n++++++++++++++++++++++++++++++++++++++++++\r\n"); } sleep(1);//睡眠,等待数据多一点 } close(fd); fclose(fpWrite); return 0; } //gcc -o gps gps.c -lm -lgps
原文链接:https://www.f2er.com/ubuntu/351754.html