Linux中的gps编程
2015-10-31 14:53
274 查看
#include <termios.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <fcntl.h> #include <sys/signal.h> #include <pthread.h> #include <string.h> #define BAUDRATE B9600 //gps波特率 #define COM "/dev/ttySAC3" //串口节点 #define FALSE 0 #define TRUE 1 pthread_t pthread_receive,pthread_show_gps_info; typedef struct{ int year; int month; int day; int hour; int minute; int second; }date_time; typedef struct{ date_time D; //时间 char status; //接收状态 double latitude; //纬度 double longitude; //经度 char NS; //南北极 char EW; //东西 double speed; //速度 double high; //高度 }GPS_INFO; int STOP=FALSE; int gpsfd; int GET_GPS_OK=FALSE; int gps_location_pass=FALSE; char GPS_BUF[1024]; int baud=BAUDRATE; GPS_INFO gps_info; //得到指定序号的逗号位置 // 从1开始算 return num后出现的第一个字符的位置x(0--x) static int GetComma(int num,char *str) { int 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; } //获取",,""之间的字符串并转换成doule类型 static double get_double_number(char *s) { char buf[128]; int i; double rev; i=GetComma(1,s); strncpy(buf,s,i); buf[i]=0; rev=atof(buf); return rev; } static void UTC2BTC(date_time *GPS) { //如果秒号先出,再出时间数据,则将时间数据+1秒 GPS->second++; //加一秒 if(GPS->second>59){ GPS->second=0; GPS->minute++; if(GPS->minute>59){ GPS->minute=0; 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++; } } } //show someting gps information static void show_gps(GPS_INFO *GPS) { printf("DATE : %ld-%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.4f %c\n",GPS->latitude,GPS->NS); printf("Longitude: %10.4f %c\n",GPS->longitude,GPS->EW); printf("high : %10.4f \n",GPS->high); printf("STATUS : %c\n",GPS->status); } //解析gps发出的数据 static void gps_parse(char *line,GPS_INFO *GPS) { int i,tmp,start,end; char c; char* buf=line; c=buf[5];//first ',' appear location if(c=='C')//"GPRMC" { 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;//日期 GPS->status=buf[GetComma(2,buf)]; if(GPS->status=='A')//vaild data gps_location_pass=TRUE; if(GPS->status=='V')//invalid data gps_location_pass=FALSE; GPS->latitude =get_double_number(&buf[GetComma(3,buf)]); //纬度 GPS->NS =buf[GetComma(4,buf)]; //南北 GPS->longitude=get_double_number(&buf[GetComma(5,buf)]); //经度 GPS->EW =buf[GetComma(6,buf)]; //东西 UTC2BTC(&GPS->D);//transform world time to beijing time } if(c=='A')//"$GPGGA" //高度 { GPS->high = get_double_number(&buf[GetComma(9,buf)]); } } static void* receive(void * data) { int i=0; char c; char buf[1024]; GPS_INFO GPS; printf("read modem\n"); while (STOP==FALSE) { read(gpsfd,&c,1); buf[i++] = c; if(c == '\n'){ strncpy(GPS_BUF,buf,i); i=0; GET_GPS_OK=TRUE; } if(STOP) break; } printf("exit from reading modem\n"); return NULL; } static 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); if(gps_location_pass==TRUE){ show_gps(&gps_info); } else printf("-----------------\n"); } usleep(100); if(STOP)break; } } static int uart_init(void) { struct termios newstdtio,newtio; gpsfd = open(COM, O_RDWR ); if (gpsfd <0) { perror(COM); exit(-1); } if(tcgetattr(gpsfd,&newstdtio)!= 0)/* get working stdtio */ { perror("SetupSerial 3"); return(FALSE); } newtio.c_cflag = baud | 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(gpsfd, TCIFLUSH);/* now clean the modem line and activate the settings for modem */ if(tcsetattr(gpsfd,TCSANOW,&newtio)!= 0)/*set attrib */ { perror("COM"); return (FALSE); } return 0; } int main(int argc,char** argv) { uart_init(); pthread_create(&pthread_receive, NULL, receive, 0); pthread_create(&pthread_show_gps_info, NULL, show_gps_info,0); while(!STOP) { usleep(100000); //0.1ms } close(gpsfd); exit(0); }
编译的时候使用
arm-linux-gcc gpc.o -o gps -static -lpthread
关于gps数据的解析,可参考或芯片手册
/article/7117630.html
如果需要将该程序运行在Android上,可运用JNI技术,最终的效果图如下
相关文章推荐
- centos7 vsftpd 虚拟用户 pam模块认证
- linux strace 命令学习网址
- CentOS6.5系统安装过程图解
- Mr. Process的一生-Linux内核的社会视角(1)-启动
- 第 四 十 四 天:虚 拟 化 简 介 - 创 建
- 虚拟机安装centos7网络问题
- linux查看线程cpu占用情况
- Linux系统网卡配置方法
- greenplum centos 安装
- linux下alias命令详解
- centos 7 编译 vim
- 在Android手机上安装linux系统
- Linux命令之netstat
- 库、系统调用、操作系统和硬件之间的关系, linux 课下总结
- Linux系统管理命令之权限管理
- linux
- Linux系统管理命令之用户组管理
- Linux内核协议栈-从BSD socket接口层到传输层1
- Linux系统管理命令之用户管理
- Linux打包压缩命令