《Linux作業系統-系統移植》第8章 USB-4G/LTE移植 -第3節 USB-4G移植(移遠AG35開發-GPS解析及程式設計)
檢視參考手冊,移遠帶有GPS的晶片的USB Serial如下。
2.1應用簡介
1、若不使用 AT+QGPSCFG 指令對AG35進行配置,則會以預設引數開啟GPS引數,NMEA埠開始上報,"gpsnmeatype"預設值為31,上報間隔為1s,每次上報所有種類的NMEA資料(GGA\RMC\GSV\GSA\VTG),若採用此預設配置,大多數使用者會覺得單次上報的資料太多且很多資訊重複,建議大家使用QGPSCFG配置自己需要的NMEA資料格式,具體格式的差異可參考網上對NMEA資料的說明。
2、Linux環境下對NMEA資料的獲取:
cat /dev/ttyUSB1 & // NMEA資料從ttyUSB1輸出
echo “AT+QGPS=1” > /dev/ttyUSB2 // 開啟GPS會話
可觀察到ttyUSB1輸出NMEA資料,如下:
3、程式設計過程中,若有固定頻率更新位置需求,可考慮採用讀取NMEA埠資料的形式,並將其配置適合自己需求的NMEA格式和資料更新間隔。若產品執行獲取位置指令的頻率較低且間隔時間不固定,也可考慮直接在AT指令埠使用AT+QGPSLOC指令進行實時位置資訊的獲取。
2.2 GPS資料解析
NMEA 0183是美國國家海洋電子協會(National Marine Electronics Association )為海用電子裝置制定的標準格式。目前業已成了GPS導航裝置統一的RTCM(Radio Technical Commission for Maritime services)標準協議。
GPS接收機上電後,會自動通過串列埠或USB口傳送NMEA0183格式的資料包,它是一組包含有各種地理位置資訊的字串,字串格式為:
$資訊型別,xxx,xxx,xxx,xxx,xxx,xxx,xxx,
每行開頭的字元都是‘$’,接著是資訊型別,後面是資料,以逗號分隔開。一行完整的資料如下:
$GPRMC,063102.00,A,2932.293196,N,10636.147385,E,0.0,45.5,250818,2.3,W,A*10
資訊型別為:
GPVTG:地面速度資訊
GPRMC:推薦最小定位資訊
GPGSA:當前衛星資訊
GPGGA:GPS定位資訊
GPGSV:可見衛星資訊
這裡我們只解析GPRMC和GPGGA的資訊。
GPRMC資料詳解:
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh
< 1> UTC時間,hhmmss(時分秒)格式
< 2> 定位狀態,A=有效定位,V=無效定位
< 3> 緯度ddmm.mmmm(度分)格式(前面的0也將被傳輸)
< 4> 緯度半球N(北半球)或S(南半球)
< 5> 經度dddmm.mmmm(度分)格式(前面的0也將被傳輸)
< 6> 經度半球E(東經)或W(西經)
< 7> 地面速率(000.0~999.9節,前面的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=資料無效)
解析內容:
1.時間,這個是格林威治時間,是世界時間(UTC),我們需要把它轉換成北京時間(BTC),BTC和UTC差了8個小時,要在這個時間基礎上加8個小時。
2.定位狀態,在接收到有效資料前,這個位是‘V’,後面的資料都為空,接到有效資料後,這個位是‘A’,後面才開始有資料。
3.緯度,我們需要把它轉換成度分秒的格式,計算方法:
如接收到的緯度是:4546.40891
4546.40891 / 100 = 45.4640891 可以直接讀出45度
4546.40891–45 * 100 = 46.40891 可以直接讀出46分
46.40891–46 = 0.40891 * 60 = 24.5346 讀出24秒
所以緯度是:45度46分24秒。
4.南北緯,這個位有兩種值‘N’(北緯)和‘S’(南緯)
5.經度的計算方法和緯度的計算方法一樣
6.東西經,這個位有兩種值‘E’(東經)和‘W’(西經)
7.速率,這個速率值是 海里/時,單位是節,要把它轉換成千米/時,根據:1海里 = 1.85公里,把得到的速率乘以1.85。
8.航向,指的是偏離正北的角度
9.日期,這個日期是準確的,如:200818表示2018年08月20日,這個日期是準確的,不需要轉換。
GPGGA資料詳解
$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*xx
$GPGGA:起始引導符及語句格式說明(本句為GPS定位資料);
<1> UTC時間,格式為hhmmss.sss;
<2> 緯度,格式為ddmm.mmmm(第一位是零也將傳送);
<3> 緯度半球,N或S(北緯或南緯)
<4> 經度,格式為dddmm.mmmm(第一位零也將傳送);
<5> 經度半球,E或W(東經或西經)
<6> 定位質量指示,0=定位無效,1=定位有效;
<7> 使用衛星數量,從00到12(第一個零也將傳送)
<8> 水平精確度,0.5到99.9
<9> 天線離海平面的高度,-9999.9到9999.9米 M 指單位米
<10> 大地水準面高度,-9999.9到9999.9米 M 指單位米
<11> 差分GPS資料期限(RTCM SC-104),最後設立RTCM傳送的秒數量
<12> 差分參考基站標號,從0000到1023(首位0也將傳送)。
2.3 GPS程式設計
GPS解析主要有兩個部分,一個是USB轉串列埠的配置,另外一個就是GPS的解析。下面就一一介紹。
1.串列埠配置
由於我是通過串列埠來進行資料傳輸,也就是把GPS定位的資訊,通過串列埠最後輸出到我們的終端裝置上。
【uart_GPS_config.c】
/**
******************************************************************************
* @file uart_GPS_config.c
* @author Bruceou
* @version V1.0
* @date 2018.04.11
* @brief 串列埠設定
******************************************************************************
*/
/**Includes*********************************************************************/
#include "uart_GPS_config.h"
/**
* @brief 串列埠設定函式
* @param fd
baud_rate
data_bits
parity
stop_bits
* @retval int
*/
int set_GPS_com_config(int fd,int baud_rate,int data_bits, char parity, int stop_bits)
{
struct termios new_cfg;
int speed;
/* 儲存並測試現有串列埠引數設定,在這裡如果串列埠號等出錯,會有相關的出錯資訊 */
if (tcgetattr(fd, &new_cfg) != 0)
{
perror("tcgetattr save");
return -1;
}
//修改控制模式,保證程式不會佔用串列埠
new_cfg.c_cflag |= CLOCAL;
//修改控制模式,使得能夠從串列埠中讀取輸入資料
new_cfg.c_cflag |= CREAD;
new_cfg.c_oflag &= ~(ONLCR | OCRNL);
new_cfg.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
new_cfg.c_iflag &= ~(ICRNL | INLCR);
new_cfg.c_iflag &= ~(IXON | IXOFF | IXANY);
/* 設定波特率 */
switch (baud_rate)
{
case 2400:
{
speed = B2400;
}
break;
case 4800:
{
speed = B4800;
}
break;
case 9600:
{
speed = B9600;
}
break;
case 19200:
{
speed = B19200;
}
break;
case 38400:
{
speed = B38400;
}
break;
default:
case 115200:
{
speed = B115200;
}
break;
}
cfsetispeed(&new_cfg, speed);//輸入波特率
cfsetospeed(&new_cfg, speed);//輸出波特率
switch (data_bits) /* 設定資料位 */
{
case 7:
{
new_cfg.c_cflag |= CS7;
}
break;
default:
case 8:
{
new_cfg.c_cflag |= CS8;
}
break;
}
switch (parity) /* 設定奇偶校驗位 */
{
default:
case 'n':
case 'N':
{
new_cfg.c_cflag &= ~PARENB;
new_cfg.c_iflag &= ~INPCK;
}
break;
case 'o':
case 'O':
{
new_cfg.c_cflag |= (PARODD | PARENB);
new_cfg.c_iflag |= INPCK;
}
break;
case 'e':
case 'E':
{
new_cfg.c_cflag |= PARENB;
new_cfg.c_cflag &= ~PARODD;
new_cfg.c_iflag |= INPCK;
}
break;
case 's': /* as no parity */
case 'S':
{
new_cfg.c_cflag &= ~PARENB;
new_cfg.c_cflag &= ~CSTOPB;
}
break;
}
switch (stop_bits) /* 設定停止位 */
{
default:
case 1:
{
new_cfg.c_cflag &= ~CSTOPB;
}
break;
case 2:
{
new_cfg.c_cflag |= CSTOPB;
}
}
//修改輸出模式,原始資料輸出
new_cfg.c_oflag &= ~OPOST;
new_cfg.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);//我加的
new_cfg.c_lflag &= ~(ISIG | ICANON);
//設定等待時間和最小接收字元
new_cfg.c_cc[VTIME] = 0; /* 讀取一個字元等待0*(0/10)s */
new_cfg.c_cc[VMIN] = 1; /* 讀取字元的最少個數為0 */
//如果發生資料溢位,接收資料,但是不再讀取 重新整理收到的資料但是不讀
tcflush(fd, TCIFLUSH); /* 處理未接收字元 */
if ((tcsetattr(fd, TCSANOW, &new_cfg)) != 0) /* 啟用新配置 */
{
perror("tcsetattr action");
return -1;
}
//printf("serial set success\n");
return 0;
}
/**
* @brief 開啟串列埠函式
* @param com
* @retval int
*/
int open_GPS_port(const char *com_port)
{
int fd;
/*分別為com1,com2, com3對應 ttyS0 ttyS1 ttyS2 */
fd = open( com_port, O_RDWR|O_NOCTTY|O_NDELAY);
if (fd < 0)
{
perror("Can't Open Serial Port");
return -1;
}
/*恢復串列埠為阻塞狀態*/
if (fcntl(fd,F_SETFL,0)<0)
{
perror("fcntl F_SETFL\n");
}
/*測試是否為終端裝置*/
if(isatty(STDIN_FILENO) == 0)
{
perror("standard input is not a terminal device");
}
return fd;
}
/**
* @brief 串列埠初始化函式
* @param com_port
* @retval int
*/
int init_GPS_port(const char *com_port)
{
int fd;
if ((fd = open_GPS_port(com_port)) < 0 )
{
perror("open_port");
return -1;
}
if(set_GPS_com_config(fd,9600,8,'N',1) < 0)
{
perror("set_com_config");
return -1;
}
return fd;
}
【uart_GPS_config.h】
#ifndef _UART_GPS_CONFIG_H_
#define _UART_GPS_CONFIG_H_
#include<errno.h>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<sys/types.h>
#include<sys/stat.h>
#include <termios.h>
#include <fcntl.h>
#include <time.h>
#include <unistd.h>
#include <ctype.h>
#define BUFFER_SIZE 36
#define DEVICE_AT_GPS "/dev/ttyUSB2"
#define DEVICE_DATA_GPS "/dev/ttyUSB1"
int set_GPS_com_config(int fd,int baud_rate, int data_bits,char parity,int stop_bits);
int open_GPS_port(const char *com_port);
int init_GPS_port(const char *com_port);
#endif
2.GPS資料分析
【GPS.c】
/**
******************************************************************************
* @file GPS.c
* @author Bruceou
* @version V1.0
* @date 2018.08.11
* @brief GPS 解析
******************************************************************************
*/
/**Includes*********************************************************************/
#include "GPS.h"
char *buff = NULL;
GPRMC_t gprmc;
GPGGA_t gpgga;
/**
* @brief GPS解析函式
* @param AT_fd:串列埠檔案描述符
* @ DATA_fd:串列埠檔案描述符
* @retval Nono
*/
void GPS_Analysis(int AT_fd,int DATA_fd)
{
int nread,nwrite;
char send_buff[16];
char recv_buff[512];
char *ptr = NULL;
char AT_Buff[16];
int ret = 0;
#if 0
uint32_t time =0;
uint32_t lat =0 ;
uint32_t lon =0;
uint32_t speed =0;
uint32_t head =0;
uint32_t alt =0;
#endif
while(1)
{
memset(AT_Buff,0,sizeof(AT_Buff));
strcpy(AT_Buff, "AT+QGPS=1");
GPS_Set(AT_fd , AT_Buff);
if(buff != NULL)
{
break;
}
memset(AT_Buff,0,sizeof(AT_Buff));
strcpy(AT_Buff, "AT+QGPSEND");
GPS_Set(AT_fd , AT_Buff);
sleep(1);
}
//接收資料
while(1)
{
memset(&gprmc, 0, sizeof(gprmc));
memset(&gpgga, 0, sizeof(gpgga));
memset(recv_buff,0,sizeof(recv_buff));
nread = read(DATA_fd,recv_buff,sizeof(recv_buff));
#ifdef DEBUG_GPS
printf("nread=%d,%s\n",nread,recv_buff);
printf("=================2===================\n");
#endif
//strcpy(buff, recv_buff);
//儲存資料
ptr = strstr(recv_buff, "$GPRMC");
ret = sscanf(ptr, "$GPRMC,%f,%c,%f,%*c,%f,%*c,%f,%f,%d,%f,%*c,%*c*",
&gprmc.time,&gprmc.state, &gprmc.lat, &gprmc.lon,
&gprmc.speed, &gprmc.head, &gprmc.date,&gprmc.dec);
ptr = strstr(recv_buff, "$GPGGA");
ret = sscanf(ptr, "$GPGGA,%f,%f,N,%f,E,%d,%d,%f,%f,M,%f,M,,*",
&gpgga.time, &gpgga.lat, &gpgga.lon,
&gpgga.state, &gpgga.num, &gpgga.hdop, &gpgga.alt, &gpgga.geoid);
#if 0
time = (int)(gprmc.time*100) % 100 + ((int)gprmc.time % 100) * 100 +\
((int)gprmc.time%10000/100) *60 * 100 + ((int)gprmc.time/10000)* 3600 * 100;
lat = ((int)(gprmc.lat/100) + (gprmc.lat-(int)gprmc.lat/100*100)/60)*10000000;
lon = ((int)(gprmc.lon/100) + (gprmc.lon-(int)gprmc.lon/100*100)/60)*10000000;
speed = gprmc.speed* 1.852;
head = gprmc.head;
alt = gpgga.alt;
#endif
//列印資料
print_GPS_RMC(&gprmc);
print_GPS_GGA(&gpgga);
}
}
/**
* @brief GPS開啟函式
* @param AT_fd:串列埠檔案描述符
* @ AT :AT指令
* @retval Nono
*/
void GPS_Set(int AT_fd,char *AT)
{
int nread,nwrite;
char send_buff[16];
char recv_buff[64];
memset(send_buff,0,sizeof(send_buff));
strcpy(send_buff, AT);
strcat(send_buff,"\r");
nwrite = write(AT_fd,send_buff,strlen(send_buff));
#ifdef DEBUG_GPS
printf("nwrite=%d,%s\n",nwrite,send_buff);
#endif
//waiting for AT's ACK等待迴應
memset(recv_buff,0,sizeof(recv_buff));
nread = read(AT_fd,recv_buff,sizeof(recv_buff));
buff = strstr(recv_buff,"OK");
//memset(buff,0,strlen(buff));
#ifdef DEBUG_GPS
printf("nread=%d,%s\n",nread,recv_buff);
printf("================1======================\n");
#endif
}
/**
* @brief GPS-RMC資訊列印
* @param gprmc_data:
* @retval Nono
*/
void print_GPS_RMC(GPRMC_t *gprmc_data)
{
printf(" \n");
printf("===========================================================\n");
printf("== 全球GPS定位導航模組 ==\n");
printf("== Author:BruceOu ==\n");
printf("== Email:[email protected] ==\n");
printf("================RMC資訊====================================\n");
printf("===========================================================\n");
printf("== GPS state bit : %c [A:有效狀態 V:無效狀態] \n",gprmc_data->state);
printf("== Date : 20%02d-%02d-%02d \n",gprmc_data->date%100,(gprmc_data->date%10000)/100,gprmc_data->date/10000);
printf("== 緯度 : 北緯:%d度%d分%d秒 \n",((int)gprmc_data->lat) / 100, (int)(gprmc_data->lat - ((int)gprmc_data->lat / 100 * 100)), (int)(((gprmc_data->lat - ((int)gprmc_data->lat / 100 * 100)) - ((int)gprmc_data->lat - ((int)gprmc_data->lat / 100 * 100))) * 60.0));
printf("== 經度 : 東經:%d度%d分%d秒 \n",((int)gprmc_data->lon) / 100, (int)(gprmc_data->lon - ((int)gprmc_data->lon / 100 * 100
相關推薦
《Linux作業系統-系統移植》第8章 USB-4G/LTE移植 -第3節 USB-4G移植(移遠AG35開發-GPS解析及程式設計)
檢視參考手冊,移遠帶有GPS的晶片的USB Serial如下。
2.1應用簡介
1、若不使用 AT+QGPSCFG 指令對AG35進行配置,則會以預設引數開啟GPS引數,NMEA埠開始上報,"gpsnmeatype"預設值為31,上報間隔為1s,每次上報所有種
《Linux作業系統-系統移植》第8章 USB-4G/LTE移植 -第4節 USB-4G移植(移遠EC20開發-Gobi撥號)
開發環境
主機:ubuntu12.04
開發板核心版本:linux-2.6.35
【注】EC20支援PPP撥號,Gobi撥號和QMI撥號,筆者使用的是Gobi撥號,關於另外兩種撥號請參考官方文件,後文的附件連結中已經給出了參考文件。
3.1 USB Serial
《Linux作業系統-系統移植》第8章 USB-4G/LTE移植 -第2節 USB-4G移植(中興ME3760移植)
ME3760 是一款Mini PCI-E介面的LTE 模組,支援LTE TDD band38(2.6GHz),band39(1.9GHz),band40(2.3GHz); LTE FDD band7(2.6GHz),向下相容TD-SCDMA A頻段(2.1GHz
《Linux作業系統-系統移植》第8章 USB-4G/LTE移植 -第1節 USB-4G移植C(華為E392u924G移植)
1.3 PPP編譯
1.獲取原始碼
PPP官網下載:https://download.samba.org/pub/ppp/
下載解壓ppp-2.4.7.tar.gz原始碼,存放在/home/farsig
《Linux作業系統-系統移植》第8章 USB-4G/LTE移植 -第1節 USB-4G移植 F(華為E392u924G移植)
1.6啟動撥號指令碼
$mkdir shell_script
$cd /shell_script
$ vi usb.sh
輸入以下內容,然後儲存退出。
usb_modeswitch -W -c /etc
《Linux作業系統-系統移植》第7章 工具移植 -第3節 Mini-xml移植
開發環境:
主機環境:Ubuntu 12.04
目標機環境:Exynos4412開發板(Linux 3.0.5)
一個輕量級的xml庫,可完成讀寫。適合系統資源受限的嵌入式裝置。
原始碼下載:https
《Linux作業系統-系統移植》第7章 工具移植 -第2節 SSH服務移植
開發環境:
主機:Ubuntu12.04
開發板:Exynos4412
2.1編譯相關檔案
SSH協議族可以用來進行遠端控制, 附加的SFTP協議可輕鬆實現在計算機之間傳送檔案。而實現此功能的傳統方式,如telnet(終端模擬協議)、 rcp ftp、 rlog
Linux命令應用大詞典-第8章 日期和時間
硬件時鐘 顯示 linu 時鐘 主機 style hwclock 硬件 暫停
8.1 cal:顯示日歷信息
8.2 date:顯示和設置系統日期和時間
8.3 hwclock:查看和設置硬件時鐘
8.4 clock:查看和設置硬件時鐘
8.5 clockdiff:主機之間
【Linux學習筆記】第8章 Linux shell基礎知識
linux centos shell 通配 8.1shell介紹shell是一個命令解釋器,提供人機交互。支持特定語法。每個用戶都可以有自己特定的shell(bash)。CentOS7默認bash(Bourne Agin Shell)。其他還有zsh、ksh等。
8.2命令歷史命令歷史存放於
易學筆記-Linux命令-第8章:從shell眼中看世界
第8章:從shell眼中看世界/8.0 echo:單詞分割機制
echo:單詞分割機制
格式:echo 結果集,這裡的結果集可能是
某個字串:abc
多個字串:abc edf
命令結果: ls
連結裝載與庫 第8章 linux共享庫的組織
由於動態連結的優點,大量的程式使用動態連結機制,導致系統裡面存在數量極為龐大的共享物件。必須得有很好的機制來管理這些共享庫,否則這些共享物件散落在各個目錄下,長期的維護,升級,都有會很大的問題。
8.1 共享庫版本
8.1.1 共享庫的相容性
共享庫的版本會不斷的更新,以修正原有
linux核心設計與實現 —— 中斷和中斷處理(第7章,第8章)
中斷和中斷處理
中斷的目的:讓處理器最快地響應外部硬體的請求。
中斷本質上是一種特殊的電訊號,由硬體裝置發向處理器,處理器反映到作業系統中,最後由作業系統處理這個中斷電訊號。
不同的裝置對應的中斷不同。每個中斷都通過一個唯一的數字標記,這個標記通常被稱為中
第8章第2講特殊函數介紹
turn 函數介紹 spl .cn scan margin urn printf return
#include"stdio.h"
int fact(int n) //求階乘函數
{ int f=1,i;
fo
第8章:Shell腳本歸檔與壓縮
extract config 生成 -- dir exclude 硬盤分區 txt name
第8章:Shell腳本歸檔與壓縮
定期備份不可小視,我們可以通過shell腳本來實現備份自動化。其中數據備份一般要使用到歸檔與壓縮,歸檔與壓縮對於系統
第8章2節《MonkeyRunner源代碼剖析》MonkeyRunner啟動執行過程-解析處理命令行參數
path 轉載 iss 命令 code rst pri bsp ack
MonkeyRunnerStarter是MonkeyRunner啟動時的入口類,由於它裏面包括了main方法.它的整個啟動過程主要做了以下幾件事情:解析用戶啟動MonkeyRunner時從命令行傳輸
第8章 包管理
重新 裝包 自己的 align love ocs 重定向 客戶端程序 target
本文目錄:
8.1 Linux上構建C程序的過程
8.2 包基礎知識
8.3 rpm管理包
8.4 yum管理包
8.5 補丁工具diff和patch
8.6 源碼編譯安裝程序
8.1
【C語言學習】《C Primer Plus》第8章 字符輸入/輸出和輸入確認
multipl 字符輸入 信號 first while 目的 bcd 問題 img
學習總結
1、緩沖區分為完全緩沖區(fully buffered)I/O和行緩沖區(line-buffered)I/O。對完全緩沖輸入來說,當緩沖區滿的時候會被清空(緩沖區內容發送至
Java編程思想讀書筆記_第8章
讀書筆記 div spl class alt oid ava 函數 opened 覆蓋私有方法
1 class Father {
2 private void f() { System.out.println("Father::f()"); }
3
第8章 傳輸層(1)_TCP/UDP協議的應用場景
一個數 選擇 str 根據 connect .cn eight 安全 器) 1. 傳輸層的兩個協議
1.1 TCP和UDP協議的應用場景
(1)TCP協議:如果要傳輸的內容比較多,需要將發送的內容分成多個數據包發送。這就要求在傳輸層用TCP協議,在發送方和接收方建立連接
第8章 傳輸層(2)_UDP協議
之前 用戶數 發送數據 1-1 效率 沒有 strong 而是 系統 2. 用戶數據報協議(UDP)
2.1 UDP的特點
(1)UDP是無連接的,即發送數據之前不需要建立連接,因此減少了開銷和發送數據之前的時延。
(2)UDP使用了盡最大努力交付,即不保證可靠交付,因此主