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

📄 handlegpsdata.c

📁 一个用来实现GPS数据接收和处理分析的程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/********************************************************************************************
//程序名称:		GPS数据处理模块程序
//版权说明:		GPS数据处理模块DEBUG版本
//版本号:			V1.0			
//功能:			控制GPS模块电源开关,从GPS模块缓冲区中读取数据,处理最小推荐帧格式数据,并以十六进制数据格式进行存放
//开发人:			谢忠铭
//开发时间:		
//修改者:			唐均
//修改时间			2008年7月9日
//修改简要说明:		1.进行GPS模块电源控制,2.修改读取GPS数据出现的丢包,读取不完整现象.3.使用回调机制,方便实现对不同数据帧类型处理.
//其他:			
  修改记录:


********************************************************************************************/
/**************************************头文件************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <termios.h>
#include <errno.h>
#include <string.h>

#include "HandleGpsData.h"
#include "io.h"
#include "ControlIo.h"
/*********************************************************************************************/

//#define DATA_PACKET_TEST
#define GPSDATA_MAIN   main

int nmea_fd = -1;
char ttyS0_Gps[] = {"/dev/ttyS3"};

GPS_DAT gpsdat;				//存储处理后的GPS16进制数据
GPS_DAT gpsdatt;			//处理GPS数据临时存储空间
GPS_NMEA_DAT *gps_nmea_dat;  //存放预处理数据

#ifdef DATA_PACKET_TEST
/*===========================数据包接收测试函数========================================*/
void Data_Packet_Test(char* str,int flag)
{
	FILE *fp1=NULL,*fp2=NULL;
	if(flag == 0)
	{
		fp1=fopen("alldata.log","a+");
		fprintf(fp1,"%s\n",str);
		fclose(fp1);
	}
	if(flag == 1)
	{
		fp2 = fopen("rmcdata.log","a+");
		fprintf(fp2,"%s\n",str);
		fclose(fp2);
	}
	return ;
} 
#endif
/*******************************************************************************************
//名称 :Dec2Hex
//功能: 十进制转换为十六制值
//输入参数:十进制整形或单字节字符型,存放十六进制整形数组
//输出参数: 无
//返回: 无
******************************************************************************************/
void Dec2Hex(int num,int temp[])
{
	//int temp[8];
	int i; 
	printf("the decimal number is %d\n",num);
	for(i=7;i>=0;i--)
	{
		if((temp[i]=num&0x0f)>9)
			temp[i] += ('A'-10);
		else
			temp[i] += '0';
		num = num >> 4;
	}
	printf("the hexadecimal number is",);
	for(i=0;i<8;i++)
		if('0' != temp[i])
			printf("%c",temp[i]);
	printf("\n");
}
/*====================================GPS处理段===========================================*/
/*******************************************************************************************
//名称 :ASC2Hex
//功能: 转换字符的ASCII码为十六制值
//输入参数: 单个字符
//输出参数: 输入字符的十六进制值
//返回: 返回十六进制值
******************************************************************************************/
unsigned char ASC2Hex(unsigned char dat)
{
	if(dat > '9')
		dat -= 0x37;
	else dat &= 0x0F;
	return(dat);
}
/*====================================GPS处理段===========================================*/
/*******************************************************************************************
//名称 :SetSerial_Port
//功能: 串口配置选项初始化
//输入参数: 1.串口配置选项各成员结构体termios,2.串口传输的波特率
//输出参数: 无
//返回: 无
******************************************************************************************/
void SetSerial_Port(struct termios *GPSDATAIO,int BaudRate)
{
	bzero(GPSDATAIO,sizeof(struct termios));  //清除IO口设置在
	/*配置串口参数*/
	GPSDATAIO->c_cflag = BaudRate|CS8|CLOCAL|CREAD;  //波特率|8个数据位|本地连接|接收全能
	GPSDATAIO->c_iflag = IGNPAR;             //忽略帧错误和奇偶检验错误
	GPSDATAIO->c_oflag = 0;						//输出控制模式,为0表示输出前不要变换		
	GPSDATAIO->c_lflag = 0;					//设置本地模式	//GPSDATAIO->c_cc[VINTR] = 0;   			//Ctrl-c
	GPSDATAIO->c_cc[VTIME] = 0;				//非 canonical 模式读时的延时,以十分之一秒为单位。  
	GPSDATAIO->c_cc[VMIN] = 0;				//非 canonical 模式读的最小字符数。
}
/*******************************************************************************************
//名称 :Open_UartPort
//功能: 打开串口对应的设备文件,以此把设备当作文件进行读写控制操作
//输入参数: 串口对应的设备文件名,此处为"/dev/ttys3"
//输出参数: 打开设备对应的文件描述符
//返回: 成功:返回设备描述文件符  失败:返回  -1
//描述:阻塞方式读写串口,采用fcntl函数,等待数据的读入
//函数中常量注释:O_RDONLY:以可读写方式打开设备,O_NOCTTY:使这个端口不成为系统对应的控制终端,
			设置该选项则系统的无法控制该进程,DEBUG时建议不设置该选项
**************************************************************************************/
int Open_UartPort( char* devname)
{
	int Nmea_fd;     //打开串口的文件描述符
	int Err;
	struct termios GPSTTYFD;
	Nmea_fd=open(devname,O_RDONLY|O_NOCTTY);//可读写及屏蔽键盘等控制   |O_NOCTTY
	if(Nmea_fd<0)
	{
		perror("Open Uart Port");
		return OPENSERIALPORTFAILURE;
	}
	SetSerial_Port(&GPSTTYFD,B9600);		//串口配置初始化
	Err=tcsetattr(Nmea_fd,TCSANOW,&GPSTTYFD);    //设置串口参数
	if(Err=-1&&Err==EINTR)
	{
		perror("can't set the attribution of the terminal");
		return (-1);
	}
	fcntl(Nmea_fd,F_SETFL,0);
	//if(Err==EBADF)
	//{
	//	return Err;   //非法的文件描述符
	//}
	//if(Err==EINTR)
	//{
	//	return Err;   //函数调用被信号中断
	//}
	//if(Err==EINVAL)
	//{
	//	return Err;   //参数termios中使用了非法值
	//}
	//if(Err==ENCTTY)
	//{
	//	return Err;  //非终端的文件描述符
	//}
	return Nmea_fd;
}
/*******************************************************************************************
//名称 :Verify_Gps_Data
//功能: 无奇偶校验字符串
//输入参数: 待校验的字符串
//输出参数: 校验结果
//返回: 成功:返回0,失败:返回 -1
//无奇偶校验方法:采用逐个字符异或,最终与校验码异或,如果为0则表明校验成功,否则校验失败.
******************************************************************************************/
int Verify_Gps_Data(char* sentence)
{
	int OKflag = 0,len;
	unsigned char *ptGPS;
	unsigned char ch,checksum = 0,chedat;
	
	if(*sentence != '$')		//判断校验数据帧第一个字符是否为NMEA协议的标志头'$'
	{
		return (-1);
	}
	len = strlen(sentence);
	len-= 4;
	if(len>100)
		len = 100;
	ptGPS = sentence + 1;
	do
	{
		ch = *ptGPS++;
		len--;
		if(ch=='*')
		{    /*求校验码十六进制值*/
			chedat = ASC2Hex(*ptGPS);
			ptGPS++;
			ch = ASC2Hex(*ptGPS);
			chedat<<=4;
			chedat|=ch;
			if(chedat!=checksum)//判断校验码是否成功
				return (-1);
			OKflag = 1;
			break;
		}
		checksum^=ch;    //循环相异或
	}while(len>0);
	if(OKflag == 0)
		return (-1);
	return SUCCESSVERIFYGPSDATA;// 返回校验成功标志
}
/*******************************************************************************************
//名称 : Handle_Gps_RMC
//功能: GPS数据中推荐最小数据类型处理,处理结果转换成十六进制值,放在结构体中
//输入参数: 处理的一帧RMC类型数据
//输出参数: RMC类型数据导航状态,是否为导航
//返回: 成功:返回1,导航 失败:返回0,不导航  
******************************************************************************************/
int Handle_Gps_RMC(char *sentence)
{
	int i, j = 0, count = 0,setflag = 0,length;
	char temp,tempdot;
	char *p;
	
	p = sentence;
	length = strlen(p);
	printf("%s\n",sentence);
	#ifdef DATA_PACKET_TEST
	Data_Packet_Test(sentence,1);
	#endif
	memset(&gpsdatt,0,sizeof(gpsdatt));  //清空临时存取GPS导航数据缓冲
	for (i = 0; i < length; ) 
	{
		temp = p[i++];
        if(temp == ',')    //遍历字符串,找出’,‘位置
        {
			count++;
		}
		else if(count<10)
		{
			switch (count) 
			{
			case 1:
				printf("========time========\n");
				printf("%d ",temp);
				temp &= 0x0F;
				temp = (temp << 3) + (temp << 1); //小时部分的十个与个位相加,相当于temp*10+(++temp)
				temp += (p[i++] & 0x0F);
				printf("%d ",temp);
				
				gpsdatt.Hour = (char)temp;
				gpsdatt.Hour &= 0xFF;      //转换为十六进制
				//handle time.minute ASCII->HEX data
				temp = p[i++];
				printf("%d ",temp);
				temp &= 0x0F;
				temp = (temp << 3) + (temp << 1);
				temp += (p[i++] & 0x0F);   //分钟部分的十个与个位相加,相当于temp*10+(++temp)
				printf("%x ",temp);
				gpsdatt.Min = temp;
				gpsdatt.Min &= 0xFF;		//转换为十六进制
				//handle time.second ASCII->HEX data
				temp = p[i++];
				printf("%d ",temp);
				temp &= 0x0F;
				temp = (temp << 3) + (temp << 1);
				temp += (p[i++] & 0x0F);    //秒钟部分的十个与个位相加,相当于temp*10+(++temp)
				printf("%d ",temp);
				//if(gpsdatta->Second == temp)
				//	temp++;
				gpsdatt.Sec = temp;
				gpsdatt.Sec &= 0xFF;
				printf("\n%x,%x,%x\n",gpsdatt.Hour,gpsdatt.Min,gpsdatt.Sec);
				break;
			case 2:
				if(temp == 'A')  	//‘A’为导航
				{
					gpsdatt.GpsValid = TRUE;
					gpsdatt.GpsValid &= 0xFF;
					setflag = 1;    //设置返回的导航状态 成功导航标志1
				}else if(temp == 'V')  //‘V’为不导航
				{
					gpsdatt.GpsValid = FALSE;
					gpsdatt.GpsValid &= 0xFF;
					setflag = 0;    //设置返回的导航状态, 不能导航标志0
					return 0;
				}else return(0);
				printf("%x\n",gpsdatt.GpsValid);
				break;
			case 3:
				printf("=====Latitue==========\n");
				j = 1;
				do
				{
					j++;
					tempdot = p[i + j];
					if(j > 8)
						break;
				}while(tempdot != '.');
				printf("%d ",tempdot);
				printf("%d ",temp);
				temp &= 0x0F;
				if(j > 2)
				{
					temp = (temp << 3) + (temp << 1);		//temp = temp *10
					temp += (p[i++] & 0x0F);
				}
				if(temp == 0)
					return(0);
				gpsdatt.Latitue[0] = temp;
				gpsdatt.Latitue[0] &= 0xFF;
				
				//处理纬度-分
				temp = p[i++];
				printf("%d ",temp);
				temp &= 0x0F;
				temp = (temp << 3) + (temp << 1);
				temp += (p[i++] & 0x0F);
				printf("%d ",temp);
				gpsdatt.Latitue[1] = temp;
				gpsdatt.Latitue[1] &= 0xFF;
	
				//处理纬度-分小数
				i++;
				temp = p[i++];
				printf("%d ",temp);
				temp &= 0x0F;
				temp = (temp << 3) + (temp << 1);
				temp += (p[i++] & 0x0F);
				printf("%d ",temp);
				//temp1 = temp * 100;		//高位数
				gpsdatt.Latitue[2] = temp;
				gpsdatt.Latitue[2] &= 0xFF;
				
				temp = p[i++];
				printf("%d ",temp);
				temp &= 0x0F;
				temp = (temp << 3) + (temp << 1);
				temp += (p[i++] & 0x0F);	//低位数
				printf("%d ",temp);
				//temp1 += temp;		
				gpsdatt.Latitue[3] = temp;
				gpsdatt.Latitue[3] &= 0xFF;
				//gpsdatta->Latitue_CD = temp1;
				printf("%x,%x,%x,%x\n",gpsdatt.Latitue[0],gpsdatt.Latitue[1], \
				gpsdatt.Latitue[2],gpsdatt.Latitue[3]);
				break;
			case 4:
				//处理北纬

⌨️ 快捷键说明

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