|
楼主 |
发表于 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);
}
} |
|