数据解析与位运算

本文详细介绍了一种从二进制文件中读取并解析GPS数据的方法,包括定位数据起始位置、解析Wi-Fi信息、提取GPS帧头、时间、经纬度及航向角等关键信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include"common.h"

int main()
{
	int num = 0;
	int fd = -1;
	int ret = -1;
	char buf[1024];
	unsigned char gps_buf[512];
	int count = 1;
	fd = open("./0.bin",O_RDONLY);
	if(fd < 0)
	{
		perror("open");
		return -1;
	}
	char *p =(char*)malloc(4096);
	ret = read(fd,p,4096);
	if(ret < 0)
	{
		perror("read");
		return -1;
	}
/*找出开始的位置*/
	while(*p)
	{
		if(*p=='+')
		{
			p=p+10;
			num += 10;
			break;
		}
		
		else
		{
			p++;
			num++;
		}
	
		if(num>=4096)return -1;
	}
/*解析出每个wifi*/
	while(*p)
	{
		int i = 0;
		bzero(buf,1024);
		if((*p++=='O')&&(*p++)=='K')
		{
			printf("进入GPS 。。。\n");
			break;
		}
		while(*(p++)!=',');
		while(1)
		{
			if(*p=='\r')
			{
				buf[i]='\0';
				printf("%d:%s\n",count,buf); 
				p=p+2;
				count++;
				break;	
			}		
			else 
			{
				buf[i]=*p;
				i++;				
				p++;
			}	
		}	
	}
	p=p+2;
	bzero(gps_buf,512);
	memcpy(gps_buf,p,512);

	/*提取帧头 4Byte*/
	int *h_num;
	int head;
	h_num = (int*)(gps_buf+0);
	head = *h_num;
	head = htonl(head);
	printf("head: %x\n",head);

	/*提取有效位 1Byte*/
	unsigned char*time_place_valid;
	time_place_valid = (unsigned char*)(gps_buf+4);
	printf("time_place_valid: %x\n",*time_place_valid);

	/*提取时间 6Byte*/
	 char *g_year,*g_month,*g_day,*g_hour,*g_min,*g_sec; 
	g_year = (unsigned char*)(gps_buf+5);
	g_month = (unsigned char*)(gps_buf+6);
	g_day = (unsigned char*)(gps_buf+7);
	g_hour = (unsigned char*)(gps_buf+8);
	g_min = (unsigned char*)(gps_buf+9);
	g_sec = (unsigned char*)(gps_buf+10);
	printf("%d/%d/%d-%d:%d:%d\n",*g_year,*g_month,*g_day,*g_hour,*g_min,*g_sec);

	/*提取经度 9Byte*/
	unsigned char *l_num;
		/*检验东西经 1Bit*/
	int num_j = 0x80;
	l_num = (unsigned char*)(gps_buf+11);
	unsigned char lo_j = (*l_num) & (num_j);//判断某一位的数值是多少,就取一个数,并把把该位值置为1,其余置为0,然后再与原数据进行与运算

		
		/*提取经度值*/
	unsigned char *l_num2 = (unsigned char*)(gps_buf+12);
	num_j = 0x7F;
	short  longitude_d = ( ((unsigned short)(*l_num) << 8) & ((unsigned short)(num_j)<<8) | (unsigned short)(*l_num2) ); //经度(度) 15Bit
	unsigned int  longitude2 = (((unsigned char)*(gps_buf+13))<<16) |  (((unsigned char)*(gps_buf+14))<<8) |  ((unsigned int)*(gps_buf+15)) ;
	unsigned char l_buf[20];
	bzero(l_buf,20);
	sprintf(l_buf,"%d.%d", longitude2/100000, longitude2%100000);
	float longitude_m = atof(l_buf);  //经度(分) 3Byte
	float l ;
	l= longitude_d + longitude_m/60;
	printf("============= l =%f\n",l);

	if(lo_j == 0x80)
	{
		printf("西经 %d 度 %f分\n", longitude_d, longitude_m);
	}
	
	else if(lo_j == 0)
	{
		printf("东经 %d 度 %f 分\n" ,longitude_d,longitude_m);
	}
	
	else 
	{
		printf("error!!!\n");
		return -1;
	}

	/*提取纬度 4Byte*/
	l_num = (unsigned char*)(gps_buf+16);
	num_j = 0x80;
	unsigned char la_j = (*l_num) & (num_j);
	unsigned char latitude_d = (*l_num) & (0x7F);
	unsigned int  latitude2 = (((unsigned int)(*(gps_buf+17)))<<16) |  (((unsigned int)(*(gps_buf+18)))<<8) |  ((unsigned int)(*(gps_buf+19))) ;
	
	sprintf(l_buf,"%d.%d", latitude2/100000, latitude2%100000);
	float latitude_m = atof(l_buf);
	if(la_j == 0x80)
	{
		printf("北纬 %d 度 %f分\n",latitude_d,latitude_m);
	}
	
	else if(la_j == 0)
	{
		printf("南纬 %d 度 %f分\n",latitude_d,latitude_m);
	}
	
	else 
	{
		printf("error!!! %x \n",la_j);
		return -1;
	}

	/*航向角有效判断*/
	unsigned char *angle_info_valid;
	angle_info_valid = (unsigned char*)(gps_buf+20);
	printf("航向角有效: %d\n",*angle_info_valid);

	unsigned short *angle = (unsigned short*)(gps_buf+21);
	int angle2 = *angle;
	unsigned int a = htons(angle2);
	unsigned char buf2[10];
	sprintf(buf2,"%d.%d",a/100,a%100);
	float angle_info = atof(buf2); 
	printf("航向角:%0.2f\n",angle_info);
	
	/*unsigned int *tail=0;
	
printf("----------%x\n",(unsigned int)(*(gps_buf+26)));
	tail = (((unsigned int)(*(gps_buf+23)))<<24) |  (((unsigned int)(*(gps_buf+24)))<<16) |  (((unsigned int)(*(gps_buf+25)))<<8) |  ((unsigned int)(*(gps_buf+26)));*/
	int *t_num;
	int tail;
	t_num = (int*)(gps_buf+23);
	tail = *t_num;
	tail = htonl(tail);
	//printf("head: %x\n",head);

	printf("tail:   %x\n",tail);	

}

部分原始数据实例:(十六进制)

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值