在imx6ull上,移远EC20模块的GPS信息获取和解析

1、接上模块通过USB连接,需要插上SIM卡,查看设备如下

root@ATK-IMX6U:~# ls /dev/ttyUSB*
/dev/ttyUSB0  /dev/ttyUSB1  /dev/ttyUSB2  /dev/ttyUSB3

2、使能GPS信息输出 

echo -e "AT+QGPS=1\n\r" > /dev/ttyUSB2

 通过命令查看信息

root@ATK-IMX6U:~#  cat /dev/ttyUSB1

没定位到的情况

$GPVTG,,T,,M,,N,,K,N*2C

$GPGSA,A,1,,,,,,,,,,,,,,,*1E

$GPGGA,,,,,,0,,,,,,,,*66

$GPRMC,,V,,,,,,,,,,N*53

定位到的情况

$GPGSV,6,1,21,10,75,334,26,12,35,087,45,18,14,185,28,23,62,132,43*7D

$GPGSV,6,2,21,24,21,042,26,25,41,129,44,31,23,230,34,32,41,313,43*76

$GPGSV,6,3,21,15,02,090,,21,01,319,,33,,,34,38,,,34*72

$GPGSV,6,4,21,39,,,34,40,,,34,41,,,41,42,,,34*77

$GPGSV,6,5,21,45,,,41,46,,,34,48,,,34,50,,,41*73

$GPGSV,6,6,21,51,,,35*78

$GPGGA,090652.00,2813.804270,N,11256.758714,E,1,07,0.9,127.6,M,-14.0,M,,*48

$GPVTG,0.0,T,3.0,M,0.0,N,0.0,K,A*20

$GPRMC,090652.00,A,2813.804270,N,11256.758714,E,0.0,0.0,230921,3.0,W,A*2F

$GPGSA,A,3,10,12,18,23,24,25,32,,,,,,1.2,0.9,0.8*3A

GPS信息解析

gps.c

//
// Created by ihz on 2020/6/4.
//
#include "gps.h"

// 数据分割,可以分割两个连续的分隔符
static char* strsplit(char** stringp, const char* delim)
{
    char* start = *stringp;
    char* p;

    p = (start != NULL) ? strpbrk(start, delim) : NULL;

    if (p == NULL)
    {
        *stringp = NULL;
    }
    else
    {
        *p = '\0';
        *stringp = p + 1;
    }

    return start;
}

// 统计字符串在另一个字符串中出现的次数
static int strstr_cnt(char *str, char *substr)
{
    char *srcStr = str;
    int count = 0;

    do
    {
        srcStr = strstr(srcStr, substr);
        if(srcStr != NULL)
        {
            count++;
            srcStr = srcStr + strlen(substr);
        }
        else
        {
            break;
        }
    }while (*srcStr != '\0');

    return count;
}

#if ENABLE_GGA
// GGA数据解析
static GGA gga_data_parse(char *gga_data)
{
    GGA gga;
    unsigned char times = 0;
    char *p;
    char *end;
    char *s = strdup(gga_data);

    p = strsplit(&s, ",");
    while (p)
    {
        switch (times)
        {
            case 1:   // UTC
                strcpy(gga.utc, p);
                break;
            case 2:   // lat
                gga.lat = strtod(p, NULL);
                break;
            case 3:   // lat dir
                gga.lat_dir = p[0];
                break;
            case 4:   // lon
                gga.lon = strtod(p, NULL);
                break;
            case 5:   // lon dir
                gga.lon_dir = p[0];
                break;
            case 6:   // quality
                gga.quality = (unsigned char)strtol(p, NULL, 10);
                break;
            case 7:   // sats
                gga.sats = (unsigned char)strtol(p, NULL, 10);
                break;
            case 8:   // hdop
                gga.hdop = (unsigned char)strtol(p, NULL, 10);
                break;
            case 9:   // alt
                gga.alt = strtof(p, NULL);
                break;
            case 11:  // undulation
                gga.undulation = strtof(p, NULL);
                break;
            case 13:  // age
                gga.age = (unsigned char)strtol(p, NULL, 10);
                break;
            case 14:  // stn_ID
                end = (char *)malloc(sizeof(p));
                strncpy(end, p, strlen(p)-3);
                end[strlen(p)-3] = '\0';
                gga.stn_ID = (unsigned short )strtol(end, NULL, 10);
                free(end);
                break;
            default:
                break;
        }
        p = strsplit(&s, ",");
        times++;
    }
    free(s);
    return gga;
}
#endif

#if ENABLE_GLL
// GLL数据解析
static GLL gll_data_parse(char *gll_data)
{
    GLL gll;
    unsigned char times = 0;
    char *p;
    char *s = strdup(gll_data);

    p = strsplit(&s, ",");
    while (p)
    {
        switch (times)
        {
            case 1:   // lat
                gll.lat = strtod(p, NULL);
                break;
            case 2:   // lat dir
                gll.lat_dir = p[0];
                break;
            case 3:   // lon
                gll.lon = strtod(p, NULL);
                break;
            case 4:   // lon dir
                gll.lon_dir = p[0];
                break;
            case 5:   // lon dir
                strcpy(gll.utc, p);
                break;
            case 6:  // data status
                gll.data_status = p[0];
                break;
            default:
                break;
        }
        p = strsplit(&s, ",");
        times++;
    }
    free(s);
    return gll;
}
#endif

#if ENABLE_GSA
// 得到GSA数据中的信道信息
static GSA_PRN *get_prn_data(char *gps_data)
{
    GSA_PRN *gsa_prn;
    unsigned char times = 0;
    unsigned char i;
    unsigned char sentences_index = 0;  // 累计找到gsa字段的个数
    char *p;
    char *s;
    char *sentences;
    int gsa_count;

    // 统计GSA字段的个数
    gsa_count = strstr_cnt(gps_data, PRE_GSA);

    gsa_prn = (GSA_PRN *)malloc(sizeof(GSA_PRN) * (gsa_count * 12 + 1));
    memset(gsa_prn, 0, sizeof(GSA_PRN) * (gsa_count * 12 + 1));
    sentences = strtok(gps_data, "\r\n");
    while (sentences)
    {
        if (strstr(sentences, PRE_GSA))
        {
            sentences_index++;
            s = strdup(sentences);
            p = strsplit(&s, ",");
            while (p)
            {
                if (times == 2)
                {
                    for (i=0; i<12; i++)
                    {
                        p = strsplit(&s, ",");
                        (gsa_prn+i+(sentences_index-1)*12)->total = (unsigned char)gsa_count * 12;
                        (gsa_prn+i+(sentences_index-1)*12)->prn_ID = i + (sentences_index - 1) * 12;
                        (gsa_prn+i+(sentences_index-1)*12)->prn = (unsigned char)strtol(p, NULL, 10);
                    }
                }
                p = strsplit(&s, ",");
                times++;
            }
            times = 0;
        }
        sentences = strtok(NULL, "\r\n");
    }
    free(s);
    return gsa_prn;
}

// GSA数据解析
static GSA gsa_data_parse(char *gsa_data, char *gpsdata)
{
    GSA gsa;
    unsigned char times = 0;
    char *p;
    char *end;
    char *s = strdup(gsa_data);
    char *alldata = strdup(gpsdata);

    p = strsplit(&s, ",");
    while (p)
    {
        switch (times)
        {
            case 1:   // mode_MA
                gsa.mode_MA = p[0];
                break;
            case 2:   // mode_123
                gsa.mode_123 = p[0];
                break;
            case 3:   // prn
                gsa.gsa_prn = get_prn_data(alldata);
                break;
            case 15:  // pdop
                gsa.pdop = strtod(p, NULL);
                break;
            case 16:  // hdop
                gsa.hdop = strtod(p, NULL);
                break;
            case 17:  // vdop
                end = (char *)malloc(sizeof(p));
                strncpy(end, p, strlen(p)-3);
                end[strlen(p)-3] = '\0';
                gsa.vdop = strtod(end, NULL);
                free(end);
            default:
                break;
        }
        p = strsplit(&s, ",");
        times++;
    }
    free(s);
    return gsa;
}
#endif

#if ENABLE_RMC
// RMC数据解析
static RMC rmc_data_parse(char *rmc_data)
{
    RMC rmc;
    unsigned char times = 0;
    char *p;
    char *s = strdup(rmc_data);

    p = strsplit(&s, ",");
    while (p)
    {
        switch (times)
        {
            case 1:   // UTC
                strcpy(rmc.utc, p);
                break;
            case 2:   // pos status
                rmc.pos_status = p[0];
                break;
            case 3:   // lat
                rmc.lat = strtod(p, NULL);
                break;
            case 4:   // lat dir
                rmc.lat_dir = p[0];
                break;
            case 5:   // lon
                rmc.lon = strtod(p, NULL);
                break;
            case 6:   // lon dir
                rmc.lon_dir = p[0];
                break;
            case 7:   // speen Kn
                rmc.speed_Kn = strtod(p, NULL);
                break;
            case 8:   // track true
                rmc.track_true = strtod(p, NULL);
                break;
            case 9:   // date
                strcpy(rmc.date, p);
                break;
            case 10:  // mag var
                rmc.mag_var = strtod(p, NULL);
                break;
            case 11:  // var dir
                rmc.var_dir = p[0];
                break;
            case 14:  // mode ind
                rmc.mode_ind = p[0];
                break;
            default:
                break;
        }
        p = strsplit(&s, ",");
        times++;
    }
    free(s);
    return rmc;
}
#endif

#if ENABLE_VTG
// VTG数据解析
static VTG vtg_data_parse(char *vtg_data)
{
    VTG vtg;
    unsigned char times = 0;
    char *p;
    char *s = strdup(vtg_data);

    p = strsplit(&s, ",");
    while (p)
    {
        switch (times)
        {
            case 1:   // track true
                vtg.track_true = strtod(p, NULL);
                break;
            case 3:   // track mag
                vtg.track_mag = strtod(p, NULL);
                break;
            case 5:   // speed Kn
                vtg.speed_Kn = strtod(p, NULL);
                break;
            case 7:   // speed Km
                vtg.speed_Km = strtod(p, NULL);
                break;
            default:
                break;
        }
        p = strsplit(&s, ",");
        times++;
    }
    free(s);
    return vtg;
}
#endif

#if ENABLE_GSV
/*
 * function:  获取GSV字段中的GPS信息
 * gps_data:  最原始的GPS字符串
 * stas:      卫星数量
 * prefix:    GSV信息字段前缀
*/
static SAT_INFO *get_sats_info(char *gps_data, unsigned char sats, char *prefix)
{
    SAT_INFO *sats_info;
    unsigned char times = 0;
    unsigned char msgs = 0;
    unsigned char msg = 0;
    unsigned char for_times;
    unsigned char i;
    char *p;
    char *s;
    char *sentences;

    sats_info = (SAT_INFO *)malloc(sizeof(SAT_INFO) * (sats+1));
    memset(sats_info, 0, sizeof(SAT_INFO) * (sats+1));
    sentences = strtok(gps_data, "\r\n");
    while (sentences)
    {
        if (strstr(sentences, prefix))
        {
            s = strdup(sentences);
            p = strsplit(&s, ",");
            while (p)
            {
                switch (times)
                {
                    case 1:   // msgs
                        msgs = (unsigned char) strtol(p, NULL, 10);
                        break;
                    case 2:   // msg
                        msg = (unsigned char) strtol(p, NULL, 10);
                        break;
                    case 3:   // sat info
                        for_times = (msgs == msg) ? ((sats % 4) ? sats % 4 : 4) : 4;
                        for (i = 0; i < for_times; i++)
                        {
                            p = strsplit(&s, ",");
                            (sats_info+(msg-1)*4+i)->prn = (unsigned char) strtol(p, NULL, 10);
                            p = strsplit(&s, ",");
                            (sats_info+(msg-1)*4+i)->elev = (unsigned char) strtol(p, NULL, 10);
                            p = strsplit(&s, ",");
                            (sats_info+(msg-1)*4+i)->azimuth = (unsigned short) strtol(p, NULL, 10);
                            p = strsplit(&s, ",");
                            (sats_info+(msg-1)*4+i)->SNR = (unsigned char) strtol(p, NULL, 10);
                        }
                        break;
                    default:
                        break;
                }
                p = strsplit(&s, ",");
                times++;
            }
            times = 0;
        }
        sentences = strtok(NULL, "\r\n");
    }
    free(s);
    return sats_info;
}

// GSV数据解析
static GSV gsv_data_parse(char *gsv_data, char *gps_data, char *prefix)
{
    GSV gsv;
    unsigned char times = 0;
    char *p;
    char *s = strdup(gsv_data);
    char *src_data = strdup(gps_data);

    p = strsplit(&s, ",");
    while (p)
    {
        switch (times)
        {
            case 1:   // msgs
                gsv.msgs = (unsigned char)strtol(p, NULL, 10);
                break;
            case 2:   // msg
                gsv.msg = (unsigned char)strtol(p, NULL, 10);
                break;
            case 3:   // sats
                gsv.sats = (unsigned char)strtol(p, NULL, 10);
                gsv.sat_info = get_sats_info(src_data, gsv.sats, prefix);
                break;
            default:
                break;
        }
        p = strsplit(&s, ",");
        times++;
    }
    free(s);
    return gsv;
}
#endif

#if ENABLE_UTC
// UTC数据解析
static UTC utc_parse(char *date, char *time)
{
    UTC utc_data;
    unsigned int date_int;
    double time_float;

    date_int = (unsigned int)strtol(date, NULL, 10);
    utc_data.DD = date_int / 10000;
    utc_data.MM = date_int % 10000 / 100;
    utc_data.YY = date_int % 100;
    time_float = strtod(time, NULL);
    utc_data.hh = (unsigned int)time_float / 10000;
    utc_data.mm = (unsigned int)time_float % 10000 / 100;
    utc_data.ss = (unsigned int)time_float % 100;
    utc_data.ds = (unsigned short)(time_float - (unsigned int)time_float);

    return utc_data;
}
#endif

// 解析全部的GPS数据
GPS gps_data_parse(char* gps_src)
{
    GPS gps_all;
    char *str_buffer = strdup(gps_src);

    // GGA数据解析
#if ENABLE_GGA
    GGA default_gga_data = {"\0",0.0,'N',0.0,'S',0,0,0,0,0,0,0};
    gps_src = strdup(str_buffer);
    gps_all.gga_data = strstr(gps_src, PRE_GGA) ? gga_data_parse(strtok(strstr(gps_src, PRE_GGA), "\r\n")) : default_gga_data;
#endif

    // GLL数据解析
#if ENABLE_GLL
    GLL default_gll_data = {0.0,'\0',0.0,'\0',"\0",'\0'};
    gps_src = strdup(str_buffer);
    gps_all.gll_data = strstr(gps_src, PRE_GLL) ? gll_data_parse(strtok(strstr(gps_src, PRE_GLL), "\r\n")) : default_gll_data;
#endif

    // GSA数据解析
#if ENABLE_GSA
    GSA_PRN default_gsa_prn_data = {0,0,0};
    GSA default_gsa_data = {'\0','\0',0.0,0.0,0.0,&default_gsa_prn_data};
    gps_src = strdup(str_buffer);
    gps_all.gsa_data = strstr(gps_src, PRE_GSA) ? gsa_data_parse(strtok(strstr(gps_src, PRE_GSA), "\r\n"), str_buffer) : default_gsa_data;
#endif

    // RMC数据解析
#if ENABLE_RMC
    RMC default_rmc_data = {"\0",'\0',0.0,'\0',0.0,'\0',0.0,0.0,"\0",0.0,'\0','\0'};
    gps_src = strdup(str_buffer);
    gps_all.rmc_data = strstr(gps_src, PRE_RMC) ? rmc_data_parse(strtok(strstr(gps_src, PRE_RMC), "\r\n")) : default_rmc_data;
#endif

    // VTG数据解析
#if ENABLE_VTG
    VTG default_vtg_data = {0.0,0.0,0.0,0.0};
    gps_src = strdup(str_buffer);
    gps_all.vtg_data = strstr(gps_src, PRE_VTG) ? vtg_data_parse(strtok(strstr(gps_src, PRE_VTG), "\r\n")) : default_vtg_data;
#endif

    // GSV数据解析
#if ENABLE_GSV
    SAT_INFO default_sat_info_data = {0,0,0,0};
    GSV default_gsv_data = {0,0,0,&default_sat_info_data};
    // GPGSV数据段解析
    gps_src = strdup(str_buffer);
    gps_all.gpgsv_data = strstr(gps_src, PRE_GPGSV) ? gsv_data_parse(strtok(strstr(gps_src, PRE_GPGSV), "\r\n"), str_buffer, PRE_GPGSV) : default_gsv_data;
    // GNGSV数据段解析
    gps_src = strdup(str_buffer);
    gps_all.gngsv_data = strstr(gps_src, PRE_GNGSV) ? gsv_data_parse(strtok(strstr(gps_src, PRE_GNGSV), "\r\n"), str_buffer, PRE_GNGSV) : default_gsv_data;
    // GLGSV数据段解析
    gps_src = strdup(str_buffer);
    gps_all.glgsv_data = strstr(gps_src, PRE_GLGSV) ? gsv_data_parse(strtok(strstr(gps_src, PRE_GLGSV), "\r\n"), str_buffer, PRE_GLGSV) : default_gsv_data;
#endif

    // UTC数据解析,UTC数据取自RMC段数据
#if ENABLE_UTC && ENABLE_RMC
    gps_all.utc = utc_parse(gps_all.rmc_data.date, gps_all.rmc_data.utc);
#endif

    free(str_buffer);
    free(gps_src);
    return gps_all;
}

gps.h

//
// Created by ihz on 2020/6/4.
//

#ifndef __GPS_H__
#define __GPS_H__

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// 根据实际的数据修改ID
#define PRE_GGA     "$GPGGA"
#define PRE_GLL     "$GNGLL"  //EC20 没有
#define PRE_GSA     "$GPGSA"
#define PRE_GPGSV   "$GPGSV"
#define PRE_GNGSV   "$GPGSV"
#define PRE_GLGSV   "$GLGSV"  //EC20 没有
#define PRE_RMC     "$GPRMC"
#define PRE_VTG     "$GPVTG"

// 语句解析控制 1:使能,0:禁用
#define ENABLE_GGA  0
#define ENABLE_GLL  0
#define ENABLE_GSA  0
#define ENABLE_GSV  0
#define ENABLE_RMC  1
#define ENABLE_VTG  0
#define ENABLE_UTC  0

#if ENABLE_GGA
// GGA字段结构体(GPS定位数据)
typedef struct
{
    char utc[11];                     // UTC时间,格式为hhmmss.sss
    double lat;                       // 纬度,格式为ddmm.mmmm
    char lat_dir;                     // 纬度半球,N或S
    double lon;                       // 经度,格式为dddmm.mmmm
    char lon_dir;                     // 经度半球,E或W
    unsigned char quality;            // 0=定位无效,1=定位有效
    unsigned char sats;               // 使用卫星数量,从00到12
    double hdop;                      // 水平精确度,0.5到99.9,单位m
    double alt;                       // 海平面的高度,-9999.9到9999.9米
    double undulation;                // 大地水准面高度,-9999.9到9999.9米
    unsigned char age;                // 差分时间
    unsigned short stn_ID;            // 差分站ID号0000 - 1023
} GGA;
#endif

#if ENABLE_GLL
// GPGLL数据结构体(地理定位信息)
typedef struct
{
    double lat;                       // 纬度,格式为ddmm.mmmm
    char lat_dir;                     // 纬度半球,N或S
    double lon;                       // 经度,格式为dddmm.mmmm
    char lon_dir;                     // 经度半球,E或W
    char utc[11];                     // UTC时间,格式为hhmmss.sss
    char data_status;                 // 状态标志位,A:有效,V无效
}GLL;
#endif

#if ENABLE_GSA
#pragma pack(1)                       // 便于指针偏移取值
// 信道信息结构体
typedef struct
{
    unsigned char total;              // 总信道个数
    unsigned char prn_ID;             // prn信道
    unsigned char prn;                // PRN 码(伪随机噪声码)
}GSA_PRN;
#pragma pack()

//GPGSA数据结构体(当前卫星信息)
typedef struct
{
    unsigned char mode_MA;            // 定位模式(选择2D/3D),A=自动选择,M=手动选择
    unsigned char mode_123;           // 定位类型,1=未定位,2=2D定位,3=3D定位
    double pdop;                      // PDOP综合位置精度因子(0.5 - 99.9)
    double hdop;                      // HDOP水平精度因子(0.5 - 99.9)
    double vdop;                      // VDOP垂直精度因子(0.5 - 99.9)
    GSA_PRN *gsa_prn;                 // 存放信道信息
}GSA;
#endif

#if ENABLE_GSV
#pragma pack(1)                       // 便于指针偏移取值
// 可见卫星信息结构体
typedef struct
{
    unsigned char prn;                // PRN 码(伪随机噪声码)
    unsigned char elev;               // 卫星仰角(00 - 90)度
    unsigned short azimuth;           // 卫星方位角(00 - 359)度
    unsigned char SNR;                // 信噪比
}SAT_INFO;
#pragma pack()

// GPGSV数据结构体(可见卫星信息)
typedef struct
{
    unsigned char msgs;               // 本次GSV语句的总数目(1 - 3)
    unsigned char msg;                // 本条GSV语句是本次GSV语句的第几条(1 - 3)
    unsigned char sats;               // 当前可见卫星总数(00 - 12)
    SAT_INFO *sat_info;               // 卫星信息
}GSV;
#endif

#if ENABLE_RMC
//RMC数据结构体(推荐定位信息数据格式)
typedef struct
{
    char utc[11];                     // UTC时间,hhmmss.sss格式
    unsigned char pos_status;         // 状态,A=定位,V=未定位
    double lat;                       // 纬度ddmm.mmmm,度分格式
    char lat_dir;                     // 纬度N(北纬)或S(南纬)
    double lon;                       // 经度dddmm.mmmm,度分格式
    char lon_dir;                     // 经度E(东经)或W(西经)
    double speed_Kn;                  // 速度
    double track_true;                // 方位角,度
    char date[7];                     // UTC日期,DDMMYY格式
    double mag_var;                   // 磁偏角,(000 - 180)度
    char var_dir;                     // 磁偏角方向,E=东W=西
    char mode_ind;                    // 模式,A=自动,D=差分,E=估测,N=数据无效(3.0协议内容)
}RMC;
#endif

#if ENABLE_VTG
//VTG数据结构体(地面速度信息)
typedef struct
{
    double track_true;                // 运动角度,000 - 359,真北参照系
    double track_mag;                 // 运动角度,000 - 359,磁北参照系
    double speed_Kn;                  // 水平运动速度(0.00),节,Knots
    double speed_Km;                  // 水平运动速度(0.00), 公里/时,km/h
}VTG;
#endif

#if ENABLE_UTC
//UTC时间结构体
typedef struct
{
    unsigned char YY;                 // 年
    unsigned char DD;                 // 日
    unsigned char MM;                 // 月
    unsigned char hh;                 // 时
    unsigned char mm;                 // 分
    unsigned char ss;                 // 秒
    unsigned short ds;                // 毫秒
}UTC;
#endif

//定义GPS结构体
typedef struct
{
#if ENABLE_GGA
    GGA gga_data;
#endif
#if ENABLE_GLL
    GLL gll_data;
#endif
#if ENABLE_GSA
    GSA gsa_data;
#endif
#if ENABLE_GSV
    GSV gpgsv_data;
    GSV gngsv_data;
    GSV glgsv_data;
#endif
#if ENABLE_RMC
    RMC rmc_data;
#endif
#if ENABLE_VTG
    VTG vtg_data;
#endif
#if ENABLE_UTC
    UTC utc;
#endif
}GPS;

GPS gps_data_parse(char* gps_src);

#endif //__GPS_H__

main.c

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include "gps.h"
#define GPS_LEN 1024

//#define ENABLE_RMC

int main()
{
    GPS gps;
    unsigned char i;
    // char gps_data[] = "$GNRMC,013300.00,A,2240.84105,N,11402.70763,E,0.007,,220319,,,D*69\r\n"
                        // "$GNVTG,,T,,M,0.007,N,0.014,K,D*3A\r\n"
                        // "$GNGGA,013300.00,2240.84105,N,11402.70763,E,2,12,0.59,70.5,M,-2.5,M,,0000*68\r\n"
                        // "$GNGSA,A,3,10,12,14,20,25,31,32,26,29,40,41,22,1.09,0.59,0.91*1F\r\n"
                        // "$GNGSA,A,3,74,70,73,80,69,,,,,,,,1.09,0.59,0.91*17\r\n"
                        // "$GPGSV,4,1,16,01,00,300,,10,56,178,51,12,12,038,38,14,47,345,48*79\r\n"
                        // "$GPGSV,4,2,16,16,00,207,,18,06,275,30,20,28,165,43,22,10,319,43*76\r\n"
                        // "$GPGSV,4,3,16,25,46,050,47,26,29,205,44,29,13,108,45,31,50,296,52*7E\r\n"
                        // "$GPGSV,4,4,16,32,56,010,52,40,20,257,40,41,46,237,48,42,46,123,42*77\r\n"
                        // "$GLGSV,2,1,06,69,27,136,49,70,76,057,50,71,34,338,50,73,64,276,55*6B\r\n"
                        // "$GLGSV,2,2,06,74,24,231,46,80,35,019,46*60\r\n"
                        // "$GNGLL,2240.84105,N,11402.70763,E,013300.00,A,D*7C\r\n";
    // gps = gps_data_parse(gps_data);


    int fd=0;
    int n=0;
    char buff[1024];
    char *dev_name="/dev/ttyUSB1";
 
    //if((fd=open(dev_name,O_RDWR|O_NOCTTY|O_NDELAY))<0)
	if((fd=open(dev_name,O_RDWR))<0)
    {
            perror("Can't Open the ttyUSB0 Serial Port");
            return -1;
	}
	while(1)
	{
	   usleep(1000);
       if((n=read(fd,buff,sizeof(buff)))<0)
        {
           perror("read error");
           return -1;
        }
		
		gps = gps_data_parse(buff);
		if(gps.rmc_data.pos_status == 0)
			continue;
	#if ENABLE_GGA
		printf("----------GGA DATA----------\n");
		printf("utc:%s\n", gps.gga_data.utc);
		printf("lat:%f\n", gps.gga_data.lat);
		printf("lat_dir:%c\n", gps.gga_data.lat_dir);
		printf("lon:%f\n", gps.gga_data.lon);
		printf("lon_dir:%c\n", gps.gga_data.lon_dir);
		printf("quality:%d\n", gps.gga_data.quality);
		printf("sats:%d\n", gps.gga_data.sats);
		printf("hdop:%f\n", gps.gga_data.hdop);
		printf("alt:%f\n", gps.gga_data.alt);
		printf("undulation:%f\n", gps.gga_data.undulation);
		printf("age:%d\n", gps.gga_data.age);
		printf("stn_ID:%d\n", gps.gga_data.stn_ID);
	#endif
	#if ENABLE_GLL
		printf("----------GLL DATA----------\n");
		printf("utc:%s\n", gps.gll_data.utc);
		printf("lat:%f\n", gps.gll_data.lat);
		printf("lat_dir:%c\n", gps.gll_data.lat_dir);
		printf("lon:%f\n", gps.gll_data.lon);
		printf("lon_dir:%c\n", gps.gll_data.lon_dir);
		printf("data_status:%c\n", gps.gll_data.data_status);
	#endif
	#if ENABLE_GSA
		printf("----------GSA DATA----------\n");
		printf("mode_MA:%c\n", gps.gsa_data.mode_MA);
		printf("mode_123:%c\n", gps.gsa_data.mode_123);
		printf("total:%d\n", gps.gsa_data.gsa_prn[0].total);
		for (i=0; i<gps.gsa_data.gsa_prn[0].total; i++)
		{
			printf("prn%d:%d\n", (i+1), gps.gsa_data.gsa_prn[i].prn);
		}
		printf("pdop:%f\n", gps.gsa_data.pdop);
		printf("hdop:%f\n", gps.gsa_data.hdop);
		printf("vdop:%f\n", gps.gsa_data.vdop);
		// gps.gsa_data.gsa_prn是动态分配的内存,用完记得释放,否则会造成内存泄漏
		free(gps.gsa_data.gsa_prn);
	#endif
	#if ENABLE_RMC
		printf("----------RMC DATA----------\n");
		printf("utc:%s\n", gps.rmc_data.utc);
		printf("lat:%f\n", gps.rmc_data.lat);
		printf("lat_dir:%c\n", gps.rmc_data.lat_dir);
		printf("lon:%f\n", gps.rmc_data.lon);
		printf("lon_dir:%c\n", gps.rmc_data.lon_dir);
		printf("speed_Kn:%f\n", gps.rmc_data.speed_Kn);
		printf("track_true:%f\n", gps.rmc_data.track_true);
		printf("date:%s\n", gps.rmc_data.date);
		printf("mag_var:%f\n", gps.rmc_data.mag_var);
		printf("var_dir:%c\n", gps.rmc_data.var_dir);
		printf("mode_ind:%c\n", gps.rmc_data.mode_ind);
	#endif
	#if ENABLE_VTG
		printf("----------VTG DATA----------\n");
		printf("track_true:%f\n", gps.vtg_data.track_true);
		printf("track_mag:%f\n", gps.vtg_data.track_mag);
		printf("speen_Kn:%f\n", gps.vtg_data.speed_Kn);
		printf("speed_Km:%f\n", gps.vtg_data.speed_Km);
	#endif
	#if ENABLE_GSV
		printf("----------GPGSV DATA----------\n");
		printf("msgs:%d\n", gps.gpgsv_data.msgs);
		printf("msg:%d\n", gps.gpgsv_data.msg);
		printf("sats:%d\n", gps.gpgsv_data.sats);
		for (i=0;i<gps.gpgsv_data.sats; i++)
		{
			printf("prn%d:%d\n", i+1, gps.gpgsv_data.sat_info[i].prn);
			printf("evel%d:%d\n", i+1, gps.gpgsv_data.sat_info[i].elev);
			printf("azimuth%d:%d\n", i+1, gps.gpgsv_data.sat_info[i].azimuth);
			printf("SNR%d:%d\n", i+1, gps.gpgsv_data.sat_info[i].SNR);
		}
		// 用完释放gps.gpgsv_data.sat_info内存
		if (gps.gpgsv_data.sats) free(gps.gpgsv_data.sat_info);

		printf("----------GNGSV DATA----------\n");
		printf("msgs:%d\n", gps.gngsv_data.msgs);
		printf("msg:%d\n", gps.gngsv_data.msg);
		printf("sats:%d\n", gps.gngsv_data.sats);
		for (i=0; i<gps.gngsv_data.sats; i++)
		{
			printf("prn%d:%d\n", i+1, gps.gngsv_data.sat_info[i].prn);
			printf("evel%d:%d\n", i+1, gps.gngsv_data.sat_info[i].elev);
			printf("azimuth%d:%d\n", i+1, gps.gngsv_data.sat_info[i].azimuth);
			printf("SNR%d:%d\n", i+1, gps.gngsv_data.sat_info[i].SNR);
		}
		if (gps.gngsv_data.sats) free(gps.gngsv_data.sat_info);

		printf("----------GLGSV DATA----------\n");
		printf("msgs:%d\n", gps.glgsv_data.msgs);
		printf("msg:%d\n", gps.glgsv_data.msg);
		printf("sats:%d\n", gps.glgsv_data.sats);
		for (i=0;i<gps.glgsv_data.sats; i++)
		{
			printf("prn%d:%d\n", i+1, gps.glgsv_data.sat_info[i].prn);
			printf("evel%d:%d\n", i+1, gps.glgsv_data.sat_info[i].elev);
			printf("azimuth%d:%d\n", i+1, gps.glgsv_data.sat_info[i].azimuth);
			printf("SNR%d:%d\n", i+1, gps.glgsv_data.sat_info[i].SNR);
		}
		if (gps.glgsv_data.sats) free(gps.glgsv_data.sat_info);
	#endif
	#if ENABLE_UTC && ENABLE_RMC
		printf("----------UTC DATA----------\n");
		printf("year:20%02d\n", gps.utc.YY);
		printf("month:%02d\n", gps.utc.MM);
		printf("date:%02d\n", gps.utc.DD);
		printf("hour:%02d\n", gps.utc.hh);
		printf("minutes:%02d\n", gps.utc.mm);
		printf("second:%02d\n", gps.utc.ss);
		printf("ds:%02d\n", gps.utc.ds);
	#endif
	}
    return 0;
}

Makefile


objs= gps.o main.o
srcs= gps.c main.c
 
gps_test: $(objs)
	$(CC) -o gps_test $(objs)
	@make clean
 
main.o: $(srcs) gps.h
	$(CC) -c  $(srcs)
 
gps.o: gps.c gps.h
	$(CC) -c  gps.c
 
clean:
	rm *.o

参考文件连接

C解析GPS数据_一杯凉白开-CSDN博客

  • 5
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值