Linux中的gps编程

#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数据的解析,可参考或芯片手册
http://www.cnblogs.com/csMapx/archive/2011/11/02/2232663.html
如果需要将该程序运行在Android上,可运用JNI,最终的效果图如下
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
GPS应用程序设计》源代码。本软件是专为《GPS应用程序设计》一书配套发行的。包括: 1、 data_log.c 数据采集程序 2、 rinexout.c RINEX数据格式写入子程序 3、 to_rinex.c 数据格式转换 4、 sav_pos.c 卫星位置计算程序 5、 sky_sav.c 卫星天空显示程序 6、 dop_calc.c 卫星星座DOP计算程序 7、 view_sav.c 历书预报卫星出现程序 8、 absl_pos.c 单点绝对定位程序 9、 ssgsoft.c -- 相对静态定位主程序 10、 controlf.c ? 读取输入文件子程序 11、 orbit.c -- 选择参考卫星子程序 12、 broad.c -- 读广播星历计算子程序 13、 igs.c -- 读 IGS 精密星历子程序 14、 singlep.c -- 近似位置计算子程序 15、 rinex.c -- 读 Rinex 数据、探测跳周、组成单差子程序 16、 eqdd_s.c -- 组成双差方程子程序 17、 normdd_s.c ? 组成法方差子程序 18、 ad_core.c -- 平差子程序19、 ambifix.c -- 模糊度固定子程序 20、 tranf.c -- 坐标变换子程序 21、 dgps_ppr. 相位平滑伪距改正数计算程序 22、 dgps_phr 准载波相位改正数计算程序 23 rtcmencd.c RTCM 电文编码程序 24 rtcmencd.c RTCM 电文译码程序 25、 net_dgn.c 测量格网设计程序 26 sur_ctr.c 动态测量控制程序 27、 replay.c 动态测量数据回放程序 28、 kin_tran.c 动态定位坐标转换程序 29、 rms.c 定位精度估计程序 30、 tide.c 潮位改正程序 31、 xybl_54.c 54坐标变换程序 32、 xyxy_loc.c 任意坐标系转换程序 33、 gga+gsv.c GGA和GSV数据模拟程序 34、 depth.c 水深数据模拟程序 35、 gg_pos.c GPS+GLONASS导航程序 36、 menu1.c DOS环境换页式菜单程序 37、 menu2.c DOS环境下拉式菜单程序 38、 menu3.c windows95环境下拉式多层界面菜单程序 39、 makedata.c 利用RINEX格式文件data.98n和data.98o形成的data.out文件,供计算单点定位用

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值