搜索
bottom↓
回复: 43

图解GPS解码

  [复制链接]

出0入8汤圆

发表于 2013-8-2 11:20:10 | 显示全部楼层 |阅读模式
在论坛上潜水很久了,再不发点资料就....

下面我就以GPRMC解码为例,讲述我的解码方法,不对的地方,请大家指正,谢谢!
1。GPS串口接收部分的数据结构:
#define GPS_BUFFER_LEN  127                      //0x7f,d6~d0都为1
typedef struct
{
    uint8_t star_$:1;                                      //注意,只有D0位有效
    int8_t GPS_data_Count;
    uint8_t GPS_Buffer[2][GPS_BUFFER_LEN];  //二级缓冲
   
}Gps_Rx_T;

Gps_Rx_T Gps_data;

//串口中断接收GPS数据

void UART0_IRQHandler(void)
{
    uint8_t u8InChar=0xFF;
    uint32_t u32_IQR= UART0->ISR;
    uint32_t u32_status = UART0->FSR;
    UART0->ISR = u32_IQR;
    OSIntEnter();
   
    //串口接收数据
    if (((_UART_IS_RX_READY(UART0) > 0) || (_UART_IS_RX_TIMEOUT(UART0) > 0)) && (_UART_IS_RX_BUF_ERR(UART0) == 0))
    {
        while(_UART_IS_RX_EMPTY(UART0) == 0)
        {
            _UART_RECEIVEBYTE(UART0, u8InChar);
            switch(u8InChar)
            {   //NEMA0183 格式数据以$开始,\r\n结尾(0x0d 0x0a)
               case '$':   
                    Gps_data.star_$++;
                    Gps_data.GPS_data_Count=0;
               break;
               case 0x0a:
                    OS_IntSend_Msg(Task0_Prio, &Gps_data.GPS_Buffer[Gps_data.star_$]);        //给任务0发消息
                break;
                default:    break;   
            }
            Gps_data.GPS_Buffer[Gps_data.star_$ & 0x01][Gps_data.GPS_data_Count++ & GPS_BUFFER_LEN] = u8InChar;
        }
    }
    else
    {//串口BUFFER数据溢出处理
        while(_UART_IS_RX_EMPTY(UART0) == 0)
        {
            _UART_FLUSH_FIFO(UART0, UART_FCR_TFR_Msk | UART_FCR_RFR_Msk);
            _UART_RECEIVEBYTE(UART0, u8InChar);
        }  
    }
   
    OSIntExit();
}

从上面的代码中,我们可以看到 Gps_data.star_$ 变量是记录 '$' 次数的,Gps_data.star_$ 只能等于0 或 1, 因为存放GPS数据的数组 uint8_t GPS_Buffer[2][GPS_BUFFER_LEN];  是二级缓冲.

当我们收到GPS输出 的第一个字节‘$’的时候,我们就这样处理:
               case '$':   
                    Gps_data.star_$++;                        //使用一个新的缓冲区
                    Gps_data.GPS_data_Count=0;         //数据个数从0记起
               break;


Gps_data.GPS_Buffer[Gps_data.star_$ & 0x01][Gps_data.GPS_data_Count++ & GPS_BUFFER_LEN] = u8InChar;   //就是把GPS输出的数据从'$'到0xda之前的数据存入数据缓冲区


看,我们第一步已做好了。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

阿莫论坛20周年了!感谢大家的支持与爱护!!

月入3000的是反美的。收入3万是亲美的。收入30万是移民美国的。收入300万是取得绿卡后回国,教唆那些3000来反美的!

出0入8汤圆

 楼主| 发表于 2013-8-2 11:31:25 | 显示全部楼层
第二步就是把收到的一帧数据送去解码,在这里我模块了ucos的消息同步机制:
               case 0x0a:
                    OS_IntSend_Msg(Task0_Prio, &Gps_data.GPS_Buffer[Gps_data.star_$]);        //给任务0发消息
                break;
//任务0是GPS解码任务.


现在我们进入解码函数里:


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入12汤圆

发表于 2013-8-2 11:32:54 | 显示全部楼层
楼主给个实例工程更好理解呀

出0入8汤圆

 楼主| 发表于 2013-8-2 11:34:24 | 显示全部楼层
GPMRC解码,太长了,我们先实现,再分段讲解!

void GprmcMessage(uint8_t *Buffer, uint8_t Len)
{
        uint8_t CommaNum; //逗号数
        uint8_t BufIndex; //数字量
        uint8_t Sbuf;
        uint8_t *Pstr;
   
    uint8_t hour, minute, sec, year, month, day, t;
   
        int i_tmp;
        double d_tmp;
    uint32_t w;

    GPS_GPRMC_T *pGPRMC_tmp;
   
   
    gRMC_info.POS_state = 'V';
   
   
    if ((sizeof(GPS_GPRMC_T) % 2) != 0)
    {
        pGPRMC_tmp = osal_mem_alloc(sizeof(GPS_GPRMC_T)+1);
    }
    else
    {
        pGPRMC_tmp = osal_mem_alloc(sizeof(GPS_GPRMC_T));
    }
   
    if (NULL != pGPRMC_tmp)
    {
        memset(pGPRMC_tmp, '\0', sizeof(GPS_GPRMC_T));
        //$GPRMC,<UTC时间>,<有效状态>,<纬度>,<纬度半球>,<经度>,<经度半球>,<地面速率>,<地面航向>,<UTC日期>,<磁偏角>,<磁偏角方向>,<模式指示>*<校验和><CR><LF>
        //NMEA0183语句(推荐定位信息(GPRMC))
        //$GPRMC,100259.00,A,3119.26216,N,12024.85164,E,2.447,,020613,,,A*7C
        //      1         2 3          4 5          6 7   8   9      ABC
        BufIndex=0;         //数字量
        CommaNum=0;         //逗号数
        Pstr=Buffer;            //找到GPRMC,后面的地址
        do
        {
            Sbuf=*Pstr++;       
         
            switch(Sbuf)
            {
                case ',':   CommaNum++;  BufIndex=0;    break;//通过逗号的数目来进行状态分类
                case '*':                               break;
                default:
                        switch(CommaNum)
                        {
                            case 1: pGPRMC_tmp->UTC_Time[BufIndex]        =Sbuf;      break;
                            case 2: pGPRMC_tmp->POS_state                 =Sbuf;      break;
                            case 3: pGPRMC_tmp->WD_Lat[BufIndex]          =Sbuf;      break;
                            case 4: pGPRMC_tmp->NS_WD                     =Sbuf;      break;
                            case 5: pGPRMC_tmp->JD_Long[BufIndex]         =Sbuf;      break;
                            case 6: pGPRMC_tmp->EW_JD                     =Sbuf;      break;
                            case 7: pGPRMC_tmp->Speed[BufIndex]           =Sbuf;      break;
                            case 8: pGPRMC_tmp->Azimuth[BufIndex]         =Sbuf;      break;
                            case 9: pGPRMC_tmp->UTC_Date[BufIndex]        =Sbuf;      break;
                            case 10: pGPRMC_tmp->MagneticDegrees[BufIndex]=Sbuf;      break;
                            case 11: pGPRMC_tmp->MagneticDirection        =Sbuf;      break;
                            case 12: pGPRMC_tmp->Mode                     =Sbuf;      break;
                            default:break;
                        }
                        BufIndex++;        //
                        break;
            }
        }while(Sbuf!='*');//直到出现‘*’退出          

        gRMC_info.POS_state = 'V';
        if ('A' == pGPRMC_tmp->POS_state)
        {
            //时分秒
            hour    =   (pGPRMC_tmp->UTC_Time[0]-0x30) * 10 + pGPRMC_tmp->UTC_Time[1]-0x30;
            minute  =   (pGPRMC_tmp->UTC_Time[2]-0x30) * 10 + pGPRMC_tmp->UTC_Time[3]-0x30;
            sec     =   (pGPRMC_tmp->UTC_Time[4]-0x30) * 10 + pGPRMC_tmp->UTC_Time[5]-0x30;  
            //年月日
            year    =   (pGPRMC_tmp->UTC_Date[4]-0x30) * 10 + pGPRMC_tmp->UTC_Date[5]-0x30;
            month         =   (pGPRMC_tmp->UTC_Date[2]-0x30) * 10 + pGPRMC_tmp->UTC_Date[3]-0x30;
            day     =   (pGPRMC_tmp->UTC_Date[0]-0x30) * 10 + pGPRMC_tmp->UTC_Date[1]-0x30;
            
                 
            //处理时间及日期
            t = GetDom(year+2000, month);                ////返回当月的最大天数
            hour = hour+8;
            if (hour >= 24)
            {
                hour -= 24;
                day += 1;
                if (day > t)
                {
                    day -= t;
                    month++;
                    if (month > 12)
                    {
                        month -= 12;
                        year++;
                    }
                }
            }  
            //更新系统时间
            UpdateSystime(year, month, day, hour, minute, sec);
            
            gRMC_info.Y_M_D[0]=0; gRMC_info.Y_M_D[1]=0; gRMC_info.Y_M_D[2]=0;
            gRMC_info.Y_M_D[3]=0; gRMC_info.Y_M_D[4]=0; gRMC_info.Y_M_D[5]=0;
            // year
            gRMC_info.Y_M_D[0] = (year/10)+0x30;
            gRMC_info.Y_M_D[1] = (year%10)+0x30;
            //month
            gRMC_info.Y_M_D[2] = (month/10)+0x30;
            gRMC_info.Y_M_D[3] = (month%10)+0x30;        
            //day
            gRMC_info.Y_M_D[4] = (day/10)+0x30;
            gRMC_info.Y_M_D[5] = (day%10)+0x30;  
            
            gRMC_info.H_M_S[0]=0; gRMC_info.H_M_S[1]=0; gRMC_info.H_M_S[2]=0;
            gRMC_info.H_M_S[3]=0; gRMC_info.H_M_S[4]=0; gRMC_info.H_M_S[5]=0;
            //hour
            gRMC_info.H_M_S[0] = (hour/10)+0x30;
            gRMC_info.H_M_S[1] = (hour%10)+0x30;
            //minute
            gRMC_info.H_M_S[2] = (minute/10)+0x30;
            gRMC_info.H_M_S[3] = (minute%10)+0x30;
            //sec
            gRMC_info.H_M_S[4] = (sec/10)+0x30;
            gRMC_info.H_M_S[5] = (sec%10)+0x30;
            //是否有效定位
            gRMC_info.POS_state = pGPRMC_tmp->POS_state;
            //数据有效才转换经纬度
            d_tmp           = Str_To_Double(&pGPRMC_tmp->WD_Lat[0]);
            i_tmp                      = (int)d_tmp / 100;                                       //分离纬度
            d_tmp           = (d_tmp - i_tmp * 100)/60;                            //分
            d_tmp                 = (double)i_tmp +  d_tmp;   
            
            gRMC_info.WD_string[0]=0; gRMC_info.WD_string[1]=0; gRMC_info.WD_string[2]=0; gRMC_info.WD_string[3]=0;
            gRMC_info.WD_string[4]=0; gRMC_info.WD_string[5]=0; gRMC_info.WD_string[6]=0; gRMC_info.WD_string[7]=0;
            gRMC_info.WD_string[8]=0; gRMC_info.WD_string[9]=0; gRMC_info.WD_string[10]=0;
            //纬度的范围是南北纬0-90°
            w = (uint32_t)d_tmp;
            Myitoa(w, &(gRMC_info.WD_string[0]));
            if (w <10)
            {   //1.123456
                w = (uint32_t)(((d_tmp - w)+1) * 10000000);                //w=1.xxxx
                Myitoa(w, &(gRMC_info.WD_string[1]));
                gRMC_info.WD_string[1] = '.';            
            }
            else
            {   //31.320145
                w = (uint32_t)(((d_tmp - w)+1) * 10000000);                //w=1.xxxx
                Myitoa(w, &(gRMC_info.WD_string[2]));
                gRMC_info.WD_string[2] = '.';  
            }   

            gRMC_info.NS_WD = pGPRMC_tmp->NS_WD;
           
            d_tmp           = Str_To_Double(&pGPRMC_tmp->JD_Long[0]);
            i_tmp                 = (int)d_tmp / 100;                                                    //分离经度
            d_tmp           = (d_tmp - i_tmp * 100)/60;
            d_tmp                 = (double)d_tmp + i_tmp;
            
            gRMC_info.JD_string[0]=0; gRMC_info.JD_string[1]=0; gRMC_info.JD_string[2]=0; gRMC_info.JD_string[3]=0;
            gRMC_info.JD_string[4]=0; gRMC_info.JD_string[5]=0; gRMC_info.JD_string[6]=0; gRMC_info.JD_string[7]=0;
            gRMC_info.JD_string[8]=0; gRMC_info.JD_string[9]=0; gRMC_info.JD_string[10]=0;
                    
            //经度的范围是东西经0-180°
            w = (uint32_t)d_tmp;
            Myitoa(w, &(gRMC_info.JD_string[0]));       
            if (w < 10)
            {   //1.123456
                w = (uint32_t)(((d_tmp - w)+1) * 10000000);
                Myitoa(w, &(gRMC_info.JD_string[1]));  
                gRMC_info.JD_string[1] = '.';
            }
            else if (w < 100)
            {   //11.123456
                w = (uint32_t)(((d_tmp - w)+1) * 10000000);
                Myitoa(w, &(gRMC_info.JD_string[2]));  
                gRMC_info.JD_string[2] = '.';
            }
            else if (w < 190)
            {
                w = (uint32_t)(((d_tmp - w)+1) * 10000000);
                Myitoa(w, &(gRMC_info.JD_string[3]));  
                gRMC_info.JD_string[3] = '.';
            }  

            gRMC_info.EW_JD=pGPRMC_tmp->EW_JD;

            //地面速率(000.0~999.9节,前面的0也将被传输)
            d_tmp = Str_To_Double(pGPRMC_tmp->Speed) * 1.85;          //1海里=1.85公里
            
            w = (uint32_t)d_tmp;
            Myitoa(w, &(gRMC_info.Speed[0]));       
            if (w < 10)
            {   //1.123456
                w = (uint32_t)(((d_tmp - w)+1) * 10000000);
                Myitoa(w, &(gRMC_info.Speed[1]));  
                gRMC_info.Speed[1] = '.';
            }
            else if (w < 100)
            {   //11.123456
                w = (uint32_t)(((d_tmp - w)+1) * 10000000);
                Myitoa(w, &(gRMC_info.Speed[2]));  
                gRMC_info.Speed[2] = '.';
            }
            else if (w < 1000)
            {
                w = (uint32_t)(((d_tmp - w)+1) * 10000000);
                Myitoa(w, &(gRMC_info.Speed[3]));  
                gRMC_info.Speed[3] = '.';
            }  
        }
        osal_mem_free(pGPRMC_tmp);
    }
}

出0入8汤圆

 楼主| 发表于 2013-8-2 11:37:06 | 显示全部楼层
朋友们先别回复,请等待我写完再回复,谢谢!

出0入0汤圆

发表于 2013-8-2 11:39:26 | 显示全部楼层
写完了吗。。

出0入8汤圆

 楼主| 发表于 2013-8-2 11:57:00 | 显示全部楼层
我们还是来看一下这个 GPS_GPRMC_T 结构吧,它其实是一个中间变量,不过我在网上看到很多人解码的时候只做到这里,但这不是我们的终极结果!

/*
GPRMC推荐定位信息(GPRMC)
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh
<1> UTC时间,hhmmss.sss(时分秒.毫秒)格式
<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> 模式指示(仅NMEA0183 3.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效)
*/
//经纬度buf长度
#define JWD_BUTF_LEN                        11
typedef struct         //typedef __packed struct
{        //GPRMC
    uint8_t UTC_Time[9];                                    
    uint8_t POS_state;
    uint8_t WD_Lat[JWD_BUTF_LEN];             //加\0
    uint8_t NS_WD;
    uint8_t JD_Long[JWD_BUTF_LEN];            //加\0
    uint8_t EW_JD;
    uint8_t Speed[8];
    uint8_t Azimuth[8];
    uint8_t UTC_Date[6];  
    uint8_t MagneticDegrees[8];
    uint8_t MagneticDirection;
    uint8_t Mode;
}GPS_GPRMC_T;




下面就是分离数据了:


呵呵,先去吃饭,一会再写

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入8汤圆

 楼主| 发表于 2013-8-2 13:23:43 | 显示全部楼层
我们的最终结果是存放在这个结构体中:
typedef struct
{        //GPRMC
    uint8_t Y_M_D[8];  //20130707
    uint8_t H_M_S[6];    //222401
    uint8_t POS_state;
    uint8_t WD_string[JWD_BUTF_LEN];             //加\0
    uint8_t NS_WD;
    uint8_t JD_string[JWD_BUTF_LEN];            //加\0
    uint8_t EW_JD;
    uint8_t Speed[8];
    uint8_t Azimuth[8];
    uint8_t MagneticDegrees[8];
    uint8_t MagneticDirection;
    uint8_t Mode;
}GPRMC_T;

extern GPRMC_T gRMC_info;  //是全局变量
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
下面我们把时间做一下转换,改成北京时间,UTC时间加8小时就是北京时间.

        //时分秒
        hour    =   (GPRMC_tmp.UTC_Time[0]-0x30) * 10 + GPRMC_tmp.UTC_Time[1]-0x30;
        minute  =   (GPRMC_tmp.UTC_Time[2]-0x30) * 10 + GPRMC_tmp.UTC_Time[3]-0x30;
        sec     =   (GPRMC_tmp.UTC_Time[4]-0x30) * 10 + GPRMC_tmp.UTC_Time[5]-0x30;  
        //年月日
        year    =   (GPRMC_tmp.UTC_Date[4]-0x30) * 10 + GPRMC_tmp.UTC_Date[5]-0x30;
        month         =   (GPRMC_tmp.UTC_Date[2]-0x30) * 10 + GPRMC_tmp.UTC_Date[3]-0x30;
        day     =   (GPRMC_tmp.UTC_Date[0]-0x30) * 10 + GPRMC_tmp.UTC_Date[1]-0x30;
        
            
        //处理时间及日期
        t = GetDom(year+2000, month);                ////返回当月的最大天数
        hour = hour+8;
        if (hour >= 24)
        {
            hour -= 24;
            day += 1;
            if (day > t)
            {
                day -= t;
                month++;
                if (month > 12)
                {
                    month -= 12;
                    year++;
                }
            }
        }  
//GetDom()代码实现:

/*----------------------------------------------------------------------------------------
  0000年~9999年星期算法(菜农自创)
-----------------------------------------------------------------------------------------*/
unsigned int GetDow(unsigned int y, unsigned int m, unsigned int d)
{
        unsigned int w, c;
        if (m <= 2)
        {
                m |= 4;//1月2月同5月六月表
                y--;
        }
        c = y / 100;
        c &= 0x03;//百年%4
        y %= 100;
        w = ((c | (c << 2)) + (y + (y >> 2)) + (13 * m + 8)/ 5 + d) % 7;//(星期=百年%4*5+年+年/4+(13*月+8)/5+日)%7
        return w;//返回星期
}

/*----------------------------------------------------------------------------------------
  附赠0000年~9999年月最大天数算法(菜农自创)
-----------------------------------------------------------------------------------------*/
int GetDom(unsigned int y, unsigned int m)
{
        int dn;
        dn = GetDow(y, m + 1, 1) - GetDow(y, m, 1);//m+1=13表示明年的1月
        if (dn < 0) dn += 7;
        return dn + 28;//返回当月的最大天数
}

运行结果:


纬度数据解析


//函数实现

//====================================================================//
// 语法格式: double Str_To_Double(uint8_t *buf)
// 实现功能: 把一个字符串转化成浮点数
// 参    数:字符串
// 返 回 值:转化后双精度值
//====================================================================//
double Str_To_Double(uint8_t *buf)
{
        double rev = 0.0f;
        double dat;
        int integer = 1;
        uint8_t *str = buf;
        int i=0;
        while(*str != '\0')
        {
                switch(*str)
                {
                        case '0':
                                dat = 0;
                                break;
                        case '1':
                                dat = 1;
                                break;
                        case '2':
                                dat = 2;
                                break;               
                        case '3':
                                dat = 3;
                                break;
                        case '4':
                                dat = 4;
                                break;
                        case '5':
                                dat = 5;
                                break;
                        case '6':
                                dat = 6;
                                break;
                        case '7':
                                dat = 7;
                                break;
                        case '8':
                                dat = 8;
                                break;
                        case '9':
                                dat = 9;
                                break;
                        case '.':
                                dat = '.';
                                break;
                }
                if(dat == '.')
                {
                        integer = 0;
                        i = 1;
                        str ++;
                        continue;
                }
                if( integer == 1 )
                {
                        rev = rev * 10 + dat;
                }
                else
                {
                        rev = rev + dat / (10 * i);
                        i = i * 10 ;
                }
                str ++;
        }
        return rev;
}

//整数转字符串,最大长度 11 位,包括正负标志位
void Myitoa(int32_t n, uint8_t str[])
{
    int32_t i, sign;
    uint8_t s[12];
    uint8_t j=0;
    if((sign=n) < 0)
        n=-n;

    i=0;
    do
    {
        s[i++] = n % 10 + '0';
    }while ((n/=10) > 0);

    if(sign < 0)
        s[i++] = '-';

    s = '\0';

    //for (; i>0; i-- )
    do{
        str[j++] = s[i-1];
    }while(--i > 0);
}





本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入8汤圆

 楼主| 发表于 2013-8-2 13:30:31 | 显示全部楼层


对此,我们已完成了GPRMC数据的全部解码。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册

x

出0入0汤圆

发表于 2013-8-2 13:42:08 | 显示全部楼层
顶一下,楼主辛苦了,暂时还用不上.

出0入0汤圆

发表于 2013-8-2 13:52:07 | 显示全部楼层
skype 发表于 2013-8-2 13:30
对此,我们已完成了GPRMC数据的全部解码。

不cuo!                           

出0入0汤圆

发表于 2013-8-2 13:53:28 | 显示全部楼层
支持一下,讲解的比较详细

出0入0汤圆

发表于 2013-8-2 13:58:27 | 显示全部楼层
楼主辛苦发帖一定要顶。

出0入0汤圆

发表于 2013-8-2 20:23:06 | 显示全部楼层
頂一下

出0入8汤圆

发表于 2013-8-2 20:26:37 | 显示全部楼层
标题叫  串口数据解码更合适吧~一开始我还以为是软件解码GPS前端的卫星数据呢。。。

出100入0汤圆

发表于 2013-8-2 20:26:46 来自手机 | 显示全部楼层
mark  楼主辛苦了!

出0入10汤圆

发表于 2013-11-1 16:22:07 | 显示全部楼层
额,楼主好有耐心,顶一下!

出0入0汤圆

发表于 2013-11-4 14:33:16 | 显示全部楼层
对我们初学的来说非常有用,谢楼主了.

出0入0汤圆

发表于 2013-11-4 16:34:34 | 显示全部楼层
MARK,过段时间解析GPS再仔细阅读

出0入4汤圆

发表于 2013-11-4 18:13:47 | 显示全部楼层
很高兴见到用结构体封装数据流;
在数据类型组合能重复出现的场合(多见于通讯),运用结构体指针是再合适不过的了;
我以前说老德的tcp/ip代码写的很优雅,也是这个原因;
还有就是状态机的运用;
顶楼主,高兴。  当然,代码收下,不谢!

出0入0汤圆

发表于 2013-11-4 19:16:12 | 显示全部楼层
学习了         

出0入0汤圆

发表于 2013-11-18 10:45:03 | 显示全部楼层
太好了,早点看到楼主的大作该多好啊,谢谢楼主无私指教。先收下,等以后再研究。

出0入0汤圆

发表于 2013-12-26 13:37:47 | 显示全部楼层
来学习下。。。

出0入0汤圆

发表于 2014-4-20 15:58:16 | 显示全部楼层
结构体封装的不错啊,就是名字命名可以更加直白

出0入0汤圆

发表于 2014-5-3 16:44:46 | 显示全部楼层
好东西,只恨相见太晚了。

出0入0汤圆

发表于 2014-5-3 19:27:20 | 显示全部楼层
多谢分享,不过这个按照标准数据格式解析一下即可

出0入0汤圆

发表于 2014-5-6 20:44:15 | 显示全部楼层
辛苦了,很详细

出0入0汤圆

发表于 2014-8-24 07:13:40 | 显示全部楼层

辛苦了,很详细

出0入0汤圆

发表于 2014-9-5 14:25:14 | 显示全部楼层
标记一下

出0入0汤圆

发表于 2014-9-5 16:04:40 | 显示全部楼层
里面有几个函数很有参考价值

出0入0汤圆

发表于 2014-9-6 08:25:01 | 显示全部楼层
mark 一下 图解GPS解码

出0入0汤圆

发表于 2014-9-9 18:33:43 | 显示全部楼层

标记一下

出0入0汤圆

发表于 2014-9-9 18:36:45 | 显示全部楼层
楼主辛苦,已下载

出0入0汤圆

发表于 2014-9-9 20:10:34 | 显示全部楼层
讲的很漂亮,抽时间好好研究下……

出0入0汤圆

发表于 2014-9-15 00:53:36 | 显示全部楼层
LZ的教程写得很好,特别系解析部分的状态机
但没发现有CHECKSUM部分,是因为LZ项目上用不到吗?

出0入16汤圆

发表于 2014-9-15 09:24:01 | 显示全部楼层
mark  楼主辛苦了!

出0入0汤圆

发表于 2014-10-12 20:04:46 | 显示全部楼层
谢谢 楼主  过段时间好好看下

出0入0汤圆

发表于 2014-10-16 23:10:17 | 显示全部楼层
围观...

出0入0汤圆

发表于 2014-10-16 23:15:12 | 显示全部楼层
收藏,谢谢楼主

出0入0汤圆

发表于 2014-10-16 23:25:25 | 显示全部楼层
mark
感谢~~~~~

出0入0汤圆

发表于 2015-10-13 17:45:10 | 显示全部楼层
非常感谢

出0入0汤圆

发表于 2015-10-13 17:51:04 | 显示全部楼层
这个并不通用。如果移植个SEHLL的代码过来。。。不只是GPS,AT命令也一样能拆成一个个参数指针。我就是这么干的。

出0入0汤圆

发表于 2015-11-19 14:22:36 | 显示全部楼层
学习了  

出0入0汤圆

发表于 2015-11-19 14:51:40 | 显示全部楼层
谢谢楼主,收藏了
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-4-26 16:52

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表