C语言编程实现GPS定位信息的接受和显示

前面主要是在PC上操作串口,接受GPS天线传来的原始数字,下面是编程在用户层对接受到的信息进行处理和解析,有了前面的编写GPRS收发短信的经历,这次编写C程序接受和显示程序接容易多了。当然也参考和学习了网上别人的程序;


以下是实现的具体代码:

/*********************************************************************************
 *      Copyright:  (C) 2014 liucehngdeng<1037398771@qq.com> 
 *                  All rights reserved.
 *
 *       Filename:  gps_test.c
 *    Description:  This file 
 *                 
 *        Version:  0.0.0(09/04/2014~)
 *         Author:  liu chengdeng <1037398771@qq.com>
 *      ChangeLog:  1, Release initial version on "09/04/2014 11:05:23 AM"
 *                 
 ********************************************************************************/
#include<stdio.h>  
#include<stdlib.h>  
#include<string.h>  
#include<sys/types.h>  
#include<sys/stat.h>  
#include<fcntl.h>  
#include<unistd.h>  
#include<termios.h>  
#include<string.h>  


#define BUF_SIZE 1024


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 open_dev(char *dev)
{
    int fd = open( dev, O_RDWR| O_NDELAY );         //| O_NOCTTY | O_NDELAY   
    if (-1 == fd)
    {
        perror("Can't Open Serial Port !");
        return -1;
    }
    else
 
    return fd;
}


int init_serial(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);  
        cfsetospeed(&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;  
    }  
    
    return 0;  
}  


char * get_gprmc (char * buf)
{
    char *buff=buf;
    char *target="$GPRMC";
    char *p=NULL;
                
    if((p=strstr(buff,target))==NULL)
    {
        printf("No fonud the string GPRMC\n");
        return 0;
    }


    return p;
}


char * get_gpgga (char * buf)
{
    char *buff=buf;
    char *target="$GPGGA";
    char *p=NULL;
                
    if((p=strstr(buff,target))==NULL)
    {
        printf("No fonud the string GPGGA\n");
        return 0;
    }


    return p;
}


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;
}


static double get_double_number(char *s)
{
    char buf[BUF_SIZE];
    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;        //鍖椾含鏃堕棿璺烾TC鏃堕棿鐩搁殧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){          //涓婅堪鍑犱釜鏈堜唤鏄?0澶╂瘡鏈堬紝2鏈堜唤杩樹笉瓒?0  
                    GPS->day=1;  
                    GPS->month++;  
                }  
            }  
            else{  
                if(GPS->day>31){          //鍓╀笅鐨勫嚑涓湀浠介兘鏄?1澶╂瘡鏈? 
                    GPS->day=1;  
                    GPS->month++;  
                }  
            }  
            if(GPS->year % 4 == 0 ){ 
                if(GPS->day > 29 && GPS->month ==2){       //闂板勾鐨勪簩鏈堟槸29澶? 
                    GPS->day=1;  
                    GPS->month++;  
                }  
            }  
            else{  
                if(GPS->day>28 &&GPS->month ==2){      //鍏朵粬鐨勪簩鏈堟槸28澶╂瘡鏈? 
                    GPS->day=1;  
                    GPS->month++;  
                }  
            }  
            if(GPS->month>12){  
                GPS->month-=12;  
                GPS->year++;  
            }         
        }  



/*姝ゅ嚱鏁颁紶鍏ヤ袱涓瓧绗︿覆$GPRMC 锛?GPGGA鐨勯鍦板潃*/
void gps_parse(char *line1,char *line2,GPS_INFO *GPS)  
{  
    int i,tmp,start,end;  
    char* buf=line1;  
    char* buff=line2;  


    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)];     //鐘舵€? 
    GPS->latitude =get_double_number(&buf[getcomma(3,buf)])/100; //绾害  
    GPS->NS       =buf[getcomma(4,buf)];             //鍗楀寳绾? 
    GPS->longitude=get_double_number(&buf[getcomma(5,buf)])/100; //缁忓害  
    GPS->EW       =buf[getcomma(6,buf)];             //涓滆タ缁? 
    
    UTC2BTC(&GPS->D);                        //杞寳浜椂闂? 
 
    GPS->high     = get_double_number(&buff[getcomma(9,buff)]);   



void show_gps(GPS_INFO *GPS)  
{   
    printf("\n");
    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 : %4.4f %c\n",GPS->latitude,GPS->NS);     
    printf("Longitude: %4.4f %c\n",GPS->longitude,GPS->EW);    
    printf("high     : %4.4f \n",GPS->high);      
    printf("STATUS   : %c\n",GPS->status);     
}  


int main(void)  
{  
    int  fd,nset1,nread;  
    char buf[BUF_SIZE];  
    char *buff_gprmc,*buff_gpgga;  
    GPS_INFO GPS;
    
    fd = open_dev("/dev/ttyS1");//鎵撳紑涓插彛  
     
    nset1 = init_serial(fd,4800, 8, 'N', 1);//璁剧疆涓插彛灞炴€? 
    if (nset1 == -1)  
        exit(1);  
  
    while(1)  
    {   
        sleep(2);   

memset(buf,0,BUF_SIZE);   
        nread = read(fd, buf, BUF_SIZE);//璇讳覆鍙? 
        if (nread > 0)
        {  
            printf("\nGPS DATALen=%d\n",nread);   
            buf[nread] = '\0';  
            printf( "GPS information as follow:\n\n%s\n", buf); //杈撳嚭鎵€璇绘暟鎹? 
        }  
       
        buff_gprmc=get_gprmc(buf);
        buff_gpgga=get_gpgga(buf);


        gps_parse(buff_gprmc,buff_gpgga,&GPS);
        show_gps(&GPS) ;
    }  


    close(fd);  
    return 0;  
}  

下面是在开发板上运行的结果:

[root@root /]# ./gps_info_test 


GPS DATALen=598
GPS information as follow:


$GPGGA,043402.000,3029.6468,N,11423.6176,E,1,09,1.2,88.9,M,-13.7,M,,0000*41
$GPGSA,A,3,30,07,08,04,01,06,17,11,28,,,,2.2,1.2,1.8*3B
$GPRMC,043402.000,A,3029.6468,N,11423.6176,E,0.08,134.87,060914,,,A*63
$GPGGA,043403.000,3029.6468,N,11423.6176,E,1,09,1.2,89.0,M,-13.7,M,,0000*48
$GPGSA,A,3,30,07,08,04,01,06,17,11,28,,,,2.2,1.2,1.8*3B
$GPGSV,3,1,12,04,87,286,29,28,66,339,23,01,55,039,26,30,41,216,46*78
$GPGSV,3,2,12,17,39,298,22,20,38,126,29,11,34,046,30,32,25,076,16*75
$GPGSV,3,3,12,07,20,187,37,08,18,180,40,06,14,224,38,19,03,074,*7D
$GPRMC,043403.000,A,3029.6468,N,11423.6176,E,0.15,


DATE     : 2014-09-06 
TIME     : 12:34:03 
Latitude : 30.2965 N
Longitude: 114.2362 E
high     : 88.9000 
STATUS   : A


GPS DATALen=434
GPS information as follow:


135.18,060914,,,A*69
$GPGGA,043404.000,3029.6468,N,11423.6176,E,1,09,1.2,89.1,M,-13.7,M,,0000*4E
$GPGSA,A,3,30,07,08,04,01,06,17,11,28,,,,2.2,1.2,1.8*3B
$GPRMC,043404.000,A,3029.6468,N,11423.6176,E,0.16,149.00,060914,,,A*6F
$GPGGA,043405.000,3029.6468,N,11423.6175,E,1,09,1.2,89.3,M,-13.7,M,,0000*4E
$GPGSA,A,3,30,07,08,04,01,06,17,11,28,,,,2.2,1.2,1.8*3B
$GPRMC,043405.000,A,3029.6468,N,11423.6175,E,0.05,113.40,060914,,,A*64




DATE     : 2014-09-06 
TIME     : 12:34:05 
Latitude : 30.2965 N
Longitude: 114.2362 E
high     : 89.1000 
STATUS   : A


GPS DATALen=412
GPS information as follow:


$GPGGA,043406.000,3029.6468,N,11423.6175,E,1,09,1.2,89.3,M,-13.7,M,,0000*4D
$GPGSA,A,3,30,07,08,04,01,06,17,11,28,,,,2.2,1.2,1.8*3B
$GPRMC,043406.000,A,3029.6468,N,11423.6175,E,0.06,154.67,060914,,,A*62
$GPGGA,043407.000,3029.6467,N,11423.6175,E,1,09,1.2,89.5,M,-13.7,M,,0000*45
$GPGSA,A,3,30,07,08,04,01,06,17,11,28,,,,2.2,1.2,1.8*3B
$GPRMC,043407.000,A,3029.6467,N,11423.6175,E,0.12,137.48,060914,,,A*61




DATE     : 2014-09-06 
TIME     : 12:34:07 
Latitude : 30.2965 N
Longitude: 114.2362 E
high     : 89.3000 
STATUS   : A



  • 7
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值