LuatOS
直播中

jf_08548249

4年用户 20经验值
擅长:控制/MCU
私信 关注

【合宙Air551G双频定位开发板试用体验】GPS 数据解读(修正乱码问题)

上一篇,Air551G双频定位开发板 通过串口连接电脑,读取了GPS数据,并保留在文件
《0307_155837_COM07.txt  》中,



解读GPS信息:
模块支持NMEA 0183 V4.1协议:
GGA:  时间,位置,卫星数量
GLL:   精度,纬度,UTC时间
GSA:   GPS 接收机操作模式,
GSV:  可见GPS 卫星信息,仰角,方位角,信噪比
RMP:  时间,日期,位置,速度
VTG:   地面速度信息

采用RMP方式, 可解读到 时间,日期,位置,速度 信息。
GNRMC 定位信息,数据结构:

$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=数据无效)

部分解析代码
以下部分解析代码可供参考:

1.1 创建Air551G_GPS数据结构体:
typedef GPS_data struct{
    double latitude; //经度
    double longitude; //纬度
    int latitude_Degree;    //度
    int        latitude_Cent;   //分
    int     latitude_Second; //秒
    int longitude_Degree;    //度
    int        longitude_Cent;  //分
    int     longitude_Second; //秒
    float     speed; //速度
    float     direction; //航向
    float     height; //海拔高度
    int satellite;
    U8     NS;
    U8     EW;
    DATE_TIME D;
}Air551G_GPS_INFO;


1.2  时间结构体:
typedef struct{
    int year;
    int month;
    int day;
    int hour;
    int minute;
    int second;
}DATE_TIME;


1.3  逗号位置函数
int GetComma(int num,char *str){
    int i,j=0;
    int len=strlen(str);
    for(i=0;i<len;i++)
    {
       IF(str==',')
        {
             j++;
        }

        if(j==num)
            return i+1;
    }
    return 0;
}



1.4 转换为double型
double
Get_Double_Number  (char *s){
   char buf[128];
    int i;
    double rev;
    i=GetComma(1,s);
    strncpy(buf,s,i);
    buf
=0;
    rev=atof(buf);
   return rev;
}

1.5  解析GPRMC数据
int GPS_RMC_Parse(char *line, Air551G_GPS_INFO *GPS)

{
    U8 ch, status, tmp;
    float lati_cent_tmp, lati_second_tmp;
    float long_cent_tmp, long_second_tmp;
    float speed_tmp;
    char *buf = line;
    ch = buf[5];
    status = buf[GetComma(2, buf)];

    if (ch == 'C') //如果第五个字符是C,($GPRMC)
    {
        if (status == 'A') //如果数据有效,则分析
        {
            GPS->NS = buf[GetComma(4, buf)];
            GPS->EW = buf[GetComma(6, buf)];

            GPS->latitude = Get_Double_Number(&buf[GetComma(3, buf)]);
            GPS->longitude = Get_Double_Number(&buf[GetComma(5, buf)]);

            GPS->latitude_Degree = (int)GPS->latitude / 100; //分离纬度
            lati_cent_tmp = (GPS->latitude - GPS->latitude_Degree * 100);
            GPS->latitude_Cent = (int)lati_cent_tmp;
            lati_second_tmp = (lati_cent_tmp - GPS->latitude_Cent) * 60;
            GPS->latitude_Second = (int)lati_second_tmp;

            GPS->longitude_Degree = (int)GPS->longitude / 100;    //分离经度
            long_cent_tmp = (GPS->longitude - GPS->longitude_Degree * 100);
            GPS->longitude_Cent = (int)long_cent_tmp;
            long_second_tmp = (long_cent_tmp - GPS->longitude_Cent) * 60;
            GPS->longitude_Second = (int)long_second_tmp;

            speed_tmp = Get_Float_Number(&buf[GetComma(7, buf)]); //速度(单位:海里/时)
            GPS->speed = speed_tmp * 1.85; //1海里=1.85公里
            GPS->direction = Get_Float_Number(&buf[GetComma(8, buf)]); //角度            

            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;

            UTC2BTC(&GPS->D);

            return 1;
        }        
    }

    return 0;
}

line是串口接收的一行数据buf
解出的GPS数据,即可送LCD显示,或 区域控制,报警。



参考文献:
原文链接:https://blog.csdn.net/jwq2011/article/details/53674125

更多回帖

发帖
×
20
完善资料,
赚取积分