Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1829300
  • 博文数量: 286
  • 博客积分: 3713
  • 博客等级: 少校
  • 技术积分: 2275
  • 用 户 组: 普通用户
  • 注册时间: 2012-01-11 09:47
个人简介

http://blog.chinaunix.net/uid/16979052.html

文章分类

全部博文(286)

文章存档

2018年(1)

2017年(16)

2016年(9)

2015年(17)

2014年(15)

2013年(112)

2012年(116)

分类:

2012-10-09 17:10:14

原文地址:linux下串口gps应用 作者:jsxthncn

linux串口gps使用总结
 
一、Gps数据格式标准(nmea0183)

这次只要获取经纬度信息,所有主要针对下面2个Gps命令
(1)位置信息(GGA)
 $GPGGA、<1>、<2>、<3>、<4>、<5>、<6>、<7>、<8>、<9>、M, <11>、<12>*hh
    <1>UTC时间,hh mm ss格式(定位它的)
    <2>经度dd mm mmmm 格式(非0)
    <3>经度方向 N或S
    <4>纬度ddd mm mmmm 格式(非0)
    <5>纬度方向E或W
    <6>GPS状态批示0—未定位 1—无差分定位信息 2—带差分定位信息
    <7>使用卫星号(00~08)
    <8>精度百分比
    <9>海平面高度
    <10>大地随球面相对海平面的高度
    <11>差分GPS信息
    <12>差分站ID号 0000-123
   
(2)最简特性(RMC)
 $GPRMC、<1>、<2>、<3>、<4>、<5>、<6>、<7>、<8>、<9>、<10>、<11>、*hh
    <1>定位时UTC时间hhmmss 格式
    <2>状态A=定位V=导航
    <3>经度ddmm.mmm 格式
    <4>经度方向N 或S
    <5>纬度dddmm.mmmm
    <6>纬度方向E或W
    <7>速率
    <8>方位敬爱(二维方向指向,相当于二维罗盘)
    <9>当前UTC日期ddmmyy 格式
    <10>太阳方位
    <11>太阳方向
   
二、nmealib库的使用
(1) 获取nmealib源码,并交叉编译成.so文件
nmealib 最新版本为0.53,可在下载获取到
获取源码后,修改源码结构如下:
a. 在源码目录新建include目录,将源码中所有.h文件移到该include目录中,
b. 编写Makefile文件,文件内容如下:

  1. # 制作的目标文件名libnmeagps.so
  2. TARGET = libnmeagps.so        

  3. # 包含所有头文件
  4. INCLUDE_FILE = context.h generate.h parse.h parser.h gtime.h
  5. INCLUDE_FILE += tok.h units.h gmath.h nmea.h sentence.h info.h generator.h config.h

  6. # 设置交叉编译工具
  7. COMPILER_PATH = arm-linux-

  8. CC = $(COMPILER_PATH)gcc
  9. CXX = $(COMPILER_PATH)g++
  10. LD = $(COMPILER_PATH)ld
  11. AR = $(COMPILER_PATH)ar

  12. LIBRARY = ./lib/

  13. INCLUDE_DIR = ./include/

  14. FLAGS = -Wall -O3 -s -I. -I$(INCLUDE_DIR)

  15. ifdef S3C2440
  16. FLAGS += -DPLAT_S3C2440
  17. else ifdef TI6446
  18. FLAGS += -DPLAT_TI6446
  19. else
  20. endif

  21. OBJS = $(patsubst %.c, %.o, $(wildcard *.c))

  22. %.o:%.c
  23.     @$(CC) -c $(FLAGS) $< -o $@

  24. all:$(OBJS)
  25.     @$(CC) -shared -Wall -fPIC -s $(OBJS) -o $(TARGET)

  26.     @cp $(TARGET) $(LIBRARY) 1>/dev/null
  27.     @cp $(INCLUDE_FILE) $(INCLUDE_DIR) 1>/dev/nul
  28.     
  29. update:
  30.     @cp -a $(INCLUDE_FILE) $(INCLUDE_DIR) 1>/dev/null

  31. clean:
  32.     rm $(TARGET) *.o -f
执行make命令,编译生成动态库文件libnmeagps.so
(2) 移植nmealib库到项目中
在项目源码目录中新建nmea_gps目录,将(1)中编译生成的libnmeagps.so和所有头文件拷贝到nmea_gps
目录中,在需要应用库借口的代码中增加相应头文件的声明即可。
项目Makefile增加下面内容:
NMEA_LIB=-L./nmea_gps/ -lnmeagps
$(CXX) -o $@  $^  $(NMEA_LIB)
(3) 测试
  1. /* nmea_lib测试程序 */
  2. void trace(const char *str, int str_size)
  3. {
  4.     printf("Trace: ");
  5.     write(1, str, str_size);
  6.     printf("\n");
  7. }
  8. void error(const char *str, int str_size)
  9. {
  10.     printf("Error: ");
  11.     write(1, str, str_size);
  12.     printf("\n");
  13. }

  14. int main()
  15. {
  16.     nmeaINFO info;
  17.     nmeaPARSER parser;
  18.     FILE *file;
  19.     char buff[2048];
  20.     int size, it = 0;
  21.     nmeaPOS dpos;

  22.     file = fopen("gpslog.txt", "rb");

  23.     if(!file)
  24.         return -1;

  25.     nmea_property()->trace_func = &trace;
  26.     nmea_property()->error_func = &error;

  27.     nmea_zero_INFO(&info);
  28.     nmea_parser_init(&parser);

  29.     /*
  30.     while(1)
  31.     {
  32.     */

  33.     while(!feof(file))
  34.     {
  35.         size = (int)fread(&buff[0], 1, 100, file);

  36.         nmea_parse(&parser, &buff[0], size, &info);

  37.         nmea_info2pos(&info, &dpos);

  38.         /* 获取 lat经度,lon纬度,sig信号指标,fix操作模式 */
  39.         printf("%03d, Lat: %f, Lon: %f, Sig: %d, Fix: %d\n", it++, info.lat, info.lon, info.sig, info.fix);
  40.     }

  41.     fseek(file, 0, SEEK_SET);

  42.     /*
  43.     }
  44.     */

  45.     nmea_parser_destroy(&parser);
  46.     fclose(file);

  47.     return 0;
  48. }
三、应用
1. 打开串口设备
hGpshandle = open("/dev/ttyS2", O_RDWR);
2. 设置串口波特率
set_serial_param(hGpshandle, 9600, 8, 1, 'n', 0);
3. 循环从串口读取数据,数据大小1024kb
readlen = read(hGpshandle, tmp_buf, 1500);
4. 数据取满,解析gps数据
pThis->DoParserGpsData(pArg);
5. 从解析结果判断gps信号质量
/* 0 = Invalid; 1 = Fix; 2 = Differential, 3 = Sensitive */
 if(info.sig == GPS_SIG_OK)
6. 经纬度数据单位转换
/* 经纬度转换为位置点 */
  nmea_info2pos(&info, &pos[it]);
7. gps校时
pThis->DoCheckTimeByGps(info);
8. 计算前后2个gps坐标点之间距离
dist = nmea_distance(&pos[it - 1], &pos[it]);
9. 将gps坐标信息,距离写入记录文件
pThis->DoWriteGpsInfoToFile(g_sCurGpsInfoPath, info, dist);
 
四、gps经纬度数据单位相关
gps数据单位是一个需要注意的问题。
(以下内容摘自网络)
1. GPS串口读取的数据格式:
GPS 串口读出的是 DDMM.MMMM格式
 一般上位机是 DD.DDDDDD°或 DD°MM'SS" 格式, 这两种都可以在 GE 里直接输入
举例说明: 3147.8749 (示例,经纬度一样) 格式为 DDMM.MMMM
转换成度:
1. 度的部分直接就是31,
2.剩下的 MM.MMMM/60=度, 所以 47.8749/60=0.797915
则 转换成度是 31.797915°
 
转换成度分秒:
1. 同样,度的部分直接就是31,
 2. 分直接是整数部分 47
 3. 秒则是 后面的 0.MMMM*60. 例子中为: 0.8749*60=52.494
 4. 则度分秒即是 31°47'52.494"
 
精确到 0.001"
阅读(994) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~