• 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
  • 相关阅读:
    关于Class.forName(“com.mysql.jdbc.Driver”)
    Vector既然继承了AbstractList为啥还要实现List接口
    推荐两个支持Java的云主机空间
    关于“Return empty arrays or collections, not nulls”的思考
    "win7回收站已损坏"解决方法
    ibatis中使用like模糊查询
    当你升级到ubuntu12.04之后
    转一篇:如何快速的修改参考文献
    Java Annotations初探
    用eclipse开发android,xmllayout文件不自动提示,Java代码可以自动提示
  • 原文地址:https://www.cnblogs.com/zhoutian220/p/3986586.html
Copyright © 2020-2023  润新知