您的位置:首页 > 运维架构 > Linux

arm9+linux fl2440 GPS 数据采集和处理

2016-04-20 21:20 633 查看
=======================================================================

主机操作系统:centos 6.7

交叉编译器版本:arm-linux-gcc-4.5.4

开发板平台:fl2440

linux内核版本:Linux-3.0

Author: shaocongshuai <916962705@qq.com>
=======================================================================
GPS简介:

GPS是英文Global Positioning System(全球定位系统)的简称。GPS起始于1958年美国军方的一个项目,1964年投入使用。20世纪70年代,美国陆海空三军联合研制了新一代卫星定位系统GPS
。主要目的是为陆海空三大领域提供实时、全天候和全球性的导航服务,并用于情报搜集、核爆监测和应急通讯等一些军事目的,经过20余年的研究实验,耗资300亿美元,到1994年,全球覆盖率高达98%的24颗GPS卫星星座己布设完成。在机械领域GPS则有另外一种含义:产品几何技术规范(Geometrical
Product Specifications, 简称GPS)。另外一种含义为G/s(GB per second)。GPS(Generalized Processor Sharing)广义为处理器分享,网络服务质量控制中的专用术语。

于GPS,串口都是字符设备,难道就不需要再在linux内核中使能驱动吗?是这样的,在一开始内核中就已经对串口驱动进行了使能,而GPS模块中有GPS模块的驱动,这个模块通过自身的串口不断的发送数据开发板需要做的就是读取然后处理就够了。

一:GPS与开发板的链接
fl2440开发板有两个串口ttys0和ttys1,其中ttys0用来连接电脑终端,则ttys1连接GPS模块的串口,linux中的串口设备文件放于/de/目录下,串口一,串口二分别为”/dev/ttyS0”,”/dev/ttyS1”.在linux下操作串口与操作文件相同.
GPS模块接上电,监听串口了发回的数据包
~ >: microcom /dev/ttyS1 -s 4800

$GPGSV,3,2,11,27,31,041,,30,30,316,,09,21,230,37,16,19,083,*75

$GPGSV,3,3,11,23,11,199,30,28,07,291,,22,00,151,*48

$GPRMC,092047.000,A,3026.3016,N,11415.4829,E,1.90,13.28,200416,,,A*53

$GPGGA,092048.000,3026.3025,N,11415.4832,E,1,05,2.5,56.1,M,-14.4,M,,0000*49

$GPGSA,A,3,09,23,01,08,11,,,,,,,,4.1,2.5,3.3*31

$GPRMC,092048.000,A,3026.3025,N,11415.4832,E,1.78,11.99,200416,,,A*58

$GPGGA,092049.000,3026.3027,N,11415.4832,E,1,05,2.5,55.9,M,-14.4,M,,0000*41

$GPGSA,A,3,09,23,01,08,11,,,,,,,,4.1,2.5,3.3*31

$GPRMC,092049.000,A,3026.3027,N,11415.4832,E,1.28,13.39,200416,,,A*56

$GPGGA,092050.000,3026.3029,N,11415.4833,E,1,05,2.5,55.7,M,-14.4,M,,0000*48

$GPGSA,A,3,09,23,01,08,11,,,,,,,,4.1,2.5,3.3*31

$GPRMC,092050.000,A,3026.3029,N,11415.4833,E,1.81,14.25,200416,,,A*58

$GPGGA,092051.000,3026.3039,N,11415.4837,E,1,05,2.5,54.7,M,-14.4,M,,0000*4D

$GPGSA,A,3,09,23,01,08,11,,,,,,,,4.1,2.5,3.3*31

$GPRMC,092051.000,A,3026.3039,N,11415.4837,E,2.74,13.72,200416,,,A*50

-s      Set serial line to SPEED

二、arm+Linux 串口编程
至于串口编程的详细介绍,如何设置波特率,如何设置停止位等等,以下给出两个linux串口编程的博客链接,讲的很详细,不再赘述: http://www.cnblogs.com/wblyuyang/archive/2011/11/21/2257544.html http://my.oschina.net/u/137617/blog/27762

gps_ttyS1.c文件

#include <stdio.h>

#include <errno.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <termios.h>

#include <stdlib.h>

#include <string.h>

#include <sys/types.h>

#include <unistd.h>

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

* Description: 串口参数配置

* Input Args: fd:open打开的文件描述符 nspeed:波特率 nBits:数据位数 nEvent:奇偶校验 nStop:停止位

* Output Argtingzhis: 串口参数设置失败返回-1

* Return Value:

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

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

{

struct termios newttys1,oldttys1;

if(tcgetattr(fd,&oldttys1)!=0) //保存原先串口配置

{

perror("Setupserial 1");

return -1;

}

bzero(&newttys1,sizeof(newttys1)); //将一段内存区域的内容全清为零

newttys1.c_cflag|=(CLOCAL|CREAD ); //CREAD 开启串行数据接收,CLOCAL并打开本地连接模式

newttys1.c_cflag &=~CSIZE; //设置数据位数

switch(nBits) //选择数据位

{

case 7:

newttys1.c_cflag |=CS7;

break;

case 8:

newttys1.c_cflag |=CS8;

break;

}

switch( nEvent ) //设置校验位

{

case '0': //奇校验

newttys1.c_cflag |= PARENB; //开启奇偶校验

newttys1.c_iflag |= (INPCK | ISTRIP); //INPCK打开输入奇偶校验;ISTRIP去除字符的第八个比特

newttys1.c_cflag |= PARODD; //启用奇校验(默认为偶校验)

break;

case 'E' : //偶校验

newttys1.c_cflag |= PARENB; //开启奇偶校验

newttys1.c_iflag |= ( INPCK | ISTRIP); //打开输入奇偶校验并去除字符第八个比特

newttys1.c_cflag &= ~PARODD; //启用偶校验;

break;

case 'N': //关闭奇偶校验

newttys1.c_cflag &= ~PARENB;

break;

}

switch( nSpeed ) //设置波特率

{

case 2400:

cfsetispeed(&newttys1, B2400); //设置输入速度

cfsetospeed(&newttys1, B2400); //设置输出速度

break;

case 4800:

cfsetispeed(&newttys1, B4800);

cfsetospeed(&newttys1, B4800);

break;

case 9600:

cfsetispeed(&newttys1, B9600);

cfsetospeed(&newttys1, B9600);

break;

case 115200:

cfsetispeed(&newttys1, B115200);

cfsetospeed(&newttys1, B115200);

break;

default:

cfsetispeed(&newttys1, B9600);

cfsetospeed(&newttys1, B9600);

break;

}

if( nStop == 1) //设置停止位;若停止位为1,则清除CSTOPB,若停止位为2,则激活CSTOPB。

{

newttys1.c_cflag &= ~CSTOPB; //默认为送一位停止位;

}

else if( nStop == 2)

{

newttys1.c_cflag |= CSTOPB; //CSTOPB表示送两位停止位;

}

//设置最少字符和等待时间,对于接收字符和等待时间没有特别的要求时

newttys1.c_cc[VTIME] = 0; //非规范模式读取时的超时时间;

newttys1.c_cc[VMIN] = 0; //非规范模式读取时的最小字符数;

tcflush(fd ,TCIFLUSH); //tcflush清空终端未完成的输入/输出请求及数据;TCIFLUSH表示清空正收到的数据,且不读取出来

// 在完成配置后,需要激活配置使其生效

if((tcsetattr( fd, TCSANOW,&newttys1))!=0) //TCSANOW不等数据传输完毕就立即改变属性

{

perror("com set error");

return -1;

}

return 0;

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

三、GPS数据解析

NMEA是National Marine Electronics Association(美国国家海事电子协会)的缩写。NMEA-0183协议是目前GPS接收机上使用最广泛的协议,大多数常见的GPS接收机、GPS数据处理软件、导航软件都遵守或者至少兼容这个协议。

NMEA-0183协议定义的语句非常多,但是常用的或者说兼容性最广的语句

只有$GPGGA、$GPGSA、$GPGSV、$GPRMC、$GPVTG、$GPGLL等,名称如下:

(1) Global Positioning System FixData(GGA)GPS定位信息

(2) GPS DOP and Active Satellites(GSA)当前卫星信息

(3) GPS Satellites in View(GSV)可见卫星信息

(4) Recommended Minimum SpecificGPS/TRANSIT Data(RMC)推荐定位信息

(5) Track Made Good and GroundSpeed(VTG)地面速度信息

(6) Geographic Position(GLL)定位地理信息

3、 本程序主要通过GPS设备获得经度、纬度和高度,只需对该语句$GPGGA进行解析,

该语句所具有的语法为:

$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*hh

<1> UTC时间,hhmmss(时分秒)格式

<2> 纬度ddmm.mmmm(度分)格式(前面的0也将被传输)

<3> 纬度半球N(北半球)或S(南半球)

<4> 经度dddmm.mmmm(度分)格式(前面的0也将被传输)

<5> 经度半球E(东经)或W(西经)

<6> GPS状态:0=未定位,1=非差分定位,2=差分定位,6=正在估算

<7> 正在使用解算位置的卫星数量(00~12)(前面的0也将被传输)

<8> HDOP水平精度因子(0.5~99.9)

<9> 海拔高度(-9999.9~99999.9)

<10> 地球椭球面相对大地水准面的高度

<11> 差分时间(从最近一次接收到差分信号开始的秒数,如果不是差分定位将为空

<12> 差分站ID号0000~1023(前面的0也将被传输,如果不是差分定位将为空)

gps_analysis.c文件代码
/*********************************************************************************

* Copyright: (C) 2016 lingyun

* All rights reserved.

*

* Filename: gps_analysis.c

* Description: This file to analysis the GPS data.

* Version: 1.0.0(04/20/2016)

* Author: shaocongshuai <916962705@qq.com>

* ChangeLog: 1, Release initial version on "04/20/2016 08:11:56 PM"

*

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

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

#include <sys/types.h>

#include <errno.h>

#include <sys/stat.h>

#include <fcntl.h>

#include "gps.h"

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

* Description: 从GPS数据包中抽取出GPRMC最小定位信息

* Input Args:

* Output Args:

* Return Value:

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

int gps_analysis(char *buff, GPRMC *gps_date)

{

char *ptr = NULL;

if ( NULL == gps_date )

{

return -1;

}

if ( strlen(buff) < 10 )

{

return -2;

}

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

{

return -3;

}

sscanf(ptr,"$GPRMC,%d.000,%c,%f,N,%f,E,%f,%f,%d,,,%c*",&(gps_date->time),&(gps_date->pos_state),&(gps_date->latitude),&(gps_date->longitude),&(gps_date->speed),&(gps_date->direction),&(gps_date->date),&(gps_date->mode));

return 0;

}

int print_gps(GPRMC *gps_date)

{

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

printf("== the GPS module ==\n");

printf("== Author:shaocongshuai ==\n");

printf("== email:916962705@qq.com ==\n");

printf("== stage:fl2440 ==\n");

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

printf("== GPS state bit : %c \n",gps_date->pos_state);

printf("== GPS way bit : %c \n", gps_date->mode);

printf("== date : 20%02d-%02d-%02d \n",gps_date->date%100,(gps_date->date%10000)/100,gps_date->date/10000);

printf("== time : %02d:%02d:%02d \n",(gps_date->time/10000+8)%24,(gps_date->time%10000)/100,gps_date->time%100);

printf("== latitude : N:%.3f \n",(gps_date->latitude/100));

printf("== longitude : E:%.3f \n",(gps_date->longitude/100));

printf("== speed : %.3f \n",gps_date->speed);

printf("== \n");

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

return 0;

}

gps_main.c文件测试
/*********************************************************************************

* Copyright: (C) 2016 lingyun

* All rights reserved.

*

* Filename: gps_main.c

* Description: This file

* Version: 1.0.0(04/20/2016)

* Author: shaocongshuai <916962705@qq.com>

* ChangeLog: 1, Release initial version on "04/20/2016 07:48:44 PM"

*

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

#include <stdio.h>

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <string.h>

#include <errno.h>

#include <stdlib.h>

#include <termios.h>

#include "gps.h"

#define GPS_LEN 512 /*set the buffer length */

int gps_analysis(char *buff,GPRMC *gps_date);

int print_gps(GPRMC *gps_date);

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

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

* Description:

* Input Args:

* Output Args:

* Return Value:

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

int main (int argc, char **argv)

{

int fd = 0;

int nread = 0;

GPRMC gprmc;

char gps_buff[GPS_LEN];

char *dev_name = "/dev/ttyS1";

fd = open(dev_name, O_RDWR | O_NOCTTY | O_NDELAY);

if ( fd < 0 )

{

printf ("open ttyS1 error.\n");

return -1;

}

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

while ( 1 )

{

sleep(2);

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

if ( nread < 0 )

{

printf ("read GPS data error.\n");

return -2;

}

printf ("gps_buff: %s\n", gps_buff);

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

gps_analysis(gps_buff, &gprmc);

print_gps(&gprmc);

}

return 0;

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

gps.h文件代码
/********************************************************************************

* Copyright: (C) 2016 lingyun

* All rights reserved.

*

* Filename: gps.h

* Description: This head file is the head file of the gps.

* Version: 1.0.0(04/20/2016)

* Author: shaocongshuai <916962705@qq.com>

* ChangeLog: 1, Release initial version on "04/20/2016 07:26:38 PM"

*

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

#ifndef __GPS_H__

#define __GPS_H__

typedef long int LI;

typedef struct gprmc

{

int time; //格林威治时间

char pos_state; //定位状态

float latitude; //纬度

float longitude; //经度

float speed; //移动速度

float direction; //方向

int date; //日期

float declination; //磁偏角

char dd; //磁偏角方向

char mode;

}GPRMC;

extern int gps_analysis(char *buff, GPRMC *gps_date);

extern int print_gps(GPRMC *gps_date);

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

#endif

[shaocongshuai@localhost GPS]$ /opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc gps_analysis.c gps_main.c gps_ttyS1.c -o gps

[shaocongshuai@localhost GPS]$ ls

gps gps_analysis.c gps.h gps_main.c gps_ttyS1.c
将上图gps烧录到开发板后,记得更改可执行权限
~ >: tftp -gr gps 192.168.1.93

gps 100% |*******************************| 13187 0:00:00 ETA

~ >: chmod 777 gps

~ >: ./gps

gps_buff:

$GPGGA,130533.000,3026.3040,N,11415.4593,E,1,03,3.3,4.1,M,-14.4,M,,0000*7A

$GPGSA,A,2,17,06,30,,,,,,,,,,3.4,3.3,1.0*36

$GPRMC,130533.000,A,3026.3040,N,11415.4593,E,0.33,240.13,200416,,,A*67

$GPGGA,130534.000,3026.3043,N,11415.4597,E,1,03,3.3,4.4,M,-14.4,M,,0000*7F

$GPGSA,A,2,17,06,30,,,,,,,,,,3.4,3.3,1.0*36

$GPRMC,130534.000,A,3026.3043,N,11415.4597,E,0.08,168.18,200416,,,A*6D

$GPGGA,130535.000,3026.3047,N,11415.4602,E,1,03,3.3,4.6,M,-14.4,532.000,A,3026.3039,N,11415.4594,E,0.97,230.40,200416,,,A*60

===========================================================

== the GPS module ==

== Author:shaocongshuai ==

== email:916962705@qq.com ==

== stage:fl2440 ==

===========================================================

== GPS state bit : A

== GPS way bit : A

== date : 2016-04-20

== time : 21:05:33

== latitude : N:30.263

== longitude : E:114.155

== speed : 0.330

==

===========================================================
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: