Chinaunix首页 | 论坛 | 博客
  • 博客访问: 933157
  • 博文数量: 70
  • 博客积分: 1741
  • 博客等级: 上尉
  • 技术积分: 2476
  • 用 户 组: 普通用户
  • 注册时间: 2009-07-05 14:46
个人简介

全志全系列芯片产品方案开发 A20/A33/A64/A40/A60/A83/A63/H3/H5/H6/H8

文章存档

2018年(1)

2012年(20)

2011年(49)

分类: 嵌入式

2011-06-26 16:41:38

单片机解析GPS数据非常简单,只要串口接收到一行字符串,传到解析函数里,再把解析到的字符串经过运算转成我们需要数据。

硬件平台:XC-GPS开发板+XC-STC单片机开发板

效果如下:


首先创建一个GPS数据结构体:
  1. typedef data struct{
  2.     double latitude; //经度
  3.     double longitude; //纬度
  4.     int latitude_Degree;    //
  5.     int        latitude_Cent;   //
  6.     int     latitude_Second; //
  7.     int longitude_Degree;    //
  8.     int        longitude_Cent;  //
  9.     int     longitude_Second; //
  10.     float     speed; //速度
  11.     float     direction; //航向
  12.     float     height; //海拔高度
  13.     int satellite;
  14.     U8     NS;
  15.     U8     EW;
  16.     DATE_TIME D;
  17. }GPS_INFO;
时间结构体:
  1. typedef struct{
  2.     int year;
  3.     int month;
  4.     int day;
  5.     int hour;
  6.     int minute;
  7.     int second;
  8. }DATE_TIME;

核心算法就是解析GPRMC数据,得到经纬度,日期时间,速度,航向:
  1. int GPS_RMC_Parse(char *line, GPS_INFO *GPS)
  2. {
  3.     U8 ch, status, tmp;
  4.     float lati_cent_tmp, lati_second_tmp;
  5.     float long_cent_tmp, long_second_tmp;
  6.     float speed_tmp;
  7.     char *buf = line;
  8.     ch = buf[5];
  9.     status = buf[GetComma(2, buf)];

  10.     if (ch == 'C') //如果第五个字符是C,($GPRMC)
  11.     {
  12.         if (status == 'A') //如果数据有效,则分析
  13.         {
  14.             GPS->NS = buf[GetComma(4, buf)];
  15.             GPS->EW = buf[GetComma(6, buf)];

  16.             GPS->latitude = Get_Double_Number(&buf[GetComma(3, buf)]);
  17.             GPS->longitude = Get_Double_Number(&buf[GetComma(5, buf)]);

  18.             GPS->latitude_Degree = (int)GPS->latitude / 100; //分离纬度
  19.             lati_cent_tmp = (GPS->latitude - GPS->latitude_Degree * 100);
  20.             GPS->latitude_Cent = (int)lati_cent_tmp;
  21.             lati_second_tmp = (lati_cent_tmp - GPS->latitude_Cent) * 60;
  22.             GPS->latitude_Second = (int)lati_second_tmp;

  23.             GPS->longitude_Degree = (int)GPS->longitude / 100;    //分离经度
  24.             long_cent_tmp = (GPS->longitude - GPS->longitude_Degree * 100);
  25.             GPS->longitude_Cent = (int)long_cent_tmp;
  26.             long_second_tmp = (long_cent_tmp - GPS->longitude_Cent) * 60;
  27.             GPS->longitude_Second = (int)long_second_tmp;

  28.             speed_tmp = Get_Float_Number(&buf[GetComma(7, buf)]); //速度(单位:海里/)
  29.             GPS->speed = speed_tmp * 1.85; //1海里=1.85公里
  30.             GPS->direction = Get_Float_Number(&buf[GetComma(8, buf)]); //角度            

  31.             GPS->D.hour = (buf[7] - '0') * 10 + (buf[8] - '0');        //时间
  32.             GPS->D.minute = (buf[9] - '0') * 10 + (buf[10] - '0');
  33.             GPS->D.second = (buf[11] - '0') * 10 + (buf[12] - '0');
  34.             tmp = GetComma(9, buf);
  35.             GPS->D.day = (buf[tmp + 0] - '0') * 10 + (buf[tmp + 1] - '0'); //日期
  36.             GPS->D.month = (buf[tmp + 2] - '0') * 10 + (buf[tmp + 3] - '0');
  37.             GPS->D.year = (buf[tmp + 4] - '0') * 10 + (buf[tmp + 5] - '0') + 2000;

  38.             UTC2BTC(&GPS->D);
  39.             
  40.             return 1;
  41.         }        
  42.     }
  43.     
  44.     return 0;
  45. }
line是串口接收的一行数据buf

GetComma函数作用是一行数据中第几个逗号后面那个字符在这行数据中的位置

Get_Double_Number函数作用是把给定字符串第一个逗号之前的字符转化成双精度型,在这里就是把代表经度和纬度的字符串转换成数字,同样的函数还有Get_Float_Number

UTC2BTC函数是将世界时间转换成北京时间(相差8小时)

在LCD显示程序中把GPS_INFO结构体的已经被赋值的变量显示到屏上相应的位置即可

还有一个GPGGA信息段可以提供海拔高度和卫星数量信息
  1. int GPS_GGA_Parse(char *line, GPS_INFO *GPS)
  2. {
  3.     U8 ch, status;
  4.     char *buf = line;
  5.     ch = buf[4];
  6.     status = buf[GetComma(2, buf)];

  7.     if (ch == 'G') //$GPGGA
  8.     {
  9.         if (status != ',')
  10.         {
  11.             GPS->height = Get_Float_Number(&buf[GetComma(9, buf)]);
  12.             GPS->satellite = Get_Int_Number(&buf[GetComma(7, buf)]);

  13.             return 1;
  14.         }
  15.     }
  16.     
  17.     return 0;
  18. }



阅读(23673) | 评论(5) | 转发(4) |
给主人留下些什么吧!~~

燚森有你2015-04-16 15:07:44

博主,可以把Get_Float_Number()函数原型 和 GetComma()原型贴出来吗?

2011-08-08 14:51:15

想问博主,你的这个开发平台售价好多?,另外想知道提供什么样的技术支持

swc1291102011-08-02 14:31:52

好啊  模块是一个问题  就应该多看看别人写的好模块

愚人陈2011-07-14 23:59:24