国产宅男网站在线|亚洲A级性爱免费视频|亚洲中精品级在线|午夜福利AA毛

  • <dd id="gf5jf"><th id="gf5jf"></th></dd>

    <cite id="gf5jf"><label id="gf5jf"></label></cite>
  • <div id="gf5jf"><listing id="gf5jf"></listing></div>
    學習啦 > 學習電腦 > 操作系統(tǒng) > Linux教程 > Linux下接收處理GPS數(shù)據(jù)教程

    Linux下接收處理GPS數(shù)據(jù)教程

    時間: 志藝942 分享

    Linux下接收處理GPS數(shù)據(jù)教程

      Linux的性能、可靠性、靈活性、和開放性,與其支持多微處理器體系結構、硬件設備、圖形支持和通信協(xié)議相結合,把Linux建成了一個日益發(fā)展的操作系統(tǒng)平臺。接下來是小編為大家收集的Linux下接收處理GPS數(shù)據(jù)教程,希望能幫到大家。

      Linux下接收處理GPS數(shù)據(jù)教程

      1,接收數(shù)據(jù)

      這個名字有點籠統(tǒng),確切講是串口接收gps模塊的原始數(shù)據(jù),在fl2440開發(fā)板左側大家可以看到有兩個母頭串口(如圖1)

      在開發(fā)板上 ls /dev 你會發(fā)現(xiàn)

      ttyS0(這個是連接到電腦的串口,也是圖一中上面的那個串口),

      ttyS1(這個就是圖一中下面的串口,也是連接gps模塊,我們需要監(jiān)聽的串口)

      由于gps模塊也是母頭,所以需要自己制作一個公頭線,首先進行硬件上的聯(lián)通,下面看一下RS_232的db9線每一個引腳的作用

      --------------下圖為引腳順序圖------------

      Db9中有效的通信引腳2(RXD),3(TXD),5(GND)。在公頭和母頭進行連接時,公頭2連接母頭3,公頭3連接母頭2。5接5。這樣硬件實現(xiàn)了連接。如下,

      gps模塊接上電,此時可以監(jiān)聽串口了,

      監(jiān)聽串口命令 microcom -s 4800 /dev/ttyS1

      有了上述結果。說明接收數(shù)據(jù)是可以實現(xiàn)的??吹竭@里不知道有沒有人有疑問,這樣就可以直接收到數(shù)據(jù)么,gps,串口都是設備,不需要對gps和串口進行驅動使能么?是這樣的,在一開始內(nèi)核中就已經(jīng)對串口驅動進行了使能,而gps模塊中有gps模塊的驅動,這個模塊通過自身的串口不斷的發(fā)送數(shù)據(jù)開發(fā)板需要做的就是讀取然后處理就夠了,

      以上步驟成功,說明硬件上的連通性沒的問題,可以說只是準備工作,接下來的才是重點,

      串口編程!!!

      數(shù)據(jù)分析!!!

      重要的事情要說三個感嘆號

      其實編寫GPS數(shù)據(jù)解析程序就是ARM+linux串口編程,串口編程是嵌入式應用程序開發(fā)中最基礎也是最重要的部分,如何從一個串口設備獲取數(shù)據(jù)并將這些數(shù)據(jù)做一定的解析呢?OK,串口編程大致可以分為以下幾個步驟:

      至于串口編程的詳細介紹,如何設置波特率,如何設置停止位等等,以下給出兩個linux串口編程的博客鏈接,講的很詳細

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

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

      其中串口設置其實就相當于串口通信的協(xié)議,

      波特率:是為了兩者信號流能同步,

      數(shù)據(jù)位:是指又幾位數(shù)據(jù)封裝成一幀

      結束位:是指以幀傳輸數(shù)據(jù)時,協(xié)定好結束位,便于提取有效數(shù)據(jù)

      奇偶校驗:檢驗數(shù)據(jù)的一種手段

      四者的設置又通信雙方協(xié)定。

      數(shù)據(jù)分析!!!

      $GPRMC,最常用的字符串,包含了時間,日期,定位,和航速航向信息。一般應用,只要有這些信息就可以了。

      $GPGGA,包含了定位信息相關的詳細信息。如定位時用到的星數(shù),定位的方式,天線的海拔高度,精度等等。

      $GPGSA,包含了定位,水平,海拔三種DOP信息,即精度信息,包含了定位所用到的衛(wèi)星ID。

      $GPGSV,包含了GPS模塊可以看到的星數(shù)(注意,只是能看到的星數(shù),實際使用到的星數(shù)在GPGGA中),以及這些衛(wèi)星的ID號,仰角,方位角,信噪比。關于這種字符串要特別說明的是,它可能會由幾條GPGSV字符串組成,因此,每個字符串都包含了共幾條字符串,本字串是第幾條這樣的信息。一般的GPS最多是三條。也有的GPS模塊會超過3條。

      $GPVTG,包含了更詳細的航向航速的信息,航向信息分為以真北為參考和以地磁北為參考(真北和地磁北是不一樣的,兩者相差幾度),航速信息則給出了以節(jié)為單位和以公里/時為單位的數(shù)據(jù)。

      以上信息,一般GPS模塊都會默認輸出,也有的模塊只輸出其中幾個。

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

      <1> UTC時間,hhmmss(時分秒)格式

      <2> 定位狀態(tài),A=有效定位,V=無效定位

      <3> 緯度ddmm.mmmm(度分)格式(前面的0也將被傳輸)

      <4> 緯度半球N(北半球)或S(南半球)

      <5> 經(jīng)度dddmm.mmmm(度分)格式(前面的0也將被傳輸)

      <6> 經(jīng)度半球E(東經(jīng))或W(西經(jīng))

      <7> 地面速率(000.0~999.9節(jié),前面的0也將被傳輸)

      <8> 地面航向(000.0~359.9度,以真北為參考基準,前面的0也將被傳輸)

      <9> UTC日期,ddmmyy(日月年)格式

      <10> 磁偏角(000.0~180.0度,前面的0也將被傳輸)

      <11> 磁偏角方向,E(東)或W(西)

      <12> 模式指示(僅NMEA0183 3.00版本輸出,A=自主定位,D=差分,E=估算,N=數(shù)據(jù)無效)

      例如

      $GPRMC,074030.00,A,3941.10576,N,11810.52559,E,0.879,136.15,020210,,,A*64

      UTC時間 定位狀態(tài) 緯度 經(jīng)度 航速 航向 UTC時間/年

      $GPGGA,074030.00,3941.10576,N,11810.52559,E,1,06,11.32,46.6,M,-2.7,M,,*4A

      UTC時間 緯度 經(jīng)度 GPS狀態(tài) 正在使用衛(wèi)星數(shù) 水平精度 海拔高度碼

      基本思路:

      open /dev/ttyS1

      read()讀串口一的數(shù)據(jù)存入到緩存里

      Strstr()在緩存里進行字符串“$GPRMC”的匹配,然后返回匹配的字符串的位置處

      Sscanf()將$GPRMC的有用數(shù)據(jù)另存起來,

      具體代碼如下

      設置串口

      set_ttyS1.c

      #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;

      }

      分析gps數(shù)據(jù)函數(shù)

      analysis.c

      #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->latitude),&(gprmc->speed),&(gprmc-

      >direction),&(gprmc->date),&(gprmc->mode));

      return 0;

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

      測試函數(shù)

      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

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

      int open_com(char *device_name);

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

      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數(shù)據(jù)讀取不完成,數(shù)據(jù)解析出錯誤

      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("===========================================\n");

      printf("= GPS狀態(tài)位 : %c [A:有效狀態(tài) V:無效狀態(tài)]==\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("=經(jīng)度 : 東經(jīng):%.3f=\n",(gprmc.longitude/100));

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

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

      }

      }

      close(fd);

      return 0;

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

      頭文件

      gpsd.h

      #ifndef __GPSD_H__

      #define __GPSD_H__

      typedef unsigned int UINT;

      typedef int BYTE;

      typedef long int WORD;

      typedef struct __gprmc__

      {

      UINT time; //時間

      char pos_state; //定位狀態(tài)

      float latitude; //緯度

      float longitude; //經(jīng)度

      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

      代碼寫好后如下

      Makefile

      生成的gps可執(zhí)行文件,下載到開發(fā)板上,運行,ok


    看了“Linux下接收處理GPS數(shù)據(jù)教程”還想看:

    1.數(shù)據(jù)包接收詳解

    2.Linux如何對網(wǎng)站數(shù)據(jù)進行自動備份和刪除

    3.怎么備份遠程mysql數(shù)據(jù)庫的腳本文件

    2806224