安信可-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元的部