NMEA-0183 协议的校验和 计算方法 :
就是 将 “$” 和 “*” 之间的字符ASCII值 进行 异或 运算 得到的数值 以16进制格式 体现 的字符串 。
例如:"$GNGLL,2239.37849,N,11400.75600,E,123254.00,A,A*7F"。 校验和 “7F” 字符串 就是 整数0x7F
#include <stdio.h>
/**
*******************************************************************************
* @brief 十六进制格式字符串 转 十六进制格式整数 函数
* @param [in] *str 字符串指针
* @param [in] size 字符串个数
* @param [in] *result 转换结果缓存指针
* @return 0--转换成功; 1--数据不在范围内;
* @note
*******************************************************************************
*/
unsigned char AsciiToHex(char *str, unsigned char size, unsigned char *result)
{
unsigned char temp;
for(*result = 0; size; size--, str++)
{
if(('9' >= *str) && (*str >='0') ) temp = *str - '0';
else if(('F' >= *str) && (*str >='A') ) temp = *str - 'A' + 10;
else if(('f' >= *str) && (*str >='a') ) temp = *str - 'a' + 10;
else return 1; //数据不在范围内
*result |= temp<<((size-1)*4);
}
return 0; //转换成功
}
/**
*******************************************************************************
* @brief NMEA 数据帧校验 函数
* @param [in] *buf 校验数据帧指针
* @return 0--校验成功; 1--校验失败; 2--校验数据超长; 3--校验和错误 不是校验和
* @note
*******************************************************************************
*/
unsigned char NMEA_CheckSum(char *buf)
{
unsigned char i;
unsigned char chk, result;
for(chk=buf[1], i=2; (buf[i]!='*')&&(i<255); i++)
{
chk ^= buf[i];
}
if( AsciiToHex(&buf[i+1], 2, &result) ) return 3; //校验和错误 不是校验和
if(i>=255) return 2; //校验数据超长
if(chk != result) return 1; //校验失败
return 0; //校验成功
}
/**
*******************************************************************************
* @brief 主 函数
* @param [in] None
* @return None
* @note
*******************************************************************************
*/
int main(void)
{
char a[] = "$GNGLL,2239.37849,N,11400.75600,E,123254.00,A,A*7F";
unsigned char pos;
unsigned char* dx;
if( !NMEA_CheckSum(a) )printf("校验OK \n");
}
运行结果: