基于C语言的NMEA-0183解析程序(二)

用户定义数据类型

#ifndef _TYPE_H_
#define _TYPE_H_

typedef signed char int8_t;
typedef signed short int16_t;
typedef signed int int32_t;
typedef unsigned char uint8_t;
typedef unsigned short uint16_t;
typedef unsigned int uint32_t;

typedef int8_t s8;
typedef int16_t s16;
typedef int32_t s32;
typedef uint8_t u8;
typedef uint16_t u16;
typedef uint32_t u32;

typedef struct NMEA_MSG
{
    struct UTC/*utc时间日期*/
    {
        int year;
        int month;
        int date;
        int hour;
        int mint;
        int sec;
    }utc;
    float speed;/*地面速率*/
    float latitude;/*纬度*/
    float longitude;/*经度*/
    float altitude;/*海拔高度*/
    float pdop;/*综合位置精度因子*/
    float hdop;/*水平精度因子*/
    float vdop;/*垂直精度因子*/
    char nshemi;/*南北纬*/
    char ewhemi;/*东西经*/
    char avhemi;/*定位状态//A有效定位、V无效定位*/
	char pattern;/*定位模式指示//A自主定位、D差分、E估算、N数据无效*/
    char mode;/*模式//M手动、A自动*/
	int mntude;/*磁北航向角度*/
	int entude;/*地北航向角度*/
    int svnum;/*可见卫星数//至多12颗*/
    int gpssta;/*GPS状态//0未定位、1非差分定位、2差分定位*/
    int posslnum;/*定位卫星数目*/   
    int fixmode;/*定位类型//1未定位、2D定位、3D定位*/
    int possl[32];/*定位卫星编号*/
    struct SLMSG/*定位卫星信息//卫星编号、卫星仰角、卫星方位角、信号强度*/
    {
        int num;
        int eledeg;
        int azideg;
        int sn;
    }slmsg[32];
}Nmea_msg;

#endif // _TYPE_H_

 用户定义的基本操作函数

#ifndef _OPERATION_H_
#define _OPERATION_H_

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<ctype.h>

#include"Type.h"
/******************************************************************************
 *  Function    -  Power calculation
 *
 *  Purpose     -  十进制转换倍率
 *
 *  Description -  计算m的n次方
 *
 * modification history
 * ----------------------------------------
 * v1.0  , 2018-12-12,  LynxChang  written
 * ----------------------------------------
 ******************************************************************************/
u32 NMEA_Pow(u8 m,u8 n)
{
    u32 result=1;
    while(n--){result*=m;}
    return result;
}

/******************************************************************************
 *  Function    -  Relative address offset
 *
 *  Purpose     -  计算第cx个逗号的相对地址偏移量
 *
 *  Description -  buf为字段的起始地址
 *
 * modification history
 * ----------------------------------------
 * v1.0  , 2018-12-12,  LynxChang  written
 * ----------------------------------------
 ******************************************************************************/
u8 NMEA_Comma_Pos(u8 *buf,u8 cx)
{
    u8 *p=buf;
    while(cx)
    {
        if(*buf=='*'||*buf<' '||*buf>'z')/*排除*和非法字符*/
        {
            return 0XFF;
        }
        if(*buf==','){cx--;}
        buf++;
    }
    return buf-p;/*相对地址偏移量*/
}
/******************************************************************************
 *  Function    -  Relative address offset
 *
 *  Purpose     -  计算每个语句结束符*的相对地址偏移量
 *
 *  Description -  buf为字段的起始地址
 *
 * modification history
 * ----------------------------------------
 * v1.0  , 2018-12-26,  LynxChang  written
 * ----------------------------------------
 ******************************************************************************/
u8 NMEA_End_Pos(u8 *buf)
{
	u8 *p = buf;
	while (*buf != '\n')
	{
		if (*buf<' ' || *buf>'z')/*排除非法字符*/
		{
			return 0XFF;
		}
		buf++;
	}
	return buf-p;/*相对地址偏移量*/
}

/******************************************************************************
 *  Function    -  Numeric character to digit
 *
 *  Purpose     -  数字字符转数字
 *
 *  Description -  buf为数字起始地址
 *
 * modification history
 * ----------------------------------------
 * v1.0  , 2018-12-12,  LynxChang  written
 * ----------------------------------------
 ******************************************************************************/
int NMEA_Str2num(u8 *buf)
{
    u8 *p=buf;/*buf为数字起始地址*/
    u8 i,j,mask=0;/*mask作为负数号与小数点的验证标志*/
    u8 ilen=0,flen=0;/*整数长和小数长*/
    u32 ires=0,fres=0;/*整数和小数*/
    int res;
    while((*p!=',')&&(*p!='*')&&(*p!=' '))
    {
		/*if(*p=='-'){mask|=0x02;p++;}*//*进行按位或,mask=0x02是负数*/
        if(*p=='.'){mask|=0x01;p++;}/*小数点*/
        else if(*p>'9'||(*p<'0'))
        {
            ilen = 0;
            flen = 0;
            break;
        }
        if(mask&0x01){flen++;p++;}/*计数小数的位数*/
        else{ilen++;p++;}/*起始检测存在数字*/
    }
	/*if(mask&0x02){flen++;}*//*负数符号位*/
    for(i=0;i<ilen;i++)
    {
        ires+=NMEA_Pow(10,ilen-1-i)*(buf[i]-'0');/*buf为数字起始地址*/
    }
    if(flen>6){flen=6;}/*限定6位小数*/
    for(j=0;j<flen;j++)
    {
        fres+=NMEA_Pow(10,flen-1-j)*(buf[ilen+1+j]-'0');/*加多1位小数点偏移量*/
    }
    res = ires*NMEA_Pow(10,flen)+fres;
    /*if(mask&0x02)res=-res;*//*负数的情况*/
    return res;
}

/******************************************************************************
 *  Function    -  Search comparison string
 *
 *  Purpose     -  搜索对比s1与s2字符串前n位
 *
 *  Description -  搜索对比s1与s2字符串前n位
 *                 相同则返回s2在s1中出现的首地址
 *                 不同则返回NULL
 *
 * modification history
 * ----------------------------------------
 * v1.0  , 2018-12-25,  LynxChang  written
 * ----------------------------------------
 ******************************************************************************/
char *strnstr(char *s1, const char *s2, int pos)
{
	int len1, len2;
	len1 = strlen(s1);
	len2 = strlen(s2);
	if (!len2)
		return (char *)s1;
	pos = (pos > len1) ? len1 : pos;
	while (pos > len2)
	{
		pos--;
	}
	if (!memcmp(s1, s2, pos))
		return (char *)s1;
	else
		return NULL;
}

/******************************************************************************
 *  Function    -  character to hex to integer
 *
 *  Purpose     -  字符转十六进制转整型
 *
 *  Description -  字符转整型
 *
 * modification history
 * ----------------------------------------
 * v1.0  , 2019-01-03,  LynxChang  written
 * ----------------------------------------
 ******************************************************************************/
int NMEA_Str2hex2num(char *tail)
{
	int digit, step, value;
	int num = 0;
	digit = strlen(tail);
    if(digit > 3)
    {
        digit = 2;
    }
	for (step = 0; step < digit; step++)
	{
		switch (tail[step])
		{
		case 'A':value = 10; break;
		case 'B':value = 11; break;
		case 'C':value = 12; break;
		case 'D':value = 13; break;
		case 'E':value = 14; break;
		case 'F':value = 15; break;
		default :value = tail[step] - '0'; break;
		}
		num = num + value * NMEA_Pow(16, (digit - step - 1));
	}
	return num;
}

/******************************************************************************
 *  Function    -  NMEA Check bit calculation check
 *
 *  Purpose     -  NMEA校验位计算检验
 *
 *  Description -  按位异或计算'$'至'*'之间的字符
 *
 * modification history
 * ----------------------------------------
 * v1.0  , 2019-01-03,  LynxChang  written
 * ----------------------------------------
 ******************************************************************************/
int NMEA_Checkout(char str[256])
{
	int i, result, value, avail;
	char *tail;

	tail = strstr(str, "*") + 1;
	value = NMEA_Str2hex2num(tail);

	for (result = str[1], i = 2; str[i] != '*'; i++)
	{
		result ^= str[i];
	}
	if (result == value)
		avail = 1;
	else
		avail = 0;

	return avail;
}

#endif // _OPERATION_H_

猜你喜欢

转载自blog.csdn.net/Dark_knights/article/details/86501876