1. 程式人生 > >安信可-A7模組——C語言程式設計實現GPS功能

安信可-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
[[email protected] gps]$ ls
gps_analyse.c  gps.h  gps_main.c  gps_test  Makefile  s_uart.c

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

相關推薦

-A7模組——C語言程式設計實現GPS功能

上一篇博文整理學習了有關串列埠通訊、串列埠程式設計的一些基本知識。本篇將通過程式設計來獲取、解析、轉換GPS接收機接收的資訊。 我們將在fl2440開發板上實現該功能。 一、A7與開發板連線 我使用的是USB轉TTL串列埠轉接線,這裡要保證Linux支

A7模組GPRS功能測試及初步學習AT指令

一、GPRS簡介 GSM模組,是將GSM射頻晶片、基帶處理晶片、儲存器、功放器件等整合在一塊線路板上,具有獨立的作業系統、GSM射頻處理、基帶處理並提供標準介面的功能模組。GSM模組根據其提供的資料傳

詳解!C語言程式設計實現小遊戲“三子棋”

今天我們來程式設計實現一個充滿童趣的小遊戲“三子棋” 先來說一下三子棋的規則: 三子棋又叫九宮棋、圈圈叉叉、一條龍等。 將正方形對角線連起來,或相對兩邊依次擺上三個雙方棋子, 總之只要將自己的三個棋子走成一條線, 對方就算輸了。 不用再過多解釋了,相信大家一定都玩過! 那麼,該

課上補做:用C語言程式設計實現ls命令

課上補做:用C語言程式設計實現ls命令 一、有關ls ls :用來列印當前目錄或者制定目錄的清單,顯示出檔案的一些資訊等。 ls -l:列出長資料串,包括檔案的屬性和許可權等資料 ls -R:連同子目錄一同顯示出來,也就所說該目錄下所有檔案都會顯示出來 ls -a:可以將目錄下的全部檔案

計算位數最高達300位的兩個非負整數的乘積,C語言程式設計實現

-------世界太蕪雜,我幫你整理---- -------C語言大數相乘運算---------- 今天我們要程式設計實現的是兩個超長整型資料進行相乘,並輸出結果 比如: 2134897427972647678 * 3497892374 我們先來看看執行效果

離散數學真值表(c語言程式設計實現

程式碼如下: 廢話不多說: 主要利用二進位制的轉化實現  #include <iostream> #include <math.h> using namespace std; void shuru(char *p,int s); void shu

KST-51微控制器:c語言程式設計實現數碼管動態顯示秒錶的倒計時

/*60S倒計時*/ /*個位每1S變一次,從0~9*/ /*十位,個位為0的下一秒十位發生變化*/ #include<reg52.h> sbit ADDR0=P1^0; sbit ADDR1=P1^1; sbit ADDR2=P1^2; sbit ADDR3

Hanoi塔問題 棧與遞迴C語言程式設計實現

Hanoi塔 棧與遞迴C程式設計實現 參考書 嚴蔚敏  資料結構 #include <stdio.h> #include <stdlib.h> #include <conio.h> typedef int ElemType; type

http協議C語言程式設計實現

轉載:http://zhoulifa.bokee.com/4640913.html 大家都很熟悉HTTP協議的應用,因為每天都在網路上瀏覽著不少東西,也都知道是HTTP協議是相當簡單的。每次用到FlashGet之類的下載軟體下載網頁,當用到那個“用FlashGet下載全部連

C語言程式設計實現建立多個目錄(資料夾)

    因為要建立90個資料夾,本人實在不想一個一個的建立,就想是不是可以用C語言程式設計來實現呢,剛才查閱了很多部落格,終於終於我實現了,可以用迴圈的方式建立了,也不屬於自己原創,參考了很多大神的程式碼。現在我把原始碼貼出來,在Visual studio 2015上跑成功了

C語言程式設計實現使用AES對檔案進行加密

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <openssl/aes.h>int main(int argc,char* argv[]){ 

c語言程式設計實現簡單三子棋遊戲

   分別建立test.c   game.c 兩個原始檔,以及game.h標頭檔案   這裡的三子棋遊戲是指棋盤為3*3,玩家與電腦之間的對決,先將各自的棋下為一排(橫/豎/斜)者獲勝,電腦所    下位置是隨機產生   1. game.h中用於函式定義,如下: #ifn

HTTP協議的C語言程式設計實現例項

大家都很熟悉HTTP協議的應用,因為每天都在網路上瀏覽著不少東西,也都知道是HTTP協議是相當簡單的。每次用到FlashGet之類的下載軟體下載網頁,當用到那個“用FlashGet下載全部連結”時總覺得很神奇。 後來想想,其實要實現這些下載功能也並不難,只要按照HTTP協

將兩個非遞減的有序連結串列合併為一個非遞增的有序連結串列(C語言程式設計實現

將兩個非遞減的有序連結串列合併為一個非遞增的有序連結串列。要求結果連結串列仍使用原來兩個連結串列的儲存空間, 不另外佔用其它的儲存空間。表中允許有重複的資料。 #include<stdio.

C語言程式設計實現,浮點型與字元陣列相互轉化

歡迎轉載,請註明出處,本文地址:http://blog.csdn.net/jk050802/article/details/8628764 聯絡郵箱:[email protected] 簡介          從浮點型轉換為字元型:這裡比較簡單,只需要用

c語言程式設計實現電腦com口發資料

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

GSM/GPRS模組 AT指令集C語言程式設計——基於有方M660+和MSP430微控制器

GSM/GPRS晶片是手機中負責收發簡訊、撥打電話以及訪問GPRS網路的核心器件。有方M660+為深圳有方公司生產的一款超小封裝的GSM/GPRS工業無線模組,可以提供高品質的語音、簡訊、資料業務等功能,在各種工業和民用領域得到廣泛的應用。 有方M660+ GPRS模組的硬體設計 硬體設計參考附件《M

1012 - C語言程式設計教程(第三版)課後習題6.2

1012 - C語言程式設計教程(第三版)課後習題6.2 時間限制:1秒 記憶體限制:128兆 題目描述 輸入一行字元,分別統計出其中英文字母、空格、數字和其他字元的個數。 輸入 一行字元 輸出 統計值 樣例輸入 aklsjflj123 sadf918u324 asdf91u32oa

1011 - C語言程式設計教程(第三版)課後習題6.1

1011 - C語言程式設計教程(第三版)課後習題6.1 時間限制:1秒 記憶體限制:128兆 題目描述 輸入兩個正整數m和n,求其最大公約數和最小公倍數。 輸入 兩個整數 輸出 最大公約數,最小公倍數 樣例輸入 5 7 樣例輸出 1 35 最大公約數求法我是用的是輾轉相除法進行

1010 - C語言程式設計教程(第三版)課後習題5.8

1010 - C語言程式設計教程(第三版)課後習題5.8 時間限制:1秒 記憶體限制:128兆 題目描述 企業發放的獎金根據利潤提成。利潤低於或等於100000元的,獎金可提10%; 利潤高於100000元,低於200000元(100000<I≤200000)時,低於100000元的部