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文件,文件内容如下:
-
# 制作的目标文件名libnmeagps.so
-
TARGET = libnmeagps.so
-
-
# 包含所有头文件
-
INCLUDE_FILE = context.h generate.h parse.h parser.h gtime.h
-
INCLUDE_FILE += tok.h units.h gmath.h nmea.h sentence.h info.h generator.h config.h
-
-
# 设置交叉编译工具
-
COMPILER_PATH = arm-linux-
-
-
CC = $(COMPILER_PATH)gcc
-
CXX = $(COMPILER_PATH)g++
-
LD = $(COMPILER_PATH)ld
-
AR = $(COMPILER_PATH)ar
-
-
LIBRARY = ./lib/
-
-
INCLUDE_DIR = ./include/
-
-
FLAGS = -Wall -O3 -s -I. -I$(INCLUDE_DIR)
-
-
ifdef S3C2440
-
FLAGS += -DPLAT_S3C2440
-
else ifdef TI6446
-
FLAGS += -DPLAT_TI6446
-
else
-
endif
-
-
OBJS = $(patsubst %.c, %.o, $(wildcard *.c))
-
-
%.o:%.c
-
@$(CC) -c $(FLAGS) $< -o $@
-
-
all:$(OBJS)
-
@$(CC) -shared -Wall -fPIC -s $(OBJS) -o $(TARGET)
-
-
@cp $(TARGET) $(LIBRARY) 1>/dev/null
-
@cp $(INCLUDE_FILE) $(INCLUDE_DIR) 1>/dev/nul
-
-
update:
-
@cp -a $(INCLUDE_FILE) $(INCLUDE_DIR) 1>/dev/null
-
-
clean:
-
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) 测试
-
/* nmea_lib测试程序 */
-
void trace(const char *str, int str_size)
-
{
-
printf("Trace: ");
-
write(1, str, str_size);
-
printf("\n");
-
}
-
void error(const char *str, int str_size)
-
{
-
printf("Error: ");
-
write(1, str, str_size);
-
printf("\n");
-
}
-
-
int main()
-
{
-
nmeaINFO info;
-
nmeaPARSER parser;
-
FILE *file;
-
char buff[2048];
-
int size, it = 0;
-
nmeaPOS dpos;
-
-
file = fopen("gpslog.txt", "rb");
-
-
if(!file)
-
return -1;
-
-
nmea_property()->trace_func = &trace;
-
nmea_property()->error_func = &error;
-
-
nmea_zero_INFO(&info);
-
nmea_parser_init(&parser);
-
-
/*
-
while(1)
-
{
-
*/
-
-
while(!feof(file))
-
{
-
size = (int)fread(&buff[0], 1, 100, file);
-
-
nmea_parse(&parser, &buff[0], size, &info);
-
-
nmea_info2pos(&info, &dpos);
-
-
/* 获取 lat经度,lon纬度,sig信号指标,fix操作模式 */
-
printf("%03d, Lat: %f, Lon: %f, Sig: %d, Fix: %d\n", it++, info.lat, info.lon, info.sig, info.fix);
-
}
-
-
fseek(file, 0, SEEK_SET);
-
-
/*
-
}
-
*/
-
-
nmea_parser_destroy(&parser);
-
fclose(file);
-
-
return 0;
-
}
三、应用
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"
阅读(2576) | 评论(0) | 转发(0) |