⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 task_gps.c

📁 GPS相关子程序
💻 C
字号:

#include "main.h"




/*************************************************
函数功能:将毫秒值表示的经纬度转换为度分秒形式
输入参数:bflag: 0表示纬度,1表示经度
          *duString:度分秒形式表示的经纬度
          value:毫秒值表示的经纬度
返回值:无
**************************************************/
void pubhMiaotoDu(u8 *duString,u32 value,u8 bflag)
{
	char tmp[20];
	int i = 0;
	int j = 0;
	int k = 0;

	i = value / 3600000;//度取整
	int2BcdAscStr(tmp, i, 4);

	if (bflag == 0)//9  
	{
		strcpy((char*)duString, tmp+2);//纬度
	}
	else
	{
		strcpy((char*)duString, tmp+1);//经度
	}

	value %= 3600000;
	j = value / 60000;//分取整

	int2BcdAscStr(tmp, j, 4);
	strcat( (char*)duString, tmp + 2 );

	value %= 60000;
	k = value / 6;//小数部分
	tmp[0] = '.';
	int2BcdAscStr(tmp+1, k, 4);

	strcat( (char*)duString , tmp );	
}



/**************************************************************
函数功能:度分秒表示的经度纬度值转成毫秒值
输入参数:*data:度分秒表示的经度纬度值
返回值:返回毫秒值表示的经纬度值
**************************************************************/
long pubDutohMiao( char *data )
{
	char tmp[10];
	int i;
	unsigned long j;

	j = strlen( data );
	if ( j == 9 )//纬度
	{
		memcpy(tmp,data,2);
		i = 2;
	}
	else //if (dataLen==10)经度
	{
		memcpy(tmp,data,3);
		i = 3;
	}

	tmp[i] = '\0';
	j = atoi( tmp ) * 3600000;//60 * 60 * 1000

	memcpy( tmp, data + i, 2 );
	tmp[2] = '\0';
	j += ( atoi( tmp ) * 60000 );

	i += 3;//去掉逗号
	memcpy(tmp,data+i,4);
	tmp[4] = '\0';
	j += ( atoi( tmp ) * 6 ); // (1/10000)*60000

	return j;
}




/****************************************************
函数功能:对串口接收到的GPS数据进行处理
输入参数:*Data:串口接收到的GPS数据
          *g_Gps_Data:用来保存接收到数据的结构体
返回值:无
****************************************************/
void GPS_Data_Deal(u8 *Data,StuGpsData* g_Gps_Data)
{
	u8 len,i,tt,sum=0;
	u8 *ptr=NULL;
	u8 buf[MSGSIZE_GPS];
	
	len=strlen(Data);
	ptr = searchStr(Data,"$GPRMC",len);
	if(!ptr)//数据不对
	{
		return;
	}
	memcpy(buf, ptr, 80);
	if(buf[0]=='$')
	{
		for( i = 1; i < len; i++ )//0为$GPRMC,
		{
			if (buf[i] == '*' )//取得后面两位的校验和
			{
				tt = hexAscStr2Byte(buf + i + 1 );
				break;
			}
			else
			{
				sum^=buf[i];
			}
		}
		if(i < 30)
		{//数据不全
			return;
		}
		if ( (buf[i] == '*') && (tt == sum) )
		{
			gpsParseFrame(buf,g_Gps_Data);
		}	
	}
	dly20ms(1);	
}

//距离 = 速度 × 时间
//速度 = 速度(海里/小时)* 1.85(to公里) * 1000(米)
//时间(1秒) = 1/3600(小时);
//故常数为 (1.852*1000)/3600 = 0.5144
void gpsParseFrame(u8 *Data, StuGpsData* Gps_Data )
{
	int i = 0;
	int k = 0;
	int j = 0;
	int iNo = 0;
	u8 t = 0;
  u8 nArrayLen;

	u16 fSpeed = 0;
	u32 iPos = 0;

	char cTmp[16];
	char gSpeed[5];

  t =t;
	memset(gSpeed, 0, 5);
  nArrayLen=strlen(Data);

	//GPRMC,090629.487,A,2303.0600,N,11228.2600,E,11.2,159.62,211105,,*01
	j = 0;
	for(i=2; i<nArrayLen; i++)//0为$GPRMC,
	{
		if (Data[i] == ',')
		{
			iNo ++;
			switch( iNo )
			{				
			case 1://head
				break;
			case 2://1 time  hhmmss.sss
				{
					Gps_Data->bHour = bcdAscStr2Byte((u8*)cTmp);
					Gps_Data->bMin = bcdAscStr2Byte((u8*)cTmp+2);
					Gps_Data->bSec  = bcdAscStr2Byte((u8*)cTmp+4);
				}
				break;
			case 3://34 A or V
				{
					if ( cTmp[0] == 'A' )
					{
						Gps_Data->bValid = 1;
					}
					else 
					{
						Gps_Data->bValid = 0;
					}
				}
				break;
			case 4://13 wd
				{
					j = 0;
					cTmp[9] = '\0';
					iPos = pubDutohMiao(cTmp);
					if(iPos != 0)
					{
						Gps_Data->iLati = iPos;

					}

				}
				break;
			case 5://21 N or S
				{	
					if ( cTmp[0] == 'S' )
					{
						Gps_Data->bLatifg = 1;
					}
					else
					{
						Gps_Data->bLatifg = 0;
					}
				}
				break;
			case 6://22 jd
				{	
					j = 0;
					cTmp[10] = '\0';
					iPos = pubDutohMiao(cTmp);
					if(iPos != 0)
					{
						Gps_Data->iLongi = iPos;

					}
				}
				break;
			case 7://31   E or W
				{
					if ( cTmp[0] == 'W' )
					{
						Gps_Data->bLongfg = 1;
					}
					else
					{
						Gps_Data->bLongfg = 0;
					}
				}
				break;
			case 8://35   speed,
				//GPRMC,090629.487,A,2303.0600,N,11228.2600,E,11.2,159.62,211105,,*01
				{
					for(k=0; k<j; k++)
					{
						if (((cTmp[k]<'0') || (cTmp[k]>'9')) && (cTmp[k] != '.'))
						{
							k = j;
							break;	
						}
						if (cTmp[k]=='.')
						{
							break;
						}
					}
					if (k != j )
					{
						if (k==0)
						{
							gSpeed[0]='0';gSpeed[1]='0';gSpeed[2]='0';gSpeed[3]=cTmp[1];
						}
						else if (k==1)
						{
							gSpeed[0]='0';gSpeed[1]='0';gSpeed[2]=cTmp[0];gSpeed[3]=cTmp[2];
						}
						else if (k==2)
						{
							gSpeed[0]='0';gSpeed[1]=cTmp[0];gSpeed[2]=cTmp[1];gSpeed[3]=cTmp[3];
						}
						else if (k==3)
						{
							gSpeed[0] = cTmp[0];gSpeed[1]=cTmp[1];gSpeed[2]=cTmp[2];gSpeed[3]=cTmp[4];
						}
						t = cTmp[k+2];
					}
					else
					{
						break;
					}
					gSpeed[4] = '\0';

					fSpeed = atoi(gSpeed);//0.1海里/小时
					Gps_Data->sSpeed = fSpeed;//单位0.1海里/小时
				}		
				break;
			case 9://32   dir
				{//
					cTmp[j] = '\0';
					Gps_Data->udirect = atoi(cTmp);
				}
				break;
			case 10://7  date
				{
					Gps_Data->bYear = bcdAscStr2Byte((u8*)cTmp+4);
					Gps_Data->bMon = bcdAscStr2Byte((u8*)cTmp+2);
					Gps_Data->bDay = bcdAscStr2Byte((u8*)cTmp);
				}
				break;
			}
			memset(cTmp, '0',16);
			j = 0;
		}
		else
		{
			cTmp[j++]=Data[i];	
		}
	}	
}



/***********************************************************************************
函数名称:u8 hexAscStr2Byte(uc8 *str)
函数功能:将两位ASC码表示的16进制数合并为一字节数
输入参数:str--ASC码串
返回值:无
返回值 :转换后的数
调用函数:无
创建人 :
创建时间:2004.10.19
修改记录:
其它说明:例:0x33 0x41   -->  0x3A
***********************************************************************************/
u8 hexAscStr2Byte(uc8 *str)
{
	u8 bValue = 0;

	bValue = (asc2HexNum(str[0])<<4) + asc2HexNum(str[1]);

	return bValue;
}


/***********************************************************************************
函数名称:u8 bcdAscStr2Byte(uc8 *str)
函数功能:将两位BCD ASC码表示的数转换为一整型数
输入参数:str--BCD ASC码串
返回值:无
返回值 :转换后的数
调用函数:无
创建人 :
创建时间:2004.10.19
修改记录:
其它说明:0x33 0x35   -->  0x23 (35)
***********************************************************************************/
u8 bcdAscStr2Byte(uc8 *str)
{
	u8 bValue = 0;

	bValue = asc2HexNum( str[0] ) * 10 + asc2HexNum( str[1] );

	return bValue;
}



/***********************************************************************************
函数名称:u8 asc2HexNum( char key )
函数功能:将一位ASC码转为一位十六进制数
输入参数:key--ASC码值('0'~'9','A'~'F','a'~'f')
返回值:无
返回值 :转换结果
调用函数:无
创建人 :
创建时间:2004.10.19
修改记录:
其它说明:例:'0'--0     'A'--A(10)
***********************************************************************************/
u8 asc2HexNum( char key )
{
	u8 iRet = 0;

	if ( ( key >= '0' ) && ( key <= '9' ) )
	{
		iRet = key - '0';
	}
	else
	{
		if ( ( key >= 'A' ) && ( key <= 'F' ) )
		{
			iRet = key - 55;
		}
		else
		{
			if ( ( key >= 'a' ) && ( key <= 'f' ) )
			{
				iRet = key - 87;
			}
			else
			{
				iRet = 0;
			}
		}
	}
	return iRet;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -