亚洲欧美精品沙发,日韩在线精品视频,亚洲Av每日更新在线观看,亚洲国产另类一区在线5

<pre id="hdphd"></pre>

  • <div id="hdphd"><small id="hdphd"></small></div>
      學(xué)習(xí)啦 > 學(xué)習(xí)電腦 > 操作系統(tǒng) > Linux教程 > Linux下接收處理GPS數(shù)據(jù)教程

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

      時間: 志藝942 分享

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        串口編程!!!

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

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

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

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

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

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

        其中串口設(shè)置其實(shí)就相當(dāng)于串口通信的協(xié)議,

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

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

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

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

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

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

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

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

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

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

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

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

        $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度,以真北為參考基準(zhǔn),前面的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()在緩存里進(jìn)行字符串“$GPRMC”的匹配,然后返回匹配的字符串的位置處

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

        具體代碼如下

        設(shè)置串口

        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': //奇校驗(yàn)

        newtio.c_cflag |= PARENB;

        newtio.c_cflag |= PARODD;

        newtio.c_iflag |= (INPCK | ISTRIP);

        break;

        case 'E': //偶校驗(yàn)

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

        //注意這個時間的設(shè)置,設(shè)置不恰好的話,會導(dǎo)致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ā)板上,運(yùn)行,ok


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

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

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

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

      2806224