zoukankan      html  css  js  c++  java
  • GPS数据解析程序

    GPS是英文Global Positioning System(全球定位系统)的简称
    卫星定位的原理:
    通过卫星发送数据可以计算出接收机与卫星的距离,只要有三颗以上的卫星距离就可以通过空间圆交汇的方法确定出此时接收机所在的空间点坐标,也就是地球上的经纬度了。
    GPS接收机的作用:
    接收解析它收到的卫星电报,然后再将这些数据组织成一定协议格式的数据按需求输出。
     
    一,GPS数据包解析:
     GPRMC 最小定位信息
    数据详解:
    $GPRMC,080655.00,A,4546.40891,N,12639.65641,E,1.045,328.42,170809,,,A*60
    $GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh
    <1> UTC 时间,hhmmss(时分秒)格式
    <2> 定位状态,A=有效定位,V=无效定位
    <3>纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
    <4> 纬度半球N(北半球)或S(南半球)
    <5>经度dddmm.mmmm(度分)格式(前面的0也将被传输)
    <6> 经度半球E(东经)或W(西经)
    <7>地面速率(000.0~999.9节,前面的0也将被传输)
    <8>地面航向(000.0~359.9度,以真北为参考基准,前面的0也将被传输)
    <9> UTC 日期,ddmmyy(日月年)格式
    <10>磁偏角(000.0~180.0度,前面的0也将被传输)
    <11> 磁偏角方向,E(东)或W(西)
    <12>模式指示(仅NMEA01833.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
     
    二,串口编程
    串口编程的流程
     
     
     
    测试程序如下(gps_main.c gps_main.h initSerialDev.c):
    gps_main.c如下:
    #include    "gps_main.h"
    
    int gps_analysize (char *gps_buff, GPRMC *gprmc);
    
    #define    GPS_LEN  512    /*  */
    
    int main (int argc, char **argv)
    {
        int fd = 0;
        char gps_buff [GPS_LEN];
        GPRMC gprmc;
    
        printf("gps_buff LENGTH:%d,%d
    ", sizeof(gps_buff), strlen(gps_buff));
        fd = open("/dev/ttyS1", O_RDWR|O_NOCTTY|O_NDELAY);
        if(fd < 0)
        {
            printf("Open /dev/ttyS1 error!");
            return 0;
        }
    
        initSerialDev(fd, 4800, 8, 'N', 1);
    
        while(1)
        {
            int nread = 0;
            
            sleep(3);
            nread = read(fd, gps_buff, sizeof(gps_buff));
        
            printf("gps_buff LENGTH:%d,%d
    ", sizeof(gps_buff), strlen(gps_buff));
    
            memset(&gprmc, 0, sizeof(gprmc));
            gps_analysize(gps_buff, &gprmc);
    
            printf("------------ GPS ANALYSIZE DATA --------------
    ");
            printf("GPS状态位: %c [A:有效定位  V:无效定位]
    ", gprmc.pos_state);
            printf ("GPS模式位: %c [A:自主定位  D:差分 E:估算 N:数据无效
    ", gprmc.mode);
            printf ("日期:  20%02d-%02d-%02d 
    ", gprmc.date%100, gprmc.date/100%100, gprmc.date/10000);
            printf ("时间: %02d:%02d:%02d 
    ",(int)(gprmc.time)/10000 + 8, (int)(gprmc.time)/100%100, (int)(gprmc.time)%100);
            printf ("纬度:  %c:%.3f 
    ", gprmc.a, gprmc.latitude/100);
            printf ("经度:  %c:%.3f 
    ", gprmc.b, gprmc.longitude/100);
            printf ("速度:  %.3f 
    ", gprmc.speed);
    
        }
    
        close(fd);
        return 0;
    } /* ----- End of main() ----- */
    
    
    /**************************************************************************************
     *  Description:
     *   Input Args:
     *  Output Args:
     * Return Value:
     *************************************************************************************/
    int gps_analysize (char *gps_buff, GPRMC *gprmc)
    {
        char *ptr = NULL;
    
        if(NULL == gprmc)
        {
            printf("parament gprmc error");
            return -1;
        }
        if((strlen(gps_buff)) < 10)
        {
            
            printf ("gps_buff error
    ");
        }
    
        if(NULL == (ptr = strstr(gps_buff, "$GPRMC")))
        {
            printf ("cannot find "$GPRMC".
    ");
            return -1;
        }
    
        sscanf (ptr, "$GPRMC,%f,%c,%f,%c,%f,%c,%f,%f,%d,,,%c", 
                &(gprmc->time),&(gprmc->pos_state),&(gprmc->latitude),&(gprmc->a),&(gprmc->longitude),&(gprmc->b),&(gprmc->speed),&(gprmc->direction),&(gprmc->date),&(gprmc->mode));
    
    
    
        return 0;
    } /* ----- End of gps_analysize()  ----- */

    gps_main.h如下:

    #ifndef  __GPS_MAIN_H__
    #define  __GPS_MAIN_H__
    
    
    #include    <stdio.h>
    #include    <string.h>
    #include    <stdlib.h>
    #include    <termios.h>
    #include    <sys/types.h>
    #include    <sys/stat.h>
    #include    <fcntl.h>
    #include    <unistd.h>
    
    
    #define    GPS_LEN 512            /* Length of GPS buffer   */
    
    typedef unsigned int UINT;    //add by skyyang
    typedef int BYTE;             //add by skyyang 
    typedef long int WORD;        //add by skyyang
    
    typedef struct __gprmc__
    {
        float time;                  //时间
        char pos_state;             //定位状态
        float latitude;             //纬度
        char a;             //南北半球
        char b;             //东经或西经
        float longitude;            //经度
        float speed;                //移动速度
        float direction;            //方向
        UINT date;                  //日期
        float declination;          //磁偏角
        char dd;                    //磁偏角方向
        char mode;
    }GPRMC;
    
    int initSerialDev(int fd,int nSpeed, int nBits, char nEvent, int nStop);
    #endif   /* ----- #ifndef __gps_main_h_INC  ----- */

    initSerialDev.c如下:

    #include "gps_main.h"
    
    int initSerialDev(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;
            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] = 0;
        tcflush(fd,TCIFLUSH);
    
        if((tcsetattr(fd,TCSANOW,&newtio))!=0)
        {
            perror("com set error");
            return -1;
        }   
        return 0;
    }
    
    int open_com(char *device_name)
    {
        int fd = 0;
    
        if (0 > (fd = open(device_name, O_RDWR|O_NOCTTY|O_NDELAY))) //要设置非阻塞模式打开设备否则会出错!
        {
            perror("Open Comport Fail:");
            return 0;
        }
    
        return fd;
    }/*  ----- End of open_com()  ----- */

    makefile如下:

    CC=/opt/buildroot-2011.11/arm920t/usr/bin/arm-linux-gcc
    BIN_NAME=gpstest
    #CFLAGS+=-g
    CFLAGS+=-Wall 
    CFLAGS+=-Werror
    
    
    all:
        ${CC} ${CFLAGS} *.c  -o ${BIN_NAME} 
    
    install:
        cp ${BIN_NAME} /tftp
    
    clean:
        @rm -f *.o
        @rm -f gpstest gps_test testgps 
    void bzero(void *s, int n); //置字节字符串s的前n个字节为零且包括‘’,推荐使用memset替代bzero,<string.h>
     
    错误:
    <1>这里我用的gcc编译的
    ./gpstest
    ./gpstest: line 1: syntax error: illegal eof marker for << redirection
  • 相关阅读:
    Array数组的使用
    map集合中取出分类优先级最高的类别名称
    关键字static介绍
    构造方法
    封装和private,this,super关键字的简单应用
    hitTest:withEvent:方法流程
    Events and Responder Chain
    block没那么难(一):block的实现
    [译] Block 小测验
    OAuth流程
  • 原文地址:https://www.cnblogs.com/zhoutian220/p/3986586.html
Copyright © 2011-2022 走看看