GPS(Global Positioning System)即全球定位系统,是由美国建立的一个卫星导航定位系统,利用该系统,用户可以在全球范围内实现全天候、连续、实时的三维导航定位和测速;另外,利用该系统,用户还能够进行高精度的时间传递和高精度的精密定位,通过GPS系统可以实现跟踪定位、防盗、里程统计、汽车导航、电子地图等等现实生活不可或缺的功能。本文着眼于在嵌入式linux系统上GPS功能的实现和研究。

1.1 GPS模块与ARM开发板的物理连接

GPS模块属于字符设备,只需要和FL2440开发板的第二个串口连接既可以,然后将GPS测试模块放在室外便可以每隔一段时间向开发板的串口发一个数据包。

~ >: microcom /dev/ttyS1 -s 4800

$GPGGA,024907.000,3029.6642,N,11423.6203,E,1,10,1.0,35.7,M,-13.7,M,,0000*41
$GPGSA,A,3,04,08,32,17,28,30,07,11,20,01,,,1.9,1.0,1.7*3B
$GPRMC,024907.000,A,3029.6642,N,11423.6203,E,0.07,244.07,210914,,,A*67
$GPGGA,024908.000,3029.6643,N,11423.6202,E,1,10,1.0,35.3,M,-13.7,M,,0000*4A
$GPGSA,A,3,04,08,32,17,28,30,07,11,20,01,,,1.9,1.0,1.7*3B
$GPGSV,3,1,11,04,78,178,38,01,74,066,31,30,56,242,44,11,54,043,31*75
$GPGSV,3,2,11,28,47,328,27,07,40,194,40,08,31,177,47,17,29,277,27*74
$GPGSV,3,3,11,20,23,145,36,32,21,098,33,19,15,059,*4C
$GPRMC,024908.000,A,3029.6643,N,11423.6202,E,0.09,238.16,210914,,,A*6D
$GPGGA,024909.000,3029.6643,N,11423.6202,E,1,10,1.0,35.0,M,-13.7,M,,0000*48
$GPGSA,A,3,04,08,32,17,28,30,07,11,20,01,,,1.9,1.0,1.7*3B
$GPRMC,024909.000,A,3029.6643,N,11423.6202,E,0.07,251.95,210914,,,A*66

。。。

1.1 GPS数据解析

GPS数据如何理解呢?这一大串的数据到底代表了什么意思呢?要想编写GPS数据解析程序,肯定要知道这些数据代表什么,还要知道如何转换这些数据。以下给出一个博客链接详细地说明了GPS数据,这里不在做赘述:

http://www.cnblogs.com/csMapx/archive/2011/11/02/2232663.html

1.1 ARM+linux串口编程介绍

其实编写GPS数据解析程序就是ARM+linux串口编程,串口编程是嵌入式应用程序开发中最基础也是最重要的部分,如何从一个串口设备获取数据并将这些数据做一定的解析呢?OK,串口编程大致可以分为以下几个步骤:

至于串口编程的详细介绍,如何设置波特率,如何设置停止位等等,以下给出两个linux串口编程的博客链接,讲的很详细,不再赘述:

http://www.cnblogs.com/wblyuyang/archive/2011/11/21/2257544.html

http://blog.csdn.net/mtv0312/article/details/6599162

1.4 编写一个简单的GPS数据解析程序

这个程序比较简单,只是一个测试GPS数据的程序,GPS数据当中的GPRMC数据就可以用来做导航信息用了,包含了经度、纬度、日期时间等等!如果你们想做一个比较完善的GPS数据解析程序,可以在我的基础上进行修改,比如加上GPS数据出错处理、GPS数据超时处理等等!

OK,我先说一下我的代码包含以下这几个文件:gps_test.c gps_analysis.c  set_com.c  gpsd.h主函数在gps_test.c文件中,gps_analysis.c主要是GPS数据解析函数设计,set_com.c主要是设置GPS串口设备函数设计,gpsd.h是头文件!

1.4.1 编写gps_test.c测试程序

#include <stdio.h>

#include <string.h>

#include <sys/types.h>

#include <errno.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <termios.h>

#include <stdlib.h>

#include "gpsd.h"

#define GPS_LEN 512         /* GPS数据长度宏定义 */

int main (int argc, char **argv)

{

int fd = 0;

int nread = 0;

GPRMC gprmc;

//GPRMC *gprmc;

char gps_buff[GPS_LEN];

char *dev_name = "/dev/ttyS1";

fd = open_com(dev_name);

set_opt(fd,4800,8,'N',1);

while(1)

{

sleep(2);  //注意这个时间的设置,设置不恰好的话,会导致GPS数据读取不完成,数据解析出错误

nread = read(fd,gps_buff,sizeof(gps_buff));

//printf("gps_buff: %s", gps_buff);

memset(&gprmc, 0 , sizeof(gprmc));

gprmc_analysis(gps_buff, &gprmc);

if(nread > 0)

{

printf("===========  GPS全球定位模块  ==============\n");

printf("==            开发者:韦书胜                  ==\n");

printf("==            版本:  1.0.0                    ==\n");

printf("===========================================\n");

printf("===========================================\n");

printf("= GPS状态位 : %c  [A:有效状态 V:无效状态]=\n" ,gprmc.pos_state);

printf("= GPS模式位 : %c  [A:自主定位 D:差分定位]=\n" , gprmc.mode);

printf("=日期 : 20%02d-%02d-%02d=\n", gprmc.date%100, (gprmc.date%10000)/100,

gprmc.date/10000);

printf("=时间 : %02d:%02d:%02d=\n",(gprmc.time/10000+8)%24,(gprmc.time%10000)/100,

gprmc.time%100);

printf("=纬度 : 北纬:%.3f=\n",(gprmc.latitude/100));

printf("=经度 : 东经:%.3f=\n",(gprmc.longitude/100));

printf("=速度 : %.3f =\n",gprmc.speed);

printf("===========================================\n");

}

}

close(fd);

return 0;

} /* ----- End of main() ----- */

1.4.2 编写gps_analysis.c GPS数据解析函数

/*********************************************************************************

*      Copyright:  (C) 2014 lingyun

*                  All rights reserved.

*

*       Filename:  gps_analysis.c

*    Description:  This file

*

*        Version:  1.0.0(2014年09月09日)

*         Author:  skyyang <790549341@qq.com>

*      ChangeLog:  1, Release initial version on "2014年09月09日 04时21分53秒"

*

********************************************************************************/

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <sys/types.h>

#include <errno.h>

#include <sys/stat.h>

#include <fcntl.h>

#include "gpsd.h"

int gprmc_analysis (char *buff,GPRMC *gprmc)

{

char *ptr = NULL;

if(gprmc == NULL)

return -1;

if(strlen(buff) < 10)

return -1;

if(NULL == (ptr = strstr(buff,"$GPRMC")))

return -1;

sscanf(ptr,"$GPRMC,%d.000,%c,%f,N,%f,E,%f,%f,%d,,,%c*",\

&(gprmc->time),&(gprmc->pos_state),&(gprmc->latitude),&(gprmc->longitude),&(gprmc->speed),&(gprmc->direction),&(gprmc->date),&(gprmc->mode));

return 0;

} /*  ----- End of gprmc_analysis()  ----- */

//strstr(str1,str2) 函数用于判断字符串str2是否是str1的子串。如果是,则该函数返回str2在str1中首次出现的地址;否则,返回NULL。

//sscanf() 从一个字符串中读进与指定格式相符的数据。

/*

例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(int argc, char **argv)
{
int ret;
char *string;
int digit;
char buf1[255];
char buf2[255];

string = "china beijing 123";
ret = sscanf(string, "%s %s %d", buf1, buf2, &digit);
printf("1.string=%s\n", string);
printf("1.ret=%d, buf1=%s, buf2=%s, digit=%d\n\n", ret, buf1, buf2, digit);

return 0;
}

执行结果:

1.ret=3, buf1=china, buf2=beijing, digit=123

可以看出,sscanf的返回值是读取的参数个数

*/

1.4.3 编写set_com.c GPS串口设备配置函数

/*********************************************************************************

*      Copyright:  (C) 2014

*                  All rights reserved.

*

*       Filename:  set_com.c

*    Description:  This file

*

*        Version:  1.0.0(2014年09月09日)

*         Author:

*      ChangeLog:  1, Release initial version on "2014年09月09日 04时15分06秒"

*

********************************************************************************/

#include <stdio.h>

#include <string.h>

#include <errno.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <termios.h>

#include <sys/types.h>

#include <stdlib.h>

#include "gpsd.h"

int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)

{

struct termios newtio,oldtio;

if( tcgetattr( fd,&oldtio)  !=  0)

{

perror("SetupSerial 1");

return -1;

}

bzero( &newtio, sizeof( newtio ) );

newtio.c_cflag  |=  CLOCAL | CREAD;

newtio.c_cflag &= ~CSIZE;

switch( nBits )

{

case 7:

newtio.c_cflag |= CS7;

break;

case 8:

newtio.c_cflag |= CS8;

break;

}

switch( nEvent )

{

case 'O':                     //奇校验

newtio.c_cflag |= PARENB;

newtio.c_cflag |= PARODD;

newtio.c_iflag |= (INPCK | ISTRIP);

break;

case 'E':                     //偶校验

newtio.c_iflag |= (INPCK | ISTRIP);

newtio.c_cflag |= PARENB;

newtio.c_cflag &= ~PARODD;

break;

case 'N':

newtio.c_cflag &= ~PARENB;

break;

}

switch( nSpeed )

{

case 2400:

cfsetispeed(&newtio, B2400);

cfsetospeed(&newtio, B2400);

break;

case 4800:

cfsetispeed(&newtio, B4800);

cfsetospeed(&newtio, B4800);

break;

case 9600:

cfsetispeed(&newtio, B9600);

cfsetospeed(&newtio, B9600);

break;

case 115200:

cfsetispeed(&newtio, B115200);

cfsetospeed(&newtio, B115200);

break;

default:

cfsetispeed(&newtio, B9600);

cfsetospeed(&newtio, B9600);

break;

}

if( nStop == 1 )

{

newtio.c_cflag &=  ~CSTOPB;

}

else if ( nStop == 2 )

{

newtio.c_cflag |=  CSTOPB;

}

newtio.c_cc[VTIME] = 0;

newtio.c_cc[VMIN] = 0;

tcflush(fd,TCIFLUSH);

if((tcsetattr(fd,TCSANOW,&newtio))!=0)

{

perror("com set error");

return -1;

}

return 0;

}

int open_com(char *device_name)

{

int fd = 0;

if (0 > (fd = open(device_name, O_RDWR|O_NOCTTY|O_NDELAY))) //要设置非阻塞模式打开设备否则会出错!

{

perror("Open Comport Fail:");

return 0;

}

return fd;

}/*  ----- End of open_com()  ----- */

1.4.4 编写gpsd.h头文件

#ifndef __GPSD_H__

#define __GPSD_H__

typedef unsigned int UINT;    //add by wei

typedef int BYTE;             //add by wei

typedef long int WORD;        //add by wei

typedef struct __gprmc__

{

UINT time;                  //时间

char pos_state;             //定位状态

float latitude;             //纬度

float longitude;            //经度

float speed;                //移动速度

float direction;            //方向

UINT date;                  //日期

float declination;          //磁偏角

char dd;                    //磁偏角方向

char mode;

} GPRMC;

extern int open_com(char *device_name);

extern int gprmc_analysis(char *buff,GPRMC *gprmc);

extern int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop);

#endif

1.5 编译下载GPS数据解析程序到开发板上

1.交叉编译器编译GPS数据解析程序,这里最好自己写一个makefile

[weishusheng@localhost gps_yang]$ ls

gps_analysis.c  gpsd.h  gps_test  gps_test.c  makefile  set_com.c  version.h

[weishusheng@localhost gps_yang]$ /opt/buildroot-2011.11/arm920t/usr/bin/arm-linux-gcc set_com.c gps_test.c gps_analysis.c -o gps_wei_test

[weishusheng@localhost gps_yang]$ ls
gps_analysis.c gpsd.h gps_test.c gps_wei_test set_com.c

生成gps_wei_test

2.在开发板上直接运行gps_test可执行程序,便可以获取解析后的GPS数据了:

/fl2440/gps >: ./gps_wei_test

gps infomation :8,53,332,24,30,52,231,43*77
$GPGSV,3,2,12,11,47,043,15,07,33,192,48,17,32,284,34,20,28,140,14*7C
$GPGSV,3,3,12,08,24,176,47,32,23,091,13,19,11,064,22,06,03,218,24*7F
$GPRMC,030323.000,A,3029.6405,N,11423.6222,E,0.34,332.13,210914,,,A*69
$GPGGA,030324.000,3029.6408,N,11423.6220,E,1,09,1.0,106.1,M,-13.7,M,,0000*7D
$GPGSA,A,3,04,08,28,30,07,17,01,11,19,,,,1.8,1.0,1.5*33
$GPRMC,030324.000,A,3029.6408,N,11423.6220,E,0.29,346.94,210914,,,A*61
$GPGGA,030325.000,3029.6410,N,11423.6218,E,1,09,1.0,105.2,M,-13.7,M,,0000*7E
$GPGSA,A,3,04,08,28,30,07,17,01,11,19,,,,1.8,1.0,1.5*33
$GPRMC,030325.000,A,3029.6410,N,11423.6218,E,0.28,315.50,210914,,,A*6D
$GPGGA,030326.000,3029.6412,N,11423.6216,E,1,09,1.0,104.5,M,-13.7,M,,0000*77
$GPGSA,A,3,04,08,28,30,07,17,01,11,19,,,,1.8,1.0,1.5*33
$GPRMC,030326.000,A,3029.6412,N,11423.621=========== GPS全球定位模块 ==============
== 开发者:weishusheng ==
== 版本: 1.0.0 ==
============================================

============================================
= GPS状态位 : A [A:有效状态 V:无效状态]=
日期 : 2014-09-21
时间 : 11:03:23
纬度 : 北纬:30.296
经度 : 东经:114.236
速度 : 0.340

到此,我们的GPS定位成功!

转载于:https://www.cnblogs.com/wanghuaijun/p/9338361.html

嵌入式系统上实现GPS全球定位功能相关推荐

  1. ARM嵌入式系统上OpenCL测试

    By Toradex Giovanni Bauermeister 1). 简介 相比曾经,如今科技设备对处理性能和速度要求越来越高.为了应对这种技术需求,许多公司发明了不少方法来获得更好的处理性能.例 ...

  2. CPU profiler(gperftools)在嵌入式系统上的应用示例

    上一篇博文<性能测试工具CPU profiler(gperftools)的使用心得>记录了CPU profiler的基本使用方式.本文以halley2开发板为例记录用CPU profile ...

  3. TUTK[MediaSDK][Android] 如何在android系统上实现后台编码功能

    必须要有摄像头权限,悬浮窗权限 开启Service加载一个1px的悬浮窗,构建CameraEncodePreview布局,进行后台编码 android5.0以下必须开启悬浮窗的硬加速配置:Window ...

  4. MiniGUI和其他嵌入式Linux 上的图形及图形用户界面系统

    基于linux和 minigui的嵌入式软件开发指南 第一节:MiniGUl-Threads 和 MiniGUl-Lite 的选择 第二节:理解消息循环和窗口过程 ----------- MiniGU ...

  5. 实时嵌入式 Linux 系统上GUI的发展与展望

    实时嵌入式 Linux 系统上GUI的发展与展望 GUI与嵌入式 ----在常见的PDA等小型手持式设备上,由于硬件条件等的限制,我们看到的用户界面都非常简单,几乎看不到PC机的华丽美观的GUI支持. ...

  6. 基于 Linux 和 MiniGUI 的嵌入式系统软件开发指南题八——MiniGUI 和其他嵌入式 Linux 上的图形及图形用户界面系统

    简介: 为了让读者对嵌入式 Linux 当中能够使用的图形及图形用户界面有个较为全面的认识,本文将为读者介绍一些嵌入式 Linux 系统中常见的图形及图形用户界面系统,并作为<基于 Linux ...

  7. 嵌入式 Linux 上的图形及图形用户界面系统

    1 Linux 图形领域的基础设施 本小节首先向读者描述 Linux 图形领域中常见的基础设施.之所以称为基础设施,是因为这些系统(或者函数库),一般作为其他高级图形或者图形应用程序的基本函数库.这些 ...

  8. MiniGUI 和其他嵌入式 Linux 上的图形及图形用户界面系统

    魏永明 (ymwei@minigui.org) 自由撰稿人 2001 年 11 月 为了让读者对嵌入式 Linux 当中能够使用的图形及图形用户界面有个较为全面的认识,本文将为读者介绍一些嵌入式 Li ...

  9. 嵌入式系统课程设计题目

    简介:一些嵌入式系统课程设计题目,可以当做对你学习ARM的一个检测. 嵌入式系统课程设计-选题要求及课题 1.嵌入式系统课程设计时长两星期,要求学生分组进行课程设计,每组学生人数为2-3人(可在不超过 ...

最新文章

  1. Google首席科学家Peyman 《计算成像去噪进展》斯坦福演讲报告,附视频与Slides
  2. 访问支付宝(淘宝)首页IE自动关闭解决方案
  3. 初识Tcl(九):Tcl 字典
  4. 面向对象课程第二单元作业总结
  5. 【Groovy】MOP 元对象协议与元编程 ( 方法委托 | 批量方法委托 )
  6. Spring Boot 项目的 API 接口防刷
  7. [react] 你有使用过formik库吗?说说它的优缺点
  8. protobuf java文档_Java中使用Protobuf
  9. 检测非法键盘hook_反越狱检测解读
  10. 大数据如何改变企业的业务
  11. Ubuntu之sshfs远程目录挂载到本地
  12. 查看IIS哪个应用程序池占用CPU过高
  13. Windows登录FTP服务器方法
  14. SpringBoot2.0系列教程(四)Springboot框架自定义消息转换器
  15. 史上最拉跨的导线平差程序( by C#)
  16. 老人与海好词100英文带翻译_英文版《老人与海》小说中优美语句50句
  17. 黄河科技学院计算机等级考试成绩查询,全国计算机等级考试成绩查询汇总
  18. 心流状态---人们做事时内心的一种状态
  19. 安卓第四次作业——简单校园二手交易APP
  20. linux下僵尸进程(<defunct>进程)的产生与避免

热门文章

  1. 浙政钉埋点 -- 稳定性监控代码(Emas)和流量分析代码(A+)
  2. ElastAlert笔记
  3. 零信任下的应用安全网关该如何建设?
  4. ES6 环境下 Openlayers 集成使用 ol-ext 以及在线示例
  5. 浏览器性能对比测试方法与评价模型研究
  6. 程序设计天梯赛L3-20 至多删三个字符(dp,一生之敌)
  7. 解决Matlab报错:警告: MATLAB 先前因底层图形错误而崩溃。为避免在此会话期间再次崩溃,MATLAB 将使用软件 OpenGL 而不再使用图形硬件。
  8. python必备软件百度网盘_【亲测好用!】python实现批量百度云批量转存工具
  9. 控制不了体重,何以控制人生
  10. 关于STM32F10x系列结构及单片机命名规则