NMEA-0183之$GPRMC数据处理

NMEA-0183

u 以下为GPS芯片串口发出的数据:

201512_15:42:3712,$GPTXT,ANTSTATUS=SHORT*43
201512_15:42:37$GNGGA,074219.000,3021.516740,N,12005.998703,E,1,9,1.09,20.996,M,6.991,M,,*42
201512_15:42:37$GNGLL,3021.516740,N,12005.998703,E,074219.000,A,A*45
201512_15:42:37$GPGSA,A,3,20,18,25,10,24,15,22,14,,,,,1.38,1.09,0.85*07
201512_15:42:37$BDGSA,A,3,06,,,,,,,,,,,,1.38,1.09,0.85*1A
201512_15:42:37$GPGSV,3,1,12,18,89,182,30,10,55,320,35,24,47,038,31,12,40,107,33*73
201512_15:42:38$GPGSV,3,2,12,14,34,297,29,22,33,315,32,25,31,156,32,15,25,077,31*7F
201512_15:42:38$GPGSV,3,3,12,20,22,140,31,31,08,227,27,37,,,,193,,,31*4A
201512_15:42:38$BDGSV,1,1,01,06,75,066,27*58
201512_15:42:38$GNVTG,128.46,T,,M,0.00,N,0.00,K,A*2A
201512_15:42:38$GNRMC,074219.000,A,3021.516740,N,12005.998703,E,0.00,128.46,311215,,,A*7E

 

u 数据接收:

GPRMC格式,数据长度不会超过70;

GPGGA格式,数据长度不会超过72;

Ø 以$开始保存,若长度超过74则丢弃并重新接收,否则判断结束符\r’’\n;

Ø 首次收到\r’’\n则向GPS芯片发送模式(GPS/BD/MIX)控制命令字;

Ø 判断GPS_RX[345]是否为’RMC’,是则开始处理;

 

u 数据处理:

Ø 判断锁定位;

Ø 时间:小时要+8,>24则需-24;

Ø 日期:需修正

static void DateRepair(void)
{
	uint8 day_tmp , mon_tmp , year_tmp;				// 日,月,年暂存
	year_tmp = ((gps_data.date_time[0] >> 4) * 10) + (gps_data.date_time[0] & 0xf);
	mon_tmp = ((gps_data.date_time[1] >> 4) * 10) + (gps_data.date_time[1] & 0xf);
	day_tmp = ((gps_data.date_time[2] >> 4) * 10) + (gps_data.date_time[2] & 0xf);
	day_tmp++;
	//GPSDATA.date[0]++;
	if(mon_tmp == 2)		// 如果是2月份
	{
		if((year_tmp % 4) != 0)
		{	//闰年
			if(day_tmp > 28)
			{	//28天
				day_tmp = 1;
				mon_tmp++;
			}
		}
		else 
		{
			if(day_tmp > 29)
			{	//29天
				day_tmp = 1;
				mon_tmp++;
			}
		}
	} 
	else if((mon_tmp == 4) || (mon_tmp == 6) || (mon_tmp == 9) || (mon_tmp == 11))
	{	//4,6,9,11月份
		if(day_tmp > 30)
		{
			day_tmp = 1;
			mon_tmp++;
		}
	} 
	else
	{
		if(day_tmp > 31)
		{	//1,3,5,7,8,10,12月份
			day_tmp = 1;
			mon_tmp++;
			if(mon_tmp > 12)
			{
				mon_tmp = 1;
				year_tmp++;
			}
		}
	}
	gps_data.date_time[0] = ((year_tmp / 10) << 4) + (year_tmp % 10);		// year
	gps_data.date_time[1] = ((mon_tmp / 10) << 4) + (mon_tmp % 10);			// mon
	gps_data.date_time[2] = ((day_tmp / 10) << 4) + (day_tmp % 10);			// day
}
 

Ø 经纬度

纬度ddmm.mmmm(度分)格式(前面的0也被传输),3021.5167=120.099786

经度dddmm.mmmm(度分)格式(前面的0也被传输),12005.9872=30.358613

static void longlat_sel(uint8 *pd , uint8 len)
{
	uint8 j , jj , jjj;
	// 先处理纬度
	j = lookup(pd , ',' , 3 , len);
	if(j)
	{
		for(jj = 0; jj < 5; jj++)
		{
			if((pd[j + jj] == '.') || (pd[j + jj] == ','))
				break;
		}
		//gps_data.latitude[0] = 0;
		switch(jj)
		{
			case 4:
				gps_data.latitude[0] = ((pd[j] & 0x0f) << 4) + (pd[j + 1] & 0x0f);
				gps_data.latitude[1] = ((pd[j + 2] & 0x0f) << 4) + (pd[j + 3] & 0x0f);
				break;
			case 3:
				gps_data.latitude[0] = pd[j] & 0x0f;
				gps_data.latitude[1] = ((pd[j + 1] & 0x0f) << 4) + (pd[j + 2] & 0x0f);
				break;
			case 2:
				gps_data.latitude[0] = 0;
				gps_data.latitude[1] = ((pd[j] & 0x0f) << 4) + (pd[j + 1] & 0x0f);
				break;
			case 1:
				gps_data.latitude[0] = 0;
				gps_data.latitude[1] = pd[j] & 0x0f;
				break;
			default:
				gps_data.latitude[0] = 0;
				gps_data.latitude[1] = 0;
				break; 
		}
		jjj = lookup(pd , ',' , 4 , len);
		switch(jjj - j - jj - 2)	// 小数点后的位数
		{
			case 6:
			case 5:
			case 4:
				gps_data.latitude[2] = ((pd[j + jj + 1] & 0x0f) << 4) + (pd[j + jj + 2] & 0x0f);
				gps_data.latitude[3] = ((pd[j + jj + 3] & 0x0f) << 4) + (pd[j + jj + 4] & 0x0f);
				break;
			case 3:
				gps_data.latitude[2] = ((pd[j + jj + 1] & 0x0f) << 4) + (pd[j + jj + 2] & 0x0f);
				gps_data.latitude[3] = (pd[j + jj + 3] & 0x0f) << 4;
				break;
			case 2:
				gps_data.latitude[2] = ((pd[j + jj + 1] & 0x0f) << 4) + (pd[j + jj + 2] & 0x0f);
				gps_data.latitude[3] = 0;
				break;
			case 1:
				gps_data.latitude[2] = (pd[j + jj + 1] & 0x0f) << 4;
				gps_data.latitude[3] = 0;
				break;
			default:
				gps_data.latitude[2] = 0;
				gps_data.latitude[3] = 0;
				break; 
		}
	}
	// 再处理经度
	j = lookup(pd , ',' , 5 , len); 
	if(j)
	{
		for(jj = 0; jj < 5; jj++)
		{
			if((pd[j + jj] == '.') || (pd[j + jj] == ','))
				break;
		}
		switch(jj)
		{
			case 5:
				gps_data.longitude[0] = pd[j] & 0x0f;
				gps_data.longitude[1] = ((pd[j + 1] & 0x0f) << 4) + (pd[j + 2] & 0x0f);
				gps_data.longitude[2] = ((pd[j + 3] & 0x0f) << 4) + (pd[j + 4] & 0x0f);
				break;
			case 4:
				gps_data.longitude[0] = 0;
				gps_data.longitude[1] = ((pd[j] & 0x0f) << 4) + (pd[j + 1] & 0x0f);
				gps_data.longitude[2] = ((pd[j + 2] & 0x0f) << 4) + (pd[j + 3] & 0x0f);
				break;
			case 3:
				gps_data.longitude[0] = 0;
				gps_data.longitude[1] = pd[j] & 0x0f;
				gps_data.longitude[2] = ((pd[j + 1] & 0x0f) << 4) + (pd[j + 2] & 0x0f);
				break;
			case 2:
				gps_data.longitude[0] = 0;
				gps_data.longitude[1] = 0;
				gps_data.longitude[2] = ((pd[j] & 0x0f) << 4) + (pd[j + 1] & 0x0f);
				break;
			case 1:
				gps_data.longitude[0] = 0;
				gps_data.longitude[1] = 0;
				gps_data.longitude[2] = pd[j] & 0x0f;
				break;
			default:
				gps_data.longitude[0] = 0;
				gps_data.longitude[1] = 0;
				gps_data.longitude[2] = 0;
				break; 
		}
		jjj = lookup(pd , ',' , 6 , len);
		switch(jjj - j - jj - 2)	// 小数点后的位数
		{
			case 6:
			case 5:
			case 4:
				gps_data.longitude[3] = ((pd[j + jj + 1] & 0x0f) << 4) + (pd[j + jj + 2] & 0x0f);
				gps_data.longitude[4] = ((pd[j + jj + 3] & 0x0f) << 4) + (pd[j + jj + 4] & 0x0f);
				break;
			case 3:
				gps_data.longitude[3] = ((pd[j + jj + 1] & 0x0f) << 4) + (pd[j + jj + 2] & 0x0f);
				gps_data.longitude[4] = (pd[j + jj + 3] & 0x0f) << 4;
				break;
			case 2:
				gps_data.longitude[3] = ((pd[j + jj + 1] & 0x0f) << 4) + (pd[j + jj + 2] & 0x0f);
				gps_data.longitude[4] = 0;
				break;
			case 1:
				gps_data.longitude[3] = (pd[j + jj + 1] & 0x0f) << 4;
				gps_data.longitude[4] = 0;
				break;
			default:
				gps_data.longitude[3] = 0;
				gps_data.longitude[4] = 0;
				break;
		}
	}
}

//换算为以秒为单位0.1234’=0.1*60’’ + 0.02*60’’ + 0.003*60’’ + 0.0004*60’’;

//扩大1000=1*6000 + 2*600 + 3*60 + 4*6;

latitude_tmp = ((gps_data.latitude[0] >> 4) * 10 + (gps_data.latitude[0] & 0xf)) * 3600000;
latitude_tmp += (gps_data.latitude[1] >> 4) * 600000 + (gps_data.latitude[1] & 0xf) * 60000;
latitude_tmp += (gps_data.latitude[2] >> 4) * 6000 + (gps_data.latitude[2] & 0xf) * 600;
latitude_tmp += (gps_data.latitude[3] >> 4) * 60 + (gps_data.latitude[3] & 0xf) * 6;
longitude_tmp = ((gps_data.longitude[0] & 0xf) * 100 + (gps_data.longitude[1] >> 4) * 10 + (gps_data.longitude[1] & 0xf)) * 3600000;
longitude_tmp += (gps_data.longitude[2] >> 4) * 600000 + (gps_data.longitude[2] & 0xf) * 60000;
longitude_tmp += (gps_data.longitude[3] >> 4) * 6000 + (gps_data.longitude[3] & 0xf) * 600;
longitude_tmp += (gps_data.longitude[4] >> 4) * 60 + (gps_data.longitude[4] & 0xf) * 6;
longitude_tmp /= 64;
latitude_tmp /= 64;


Ø 速度

车辆速度不会大于255

speed_tmp = (gps_data.speed[0] >> 4) * 1000 + (gps_data.speed[0] & 0xf) * 100 + (gps_data.speed[1] >> 4) * 10 + (gps_data.speed[1] & 0xf);
speed_tmp *= 1852;						// 将速度knot转换成公里/小时
speed_tmp /= 10000;						// 缩小10000倍还原速度值

Ø 角度

角度可能大于255,需缩小才能单字节传送;

direct_tmp = (gps_data.angle[0] >> 4) * 1000 + (gps_data.angle[0] & 0xf) * 100 + (gps_data.angle[1] >> 4) * 10 + (gps_data.angle[1] & 0xf);
direct_tmp /= 16;						// 方向为原来方向/1.6


 

 


评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值