您的位置:首页 > 运维架构 > Linux

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技术,最终的效果图如下

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: