安信可-A7模塊——C語言編程實現GPS功能

上一篇博文整理學習了有關串口通信、串口編程的一些基本知識。本篇將通過編程來獲取、解析、轉換GPS接收機接收的信息。
我們將在fl2440開發板上實現該功能。

一、A7與開發板連線

我使用的是USB轉TTL串口轉接線,這裏要保證Linux支持了所用的轉接芯片。我使用的是cp210的USB轉串口芯片,因此要在內核選項中支持它:

make menuconfig
    Device Drivers->
        [*]USB support ->
            [*]USB Serial Converter supportUSB CP210x family of UART Bridge Controllers 

make新內核燒錄到開發板,這樣開發板就使能了USB驅動。
將串口AT指令控制發送端(U_TXD)和串口AT指令控制接收端(U_RXD)分別與USB轉TTL轉接頭上的RXD和TXD相連,GND與GND相連。另一端接入開發板的USB口即可。

二、打開GPS功能並測試

將A7連上開發板以後,在開發板上使用microcom命令監聽相關串口,USB轉串口芯片連接則監聽串口/dev/ttyUSB0。然後把GPS功能打開:

>: microcom -s 115200 /dev/ttyUSB0 
>at   //檢測模塊是否正常
OK
>AT+GPS=1   //打開GPS功能
OK

此時將A7模塊上的U_TXD連線切換到A7模塊上的GPS_TXD引腳,其他連線不變。以波特率爲9600重新打開監聽串口,將會不斷的收到GPS定位的數據。

這裏寫圖片描述

可以看到GPS已經正常工作。

三、編程實現信息獲取、解析

首先便是對串口的設置程序s_uart.c。通過串口把數據發送到終端設備,請參考上一篇博文

gps數據分析,gps_analyse.c :

/*********************************************************************************
*      Copyright:  (C) 2017 TangBin<[email protected]>
*                  All rights reserved.
*
*        Filename:  gps_analyse.c
*    Description:  This file 
*                 
*           Version:  1.0.0(06/04/2017)
*            Author:  TangBin <[email protected]>
*     ChangeLog:  1, Release initial version on "06/04/2017 07:59:41 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"

int gps_analyse (char *buff,GPRMC *gps_data)
{
    char *ptr = NULL;

    if(gps_data==NULL)
    {
        return -1;
    }

    if(strlen(buff)<10)
    {
        return -1;
    }

    /*如果buff字符串中包含字符"$GPRMC"則將$GPRMC的地址賦值給ptr*/
    if(NULL==(ptr=strstr(buff,"$GPRMC")))
    {
        return -1;
    }
    sscanf(ptr,"$GPRMC,%d.000,%c,%f,N,%f,E,%f,%f,%d,,,%c*",&(gps_data->time),&(gps_data->pos_state),&(gps_data->latitude),&(gps_data->longitude),&(gps_data->speed),&(gps_data->direction),&(gps_data->date),&(gps_data->mode));
/*sscanf函數爲從字符串輸入,上面這句話的意思是將ptr內存單元的值作爲輸入分別輸入到後面的結構體成員*/
    return 0;
} /* ----- End of gps_analyis()  ----- */



/**************************************************************************************
 *  Description:
 *   Input Args:
 *  Output Args:
 * Return Value:
 *************************************************************************************/
int print_gps (GPRMC *gps_data)
{
    printf("                                                           \n");
    printf("                                                           \n");
    printf("===========================================================\n");
    printf("==                   全球GPS定位導航模塊                 ==\n");
    printf("==              開發人員:唐彬                         ==\n");
    printf("==              郵箱:[email protected]               ==\n");
    printf("==              平臺:fl2440                             ==\n");
    printf("===========================================================\n");
    printf("                                                           \n");
    printf("===========================================================\n");
    printf("==   GPS狀態位 : %c  [A:有效狀態 V:無效狀態]              \n",gps_data->pos_state);
    printf("==   GPS模式位 : %c  [A:自主定位 D:差分定位]               \n", gps_data->mode);
    printf("==   日期 : 20%02d-%02d-%02d                                  \n",gps_data->date%100,(gps_data->date%10000)/100,gps_data->date/10000);
    printf("==   時間 : %02d:%02d:%02d                                   \n",(gps_data->time/10000+8)%24,(gps_data->time%10000)/100,gps_data->time%100);
    printf("==   緯度 : 北緯:%d度%d分%d秒                              \n", ((int)gps_data->latitude) / 100, (int)(gps_data->latitude - ((int)gps_data->latitude / 100 * 100)), (int)(((gps_data->latitude - ((int)gps_data->latitude / 100 * 100)) - ((int)gps_data->latitude - ((int)gps_data->latitude / 100 * 100))) * 60.0));
    printf("==   經度 : 東經:%d度%d分%d秒                              \n", ((int)gps_data->longitude) / 100, (int)(gps_data->longitude - ((int)gps_data->longitude / 100 * 100)), (int)(((gps_data->longitude - ((int)gps_data->longitude / 100 * 100)) - ((int)gps_data->longitude - ((int)gps_data->longitude / 100 * 100))) * 60.0));
    printf("==   速度 : %.3f  m/s                                      \n",gps_data->speed);
    printf("==                                                       \n");
    printf("============================================================\n");

    return 0;
} /* ----- End of printf_gps()  ----- */

對於字段的分析,在上上篇博文已經解讀,不過我們要把數據轉化一下,方便我們記錄和識別。
1. 時間,這個是格林威治時間即世界時間(UTC),把它轉換成我們用的北京時間(BTC),在這個時間基礎上加8個小時。
2. 經緯度,GPRMC返回的緯度數據位ddmm.mmmm格式即度分格式,我們把它轉換成常見的度分秒的格式,計算方法:如接收到的緯度是:3029.60430
3029.60430/100=30.2960430可以直接讀出30度, 3029.60430–30*100=29.60430, 可以直接讀出29分
(29.60430–29)*60 =0.60430*60=36.258讀出36秒, 所以緯度是:30度29分36秒。
3. 南北緯東西經,N:北緯。S:南緯。E:東經。W:西經。
4. 速率,GPRMC返回的速率值是海里/時,單位是節,把它轉換成千米/時,換算爲:1海里=1.85公里,把得到的速率乘以1.85。
5. 航向,指的是偏離正北的角度
6. 日期,GPRMC的日期格式爲:ddmmyy,如:040617表示2017年06月04日,這個日期是準確的,不需要轉換。

主函數gps_main.c,這裏便涉及到了串口的打開,讀操作,以及調用了串口設置函數:

/*********************************************************************************
*      Copyright:  (C) 2017 TangBin<[email protected]>
*                  All rights reserved.
*
*       Filename:  gps_main.c
*    Description:  This file 
*                 
*        Version:  1.0.0(06/04/2017)
*         Author:  TangBin <[email protected]>
*      ChangeLog:  1, Release initial version on "06/04/2017 08:07:14 PM"
*                 
********************************************************************************/
#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 "gps.h"

#define GPS_LEN 512 

int set_serial(int fd,int nSpeed, int nBits, char nEvent, int nStop);
int gps_analyse(char *buff,GPRMC *gps_date);
int print_gps(GPRMC *gps_date);


/********************************************************************************
 *  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/ttyUSB0";

    fd = open(dev_name,O_RDWR|O_NOCTTY|O_NDELAY);
    if(fd<0)
    {
        printf("open ttyUSB0 failed.\n");
        return -1;
    }

    set_serial( fd,9600,8,'N',1);

    while(1)
    {
        sleep(2);
        nread = read(fd,gps_buff,sizeof(gps_buff));
        if(nread<0)
        {
            printf("read GPS date error!!\n");
            return -2;
        }
        printf("gps_buff: %s\n", gps_buff);

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

        print_gps(&gprmc);
    }

    close(fd);
    return 0;
} /* ----- End of main() ----- */

gps.h:

/********************************************************************************
 *      Copyright:  (C) 2017 TangBin<[email protected]>
 *                  All rights reserved.
 *
 *       Filename:  gps.h
 *    Description:  This head file 
 *
 *        Version:  1.0.0(06/04/2017)
 *         Author:  TangBin <[email protected]>
 *      ChangeLog:  1, Release initial version on "06/04/2017 08:10:52 PM"
 *                 
 ********************************************************************************/

#ifndef __GPS_H__
#define __GPS_H__

typedef unsigned int UINT;
typedef int BYTE;
typedef long int WORD;

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 gps_analysis(char *buff,GPRMC *gps_date);
extern int print_gps(GPRMC *gps_date);
extern int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop);

#endif

接下來使用Makefile編譯,
Makefile:

  1 CC=/opt/buildroot-2012.08/arm920t/usr/bin/arm-linux-gcc
  2 
  3 objs=s_uart.o gps_analyse.o gps_main.o
  4 srcs=s_uart.c gps_analyse.c gps_main.c
  5 
  6 gps_test: $(objs)
  7         $(CC) -o gps_test $(objs)
  8             @make clean
  9 
 10 gps_main.o: $(srcs) gps.h
 11         $(CC) -c  $(srcs) 
 12 
 13 set_uart.o:  suart.c
 14         $(CC) -c  s_uart.c
 15 
 16 analyse_gps.o: gps_analyse.c gps.h
 17         $(CC) -c  gps_analyse.c
 18 
 19 clean:  
 20         rm *.o
[tangbin@localhost gps]$ ls
gps_analyse.c  gps.h  gps_main.c  gps_test  Makefile  s_uart.c

將編譯生成的gps_test下載到開發板,運行測試:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章