单片机解析GPS数据非常简单,只要串口接收到一行字符串,传到解析函数里,再把解析到的字符串经过运算转成我们需要数据。
硬件平台:XC-GPS开发板+XC-STC单片机开发板
效果如下:
首先创建一个GPS数据结构体:
- typedef data struct{
-
double latitude; //经度
-
double longitude; //纬度
-
int latitude_Degree; //度
-
int latitude_Cent; //分
-
int latitude_Second; //秒
-
int longitude_Degree; //度
-
int longitude_Cent; //分
-
int longitude_Second; //秒
-
float speed; //速度
-
float direction; //航向
-
float height; //海拔高度
-
int satellite;
-
U8 NS;
-
U8 EW;
-
DATE_TIME D;
-
}GPS_INFO;
时间结构体:
- typedef struct{
-
int year;
-
int month;
-
int day;
-
int hour;
-
int minute;
-
int second;
-
}DATE_TIME;
核心算法就是解析GPRMC数据,得到经纬度,日期时间,速度,航向:
- int GPS_RMC_Parse(char *line, GPS_INFO *GPS)
-
{
-
U8 ch, status, tmp;
-
float lati_cent_tmp, lati_second_tmp;
-
float long_cent_tmp, long_second_tmp;
-
float speed_tmp;
-
char *buf = line;
-
ch = buf[5];
-
status = buf[GetComma(2, buf)];
-
-
if (ch == 'C') //如果第五个字符是C,($GPRMC)
-
{
-
if (status == 'A') //如果数据有效,则分析
-
{
-
GPS->NS = buf[GetComma(4, buf)];
-
GPS->EW = buf[GetComma(6, buf)];
-
-
GPS->latitude = Get_Double_Number(&buf[GetComma(3, buf)]);
-
GPS->longitude = Get_Double_Number(&buf[GetComma(5, buf)]);
-
-
GPS->latitude_Degree = (int)GPS->latitude / 100; //分离纬度
-
lati_cent_tmp = (GPS->latitude - GPS->latitude_Degree * 100);
-
GPS->latitude_Cent = (int)lati_cent_tmp;
-
lati_second_tmp = (lati_cent_tmp - GPS->latitude_Cent) * 60;
-
GPS->latitude_Second = (int)lati_second_tmp;
-
-
GPS->longitude_Degree = (int)GPS->longitude / 100; //分离经度
-
long_cent_tmp = (GPS->longitude - GPS->longitude_Degree * 100);
-
GPS->longitude_Cent = (int)long_cent_tmp;
-
long_second_tmp = (long_cent_tmp - GPS->longitude_Cent) * 60;
-
GPS->longitude_Second = (int)long_second_tmp;
-
-
speed_tmp = Get_Float_Number(&buf[GetComma(7, buf)]); //速度(单位:海里/时)
-
GPS->speed = speed_tmp * 1.85; //1海里=1.85公里
-
GPS->direction = Get_Float_Number(&buf[GetComma(8, buf)]); //角度
-
-
GPS->D.hour = (buf[7] - '0') * 10 + (buf[8] - '0'); //时间
-
GPS->D.minute = (buf[9] - '0') * 10 + (buf[10] - '0');
-
GPS->D.second = (buf[11] - '0') * 10 + (buf[12] - '0');
-
tmp = GetComma(9, buf);
-
GPS->D.day = (buf[tmp + 0] - '0') * 10 + (buf[tmp + 1] - '0'); //日期
-
GPS->D.month = (buf[tmp + 2] - '0') * 10 + (buf[tmp + 3] - '0');
-
GPS->D.year = (buf[tmp + 4] - '0') * 10 + (buf[tmp + 5] - '0') + 2000;
-
-
UTC2BTC(&GPS->D);
-
-
return 1;
-
}
-
}
-
-
return 0;
-
}
line是串口接收的一行数据buf
GetComma函数作用是一行数据中第几个逗号后面那个字符在这行数据中的位置
Get_Double_Number函数作用是把给定字符串第一个逗号之前的字符转化成双精度型,在这里就是把代表经度和纬度的字符串转换成数字,同样的函数还有Get_Float_Number
UTC2BTC函数是将世界时间转换成北京时间(相差8小时)
在LCD显示程序中把GPS_INFO结构体的已经被赋值的变量显示到屏上相应的位置即可
还有一个GPGGA信息段可以提供海拔高度和卫星数量信息
- int GPS_GGA_Parse(char *line, GPS_INFO *GPS)
-
{
-
U8 ch, status;
-
char *buf = line;
-
ch = buf[4];
-
status = buf[GetComma(2, buf)];
-
-
if (ch == 'G') //$GPGGA
-
{
-
if (status != ',')
-
{
-
GPS->height = Get_Float_Number(&buf[GetComma(9, buf)]);
-
GPS->satellite = Get_Int_Number(&buf[GetComma(7, buf)]);
-
-
return 1;
-
}
-
}
-
-
return 0;
-
}
阅读(2101) | 评论(0) | 转发(0) |