《嵌入式系統綜合實驗》報告
學號: 姓名: Shanghai University of Engineering Science School of Electronic and Electrical Engineering
基于 2 STM32 的 的 S GPS 信息 顯示系統
—— 嵌入式系統綜合實驗報告
班級:0211112
姓名:褚建勤 學號:021111228 班級:0211112
姓名:于心憶 學號:021111216 班級:0211112
姓名:樂浩奎 學號:021111232 一、產品設計要求( ( 產品規 格描述) )
1 、嵌入式產品名稱
GPS 信息顯示系統 2 、嵌入式產品目的
在學校的生活中,您經常可能需要聯系不就是同一間宿舍的同學,但就是您不能確定她現在在什么地方,這時候全球定位系統(GPS)就可以發揮作用了,但就是傳統的 GPS 系統只能提供經緯度信息,不能直觀的顯示您想要找到人在何處,我們的系統就在傳統的 GPS 的基礎上添加了對應位置顯示的功能,方便您更方便更快捷的找到您想找的同學 3 、嵌入式產品功能
使用 GPS 輸入用戶位置信息 GPS 將相關經緯度信息反饋給主處理器 主處理器處理相關位置信息并將信息轉換為對應位置在 LCD 上顯示出來 在 LCD 上輸出用戶狀態信息 4 、嵌入式產品的輸入與輸出
輸入設備:GPS 系統 輸出設備:LCD 二、產品方案設計( ( 產品設計方案) )
1 、產品架構設計
2 、產品硬件設計
1 ) 處理器選擇
本系統選用基于 ARMCortex-M3 內核的 STM32F103RB 嵌入式微控制器作為處理器。
①
選用原因 A
技術因素 工作頻率: 最高 72MHz。
內部與外部存儲器: 128K 字節的閃存程序存儲器,用于存放程序及數據;多達 20K 字節的內置 SRAM,CPU 能以 0 等待周期訪問(讀/寫)。
定時器與中斷:包含 1 個高級控制定時器、3 個普通定時器,以及 2 個瞧門狗定時器與 1個系統嘀嗒定時器;內置嵌套的向量式中斷控制器,能夠處理多達43個可屏蔽中斷通道與16個優先級。
IO 接口:通用輸入輸出接口(GPIO)。每個 GPIO 管腳都可以由軟件配置成輸出(推拉或開路)、輸入(帶或不帶上拉或下拉)或其它的外設功能口。多數 GPIO 管腳都與數字或模擬的外設共用。所有的 GPIO 管腳都有大電流通過能力。在需要的情況下,I/O 管腳的外設功能可以通過一個特定的操作鎖定,以避免意外的寫入 I/O 寄存器。在 APB2 上的 I/O 腳可達 18MHzstm32 LCD GPS 模塊
的翻轉速度。
通用同步/異步接受發送器(USART):USART1 接口通信速率可達 4、5 兆位/秒,其她接口的通信速率可達 2、25 兆位/秒。USART 接口具有硬件的 CTS 與 RTS 信號管理、支持 IrDA SIR ENDEC 傳輸編解碼、兼容 ISO7816 的智能卡并提供 LIN 主/從功能。所有 USART 接口都可以使用 DMA 操作。
環境要求:-40°C 至+85°C 溫度范圍。
B
非技術因素 開發及調試工具:Keil MDK
參考資料:STM32F103RBT6 官方資料 操作系統:Windows XP / Windows 7 / Windows 8 內部 AHB 時鐘頻率 :72 MHz。
內部 APB1 時鐘頻率:36 MHz。
內部 APB2 時鐘頻率:72 MHz。
標準工作電壓 VDD:2、0V~3、6V。
模擬部分工作電壓(未使用 ADC):必須與 VDD 相同,最大 3、6V。
模擬部分工作電壓(使用 ADC):必須與 VDD 相同,2、4V~3、6V。
備份部分工作電壓 VBAT:1、8V~3、6V。
電流:睡眠時與工作時差異較大,還與打開的外設多少有關,范圍大約為 4mA~50mA。
存儲溫度:-65 至+150 度。
工作溫度:-40 至+85 度。
3 、產品軟件設計
1 ) 操作系統選擇
無操作系統 2 ) 其她重要器件選擇
D LCD 模塊: :
功能: 主要特性: S GPS 模塊: :
該 GPS 模塊選用的就是型號為 ATK-NEO-M6_V12 的 GPS 模塊,就是 ALIENTEK 生產的一款高性能 GPS 模塊,模塊核心采用 UBLOX 公司的 NEO-M^模組,具有 50 個通道,追蹤靈敏度高達-161dBm,測量輸出頻率最高可達 5HZ。
功能:
實現當前系統位置的定位 主要特性: 1,模塊采用 UBLOX NEO-M6 模組,體積小,性能優異。
2,模組自帶陶瓷天線及 MAXIM 公司 20,5dB 高增益 LNA 芯片,搜星能力強。
3,模組可通過串口進行各種參數設置,并可以保存在 EEPROM,使用方便。
4,模組自帶 IPX 接口,可以連接各種有源天線,適應能力強。
5 模組兼容 3、3V/5、5V 電平,方便連接各種單片機系統。
6,模組自帶可充電后備電源,可以掉電保持星歷?數據 注 ?: : 在主電源斷電后,后備電池可以維持半小時左右的GPS星歷數據的保存,以支持溫啟動或者熱啟動,從而實現快速定位 。
GPS 模塊圖 3 3
) ) 開發環境選擇
本系統選用 KEIL 作為開發環境。
KeiL uVision4 完美支持 Cortex-M、Cortex-R4、ARM7 與 ARM9 系列器件;擁有業行領先的 ARM C/C++編譯工具鏈;提供帶標準驅動類的 USB 設備與 USB 主機棧;為帶圖形用戶接口的嵌入式系統提供了完善的 GUI 庫支持;ULINKpro 可實時分析運行中的應用程序,且能記錄 Cortex-M 指令的每一次執行;執行分析工具與性能分析器可使程序得到最優化等特征。
4 4
) ) 開發語言選擇
產品軟件開發語言:C 語言 C 語言就是一種計算機程序設計語言,它既具有高級語言的特點,又具有匯編語言的特點。它可以作為工作系統設計語言,編寫系統應用程序,也可以作為應用程序設計語言,編寫不依賴計算機硬件的應用程序。它的應用范圍廣泛,具備很強的數據處理能力,不僅僅就是在軟件開發上,而且各類科研都需要用到 C 語言,適于編寫系統軟件,具體應用比如單片機以及嵌入式系統開發。主要優點如下:簡潔緊湊、靈活方便;運算符豐富;數據類型豐富;表達方式靈活實用;允許直接訪問物理地址,對硬件進行操作;生成目標代碼質量高,程序執行效率高;可移植性好;表達力強。由于大一剛進校時就接觸C語言,所以C語言相對我們而言比較熟悉,在編寫中更加容易。
4 、項目組成員分工
姓名 現有工作基礎 項目中 任務 項目中預計總共 工作時間(小時) 組長 褚建勤 C 語言基礎 GPS 90 組員 于心憶 初學 串口 90 組員 樂浩奎 初學 LCD 90 5 、產品開發計劃
時間 任務計劃 1-10 制定嵌入式系統綜合實驗計劃。
11-15 查閱相關書籍,到官方網站下載 GPS 使用說明。
15-30 了解熟悉 AT 指令、串口通信的知識。
31-45 了解熟悉 GPS 相關知識 46-60 完成 GPS 初始化及基礎設置 61-75 添加對應位置顯示功能 76-90 撰寫嵌入式系統綜合實驗報告
6 、產品成本分析 1 )硬件成本清單 產品中硬件材料(如元器件芯片、開發板、仿真器、編程器與測量儀器等)及開發費用(如制板及焊接等費用) 類別 型號∕參數 單價 數量 合計 供應商 聯系人及方式 CPU STM32f103RB 138 1 138 正點原子 … GPS
Neo-6m-v12 85 1 85 青島達英電信器材有限公司
LCD
TFTLCD 2、8
1
★
要求供應商必須就是專業公司非淘寶個人用戶并能開立正規的產品發票 2 )軟件成本清單 產品中所用軟件(如嵌入式開發環境、嵌入式操作系統、GUI 支持包與 TCPIP 協議棧等)費用 類別 名稱 單價 數量 合計 供應商 聯系人及方式 開發環境 Keil uVsion4 0 1 0 無 無 ★
要求供應商必須就是專業公司非淘寶個人用戶并能開立正規的產品發票 3 )人工成本清單
人工成本= 50 小時*10 元/小時*3 人=1500 元
4 )其她成本
無本 5 )產品總成本及分析
產品總成本=硬件成本+軟件成本+人工成本+其她成本=138+ 三、產品實現
1 、硬件實現( ( 必須) )
嵌入式處理器的最小系統圖 GPS 模塊原理圖
嵌入式處理器與 GPS 模塊間的具體連接連線圖硬件連接: STM32 開發板-->ATK-NEO-6M GPS 模塊
PA9 -->RXD
PA10-->TXD
GND -->GND
5V/3、3V-->VCC
2 、軟件實現( ( 必須) )
軟件編程中設計思路(main 主程序流程圖)
GPS 模塊主要函數: u8 NMEA_Comma_Pos(u8 *buf,u8 cx); 功能:分析 GPS 接收到的數據,采用逗號取值法 參數:數據緩存區數據首地址、逗號位置標號: 返回值: 兩個逗號之間的數據 int NMEA_Str2num(u8 *buf,u8*dx); 功能: 把獲取到的字符串轉換為數字 參數:數據緩存區數據首地址、小數點位置 返回值:轉換后的數值 void NMEA_GPGSV_Analysis(nmea_msg *gpsx,u8 *buf); 工能:用來獲取可見衛星的總數、衛星編號、衛星仰角、衛星方位角、信噪比等信息 參數:結構體 gpsx 的首地址、數據緩存區首地址 返回值:無、 $GPGSV 語句的基本格式如下: $GPGSV,(1),(2),(3),(4),(5),(6),(7),、、、,(4),(5),(6),(7)*hh(CR)(LF) (1) GSV 語句總數 (2)本句 GSV 的編號 (3) 可見衛星總數(00~12,前面的 0 也將被傳輸)
(4)衛星編號(01~32,前面的 0 也將被傳輸) (5)衛星仰角(00~90 度,前面的 0 也將被傳輸) (6)衛星方位角(000~359 度,前面的 0 也將被傳輸) (7)信噪比(00~99dB,沒有跟蹤到衛星時為空) void NMEA_GPGGA_Analysis(nmea_msg *gpsx,u8 *buf); 功能:用來獲取 UTC 時間、經緯度、海拔高度等信息 參數:結構體 gpsx 的首地址、數據緩存區首地址 返回值:無 $GPGGA 的語句格式如下: $GPGGA, $GPGGA, $GPGGA,$GPGGA,(1),(2),(3),(4),(5),(6),(7),(8),(9),M, (10 ),M,,M, (11 ),(12 )*hh (CR )( LF ) (1) UTC 時間,格式 hhmmss、ss (2) 緯度 ddmm、mmmmm 度分格式 ); (3) 緯度半球 N 或 S(北緯 或南); (4) 經度,格式為 dddmm、mmm 度分格式; (5) 經度半球 E 或 W(東經 或西); (6) GPSGPS 狀態 ,0= 未定位, 1= 非差分定位, 2=
差分定位 ; (7) 正在使用的于定位衛星數量(00~12) (8) HDOP 水平精確度 因子( 0、5~99、9 ) (9) 海拔 高度 (-9999、9 到 9999、9 米) (10 ) 大地水準面高度(-9999、9
到 9999、9 米) (11 ) 差分 時間(從最近一次接收到差分信號開始的秒數,非定位此項為空)
(12 ) 差分參考基站標號 (0000 到 1023 ,首位 0 也將傳送 ,非差分定位此項為空 void NMEA_GPGSA_Analysis(nmea_msg *gpsx,u8 *buf); 功能:用來獲得衛星號、水平/垂直因子等信息 參數:結構體 gpsx 的首地址、數據緩存區首地址 返回值:無 $GPGSA 的語句格式如下: $GPGSA,(1),(2),(3),(3),(3),(3),(3),(3),(3),(3),(3),(3),(3),(3),(4),(5),(6)*hh(CR)(LF) (1) 模式, M=手動,A=自動 (2) 定位類型,1=為定位,2=2D 定位,3=3D 定位 (3)正在用于定位的衛星號(00~32) (4)PDOP 綜合位置精度因子(0、5~99、9) (5)HDOP 水平精度因子(0、5~99、9) (6)VDOP 垂直精度因子(0、5~99、9) void NMEA_GPRMC_Analysis(nmea_msg *gpsx,u8 *buf); 功能:獲取 UTC 時間、UTC 日期、地面速度等信息 參數:結構體 gpsx 的首地址、數據緩存區首地址 返回值:無 $GP $GPRMC 語句的基本格式如下:
$GPRMC,(1),(2),(3),(4),(5),(6),(7),(8),(9),(10),(11),(12)*(CR)(LF) (1) (1) (1) UTC 時間 hhmmsshhmmss(時分秒) (2)
A= 有效定位, V= 無效定位 無效定 (3) ddmm、mmm (度分) (度分)
(4) 緯度半球 N(北半球)或 S(南半球) (5) 經度 dddmm、mm(度分(度分) (6)經度半球 E(東經)或 W(西經) (7)地面速率 000、0~999、9 節) (8) 地面航向(
000、0~359、9 度,以 真北方 為參考基準)) (9) UTC 日期, 日期, ddmmyyddmmyy
(日月年) (10)磁偏角(000、0~180、0 度,前導位數不足則補 0) (11)磁偏角方向, E(東)或 W(西)
(12)
模式指示( A= 自主定位 D= 差分 E= 估算, N= 數據無效)
void NMEA_GPVTG_Analysis(nmea_msg *gpsx,u8 *buf); 功能:獲取地面航向、地面速率等信息 參數:結構體 gpsx 的首地址、數據緩存區首地址 返回值:無 格式如下: $GPVTG,(1),T,(2),M,(3),N,(4),K, (5)*hh(CR)(LF) (1) 以真北為參考基準的地面航向(000~359 度,前面的 0 也將被傳輸) (2) 以磁北為參考基準的地面航向(000~359 度,前面的 0 也將被傳輸) (3)地面速率(000、0~999、9 節,前面的 0 也將被傳輸) (4)地面速率(0000、0~1851、8 公里/小時,前面的 0 也將被傳輸) (5)模式指示 (A=自主定位,D=差分,E= 估算,N=數據無效) 四、用戶使用說明
該產品就是一個基于 STM32 的校園定位系統,在您接通電源、按下電源后系統能夠精確的顯示出您當前的坐標、時間、以及海拔等信息。
由于室內 GPS 無法接收到信號,該產品只能在室外進行定位 五、產品開發小結
1 、產品完成情況( ( 必須) )
本產品最初的目的就是實現一個個人定位系統、并且實現位置信息的跟蹤,但就是由于技術問題只完成了當前位置的定位。
花費的時間:60 小時 費用: 2 、產品存在問題( ( 必須) )
該產品的定位并不完善,僅僅就是能夠獲取到當前位置,當然如果您就是在我們本校園的話、還可以顯示具體的校園地址信息,比如圖書館、實訓樓、教學樓等信息。但就是有一個問題就就是沒有實現將數據傳輸到手機端或者 PC 端,無法進行位置信息的跟蹤。
3 3 、產品開發過程中的經驗與體會( ( 必須) )
在這次嵌入式的實驗過程中學習到了好多以前沒有接觸過的東西,比如 STM32 開發板的使用,GPS 模塊的使用,在這過程中學會了如何點亮 LCD、LED,如何讓一個 GPS 開始工作、并且把獲取的數據顯示在 LCD 上等等。
如果要自己編寫所有的代碼以我們目前的水平還就是有一定的難度的,所以這次試驗基本上就是在原有的代碼上進行了一定的修改來實現自己的目標程序。通過對代碼的反復讀寫與研究基本上理解了 GPS 的實現過程。
附 附 2: 所有源程序代碼( ( 必須) )
#include "gps、h"
#include "led、h"
#include "delay、h"
#include "usart1、h"
#include "stdio、h"
#include "stdarg、h"
#include "string、h"
#include "math、h" //從 buf 里面得到第 cx 個逗號所在的位置 //返回值:0~0XFE,代表逗號所在位置的偏移、 //
0XFF,代表不存在第 cx 個逗號
u8 NMEA_Comma_Pos(u8 *buf,u8 cx) {
u8 *p=buf;
while(cx)
{
if(*buf=="*"||*buf<" "||*buf>"z")return 0XFF;//遇到"*"或者非法字符,則不存在第 cx 個逗號
if(*buf==",")cx--;
buf++;
}
return buf-p;
} //m^n 函數 //返回值:m^n 次方、 u32 NMEA_Pow(u8 m,u8 n) {
u32 result=1;
while(n--)result*=m;
return result; }
//str 轉換為數字,以","或者"*"結束 //buf:數字存儲區 //dx:小數點位數,返回給調用函數 //返回值:轉換后的數值 int NMEA_Str2num(u8 *buf,u8*dx) {
u8 *p=buf;
u32 ires=0,fres=0;
u8 ilen=0,flen=0,i;
u8 mask=0;
int res;
while(1) //得到整數與小數的長度
{
if(*p=="-"){mask|=0X02;p++;}//就是負數
if(*p==","||(*p=="*"))break;//遇到結束了
if(*p=="、"){mask|=0X01;p++;}//遇到小數點了
else if(*p>"9"||(*p<"0")) //有非法字符
{
ilen=0;
flen=0;
break;
}
if(mask&0X01)flen++;
else ilen++;
p++;
}
if(mask&0X02)buf++; //去掉負號
for(i=0;i<ilen;i++) //得到整數部分數據
{
ires+=NMEA_Pow(10,ilen-1-i)*(buf[i]-"0");
}
if(flen>5)flen=5; //最多取 5 位小數
*dx=flen;
//小數點位數
for(i=0;i<flen;i++) //得到小數部分數據
{
fres+=NMEA_Pow(10,flen-1-i)*(buf[ilen+1+i]-"0");
}
res=ires*NMEA_Pow(10,flen)+fres;
if(mask&0X02)res=-res;
return res; }
//分析 GPGSV 信息 //gpsx:nmea 信息結構體 //buf:接收到的 GPS 數據緩沖區首地址 void NMEA_GPGSV_Analysis(nmea_msg *gpsx,u8 *buf) {
u8 *p,*p1,dx;
u8 len,i,j,slx=0;
u8 posx;
p=buf;
p1=(u8*)strstr((const char *)p,"$GPGSV");
len=p1[7]-"0";
//得到 GPGSV 的條數
posx=NMEA_Comma_Pos(p1,3);
//得到可見衛星總數
if(posx!=0XFF)gpsx->svnum=NMEA_Str2num(p1+posx,&dx);
for(i=0;i<len;i++)
{
p1=(u8*)strstr((const char *)p,"$GPGSV");
for(j=0;j<4;j++)
{
posx=NMEA_Comma_Pos(p1,4+j*4);
if(posx!=0XFF)gpsx->slmsg[slx]、num=NMEA_Str2num(p1+posx,&dx); //得到衛星編號
else break;
posx=NMEA_Comma_Pos(p1,5+j*4);
if(posx!=0XFF)gpsx->slmsg[slx]、eledeg=NMEA_Str2num(p1+posx,&dx);//得到衛星仰角
else break;
posx=NMEA_Comma_Pos(p1,6+j*4);
if(posx!=0XFF)gpsx->slmsg[slx]、azideg=NMEA_Str2num(p1+posx,&dx);//得到衛星方位角
else break;
posx=NMEA_Comma_Pos(p1,7+j*4);
if(posx!=0XFF)gpsx->slmsg[slx]、sn=NMEA_Str2num(p1+posx,&dx); //得到衛星信噪比
else break;
slx++;
}
p=p1+1;//切換到下一個 GPGSV 信息
}
} //分析 GPGGA 信息 //gpsx:nmea 信息結構體 //buf:接收到的 GPS 數據緩沖區首地址 void NMEA_GPGGA_Analysis(nmea_msg *gpsx,u8 *buf) {
u8 *p1,dx;
u8 posx;
p1=(u8*)strstr((const char *)buf,"$GPGGA");
posx=NMEA_Comma_Pos(p1,6);
//得到 GPS 狀態
if(posx!=0XFF)gpsx->gpssta=NMEA_Str2num(p1+posx,&dx);
posx=NMEA_Comma_Pos(p1,7);
//得到用于定位的衛星數
if(posx!=0XFF)gpsx->posslnum=NMEA_Str2num(p1+posx,&dx);
posx=NMEA_Comma_Pos(p1,9);
//得到海拔高度
if(posx!=0XFF)gpsx->altitude=NMEA_Str2num(p1+posx,&dx);
} //分析 GPGSA 信息 //gpsx:nmea 信息結構體 //buf:接收到的 GPS 數據緩沖區首地址 void NMEA_GPGSA_Analysis(nmea_msg *gpsx,u8 *buf) {
u8 *p1,dx;
u8 posx;
u8 i;
p1=(u8*)strstr((const char *)buf,"$GPGSA");
posx=NMEA_Comma_Pos(p1,2);
//得到定位類型
if(posx!=0XFF)gpsx->fixmode=NMEA_Str2num(p1+posx,&dx);
for(i=0;i<12;i++)
//得到定位衛星編號
{
posx=NMEA_Comma_Pos(p1,3+i);
if(posx!=0XFF)gpsx->possl[i]=NMEA_Str2num(p1+posx,&dx);
else break;
}
posx=NMEA_Comma_Pos(p1,15);
//得到 PDOP 位置精度因子
if(posx!=0XFF)gpsx->pdop=NMEA_Str2num(p1+posx,&dx);
posx=NMEA_Comma_Pos(p1,16);
//得到 HDOP 位置精度因子
if(posx!=0XFF)gpsx->hdop=NMEA_Str2num(p1+posx,&dx);
posx=NMEA_Comma_Pos(p1,17);
//得到 VDOP 位置精度因子
if(posx!=0XFF)gpsx->vdop=NMEA_Str2num(p1+posx,&dx);
} //分析 GPRMC 信息 //gpsx:nmea 信息結構體
//buf:接收到的 GPS 數據緩沖區首地址 void NMEA_GPRMC_Analysis(nmea_msg *gpsx,u8 *buf) {
u8 *p1,dx;
u8 posx;
u32 temp;
float rs;
p1=(u8*)strstr((const char *)buf,"GPRMC");//"$GPRMC",經常有&與 GPRMC 分開的情況,故只判斷GPRMC、
posx=NMEA_Comma_Pos(p1,1);
//得到 UTC 時間
if(posx!=0XFF)
{
temp=NMEA_Str2num(p1+posx,&dx)/NMEA_Pow(10,dx);
//得到 UTC 時間,去掉 ms
gpsx->utc、hour=8+temp/10000;
if(gpsx->utc、hour>=24)
{
gpsx->utc、hour=gpsx->utc、hour-24;
}
gpsx->utc、min=(temp/100)%100;
gpsx->utc、sec=temp%100;
}
posx=NMEA_Comma_Pos(p1,3);
//得到緯度
if(posx!=0XFF)
{
temp=NMEA_Str2num(p1+posx,&dx);
gpsx->latitude=temp/NMEA_Pow(10,dx+2); //得到°
rs=temp%NMEA_Pow(10,dx+2);
//得到"
gpsx->latitude=gpsx->latitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//轉換為°
}
posx=NMEA_Comma_Pos(p1,4);
//南緯還就是北緯
if(posx!=0XFF)gpsx->nshemi=*(p1+posx);
posx=NMEA_Comma_Pos(p1,5);
//得到經度
if(posx!=0XFF)
{
temp=NMEA_Str2num(p1+posx,&dx);
gpsx->longitude=temp/NMEA_Pow(10,dx+2); //得到°
rs=temp%NMEA_Pow(10,dx+2);
//得到"
gpsx->longitude=gpsx->longitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;// 轉 換為°
}
posx=NMEA_Comma_Pos(p1,6);
//東經還就是西經
if(posx!=0XFF)gpsx->ewhemi=*(p1+posx);
posx=NMEA_Comma_Pos(p1,9);
//得到 UTC 日期
if(posx!=0XFF)
{
temp=NMEA_Str2num(p1+posx,&dx);
//得到 UTC 日期
gpsx->utc、date=temp/10000;
gpsx->utc、month=(temp/100)%100;
gpsx->utc、year=2000+temp%100;
}
} //分析 GPVTG 信息 //gpsx:nmea 信息結構體 //buf:接收到的 GPS 數據緩沖區首地址 void NMEA_GPVTG_Analysis(nmea_msg *gpsx,u8 *buf) {
u8 *p1,dx;
u8 posx;
p1=(u8*)strstr((const char *)buf,"$GPVTG");
posx=NMEA_Comma_Pos(p1,7);
//得到地面速率
if(posx!=0XFF)
{
gpsx->speed=NMEA_Str2num(p1+posx,&dx);
if(dx<3)gpsx->speed*=NMEA_Pow(10,3-dx);
//確保擴大 1000 倍
} }
//提取 NMEA-0183 信息 //gpsx:nmea 信息結構體 //buf:接收到的 GPS 數據緩沖區首地址 void GPS_Analysis(nmea_msg *gpsx,u8 *buf) {
NMEA_GPGSV_Analysis(gpsx,buf); //GPGSV 解析
NMEA_GPGGA_Analysis(gpsx,buf); //GPGGA 解析
NMEA_GPGSA_Analysis(gpsx,buf); //GPGSA 解析
NMEA_GPRMC_Analysis(gpsx,buf); //GPRMC 解析
NMEA_GPVTG_Analysis(gpsx,buf); //GPVTG 解析 } //GPS 校驗與計算 //buf:數據緩存區首地址 //len:數據長度 //cka,ckb:兩個校驗結果、 void Ublox_CheckSum(u8 *buf,u16 len,u8* cka,u8*ckb) {
u16 i;
*cka=0;*ckb=0;
for(i=0;i<len;i++)
{
*cka=*cka+buf[i];
*ckb=*ckb+*cka;
} } /////////////////////////////////////////UBLOX 配置代碼///////////////////////////////////// //檢查 CFG 配置執行情況 //返回值:0,ACK 成功 //
1,接收超時錯誤 //
2,沒有找到同步字符 //
3,接收到 NACK 應答 u8 Ublox_Cfg_Ack_Check(void) {
u16 len=0,i;
u8 rval=0;
while((USART1_RX_STA&0X8000)==0 && len<100)//等待接收到應答
{
len++;
delay_ms(5);
}
if(len<250)
//超時錯誤、
{
len=USART1_RX_STA&0X7FFF; //此次接收到的數據長度
for(i=0;i<len;i++)if(USART1_RX_BUF[i]==0XB5)break;//查找同步字符 0XB5
if(i==len)rval=2;
//沒有找到同步字符
else if(USART1_RX_BUF[i+3]==0X00)rval=3;//接收到 NACK 應答
else rval=0;
//接收到 ACK 應答
}else rval=1;
//接收超時錯誤
USART1_RX_STA=0;
//清除接收
return rval;
} //配置保存 //將當前配置保存在外部 EEPROM 里面
//返回值:0,執行成功;1,執行失敗、 u8 Ublox_Cfg_Cfg_Save(void) {
u8 i;
_ublox_cfg_cfg *cfg_cfg=(_ublox_cfg_cfg *)USART1_TX_BUF;
cfg_cfg->header=0X62B5;
//cfg header
cfg_cfg->id=0X0906;
//cfg cfg id
cfg_cfg->dlength=13;
//數據區長度為 13 個字節、
cfg_cfg->clearmask=0;
//清除掩碼為 0
cfg_cfg->savemask=0XFFFF;
//保存掩碼為 0XFFFF
cfg_cfg->loadmask=0;
//加載掩碼為 0
cfg_cfg->devicemask=4;
//保存在 EEPROM 里面
Ublox_CheckSum((u8*)(&cfg_cfg->id),sizeof(_ublox_cfg_cfg)-4,&cfg_cfg->cka,&cfg_cfg->ckb);
while(DMA1_Channel4->CNDTR!=0); //等待通道 7 傳輸完成
UART_DMA_Enable(DMA1_Channel4,sizeof(_ublox_cfg_cfg)); //通過 dma 發送出去
for(i=0;i<6;i++)if(Ublox_Cfg_Ack_Check()==0)break;
//EEPROM 寫入需要比較久時間,所以連續判斷多次
return i==6?1:0; } //配置 NMEA 輸出信息格式 //msgid:要操作的 NMEA 消息條目,具體見下面的參數表 //
00,GPGGA;01,GPGLL;02,GPGSA; //
03,GPGSV;04,GPRMC;05,GPVTG; //
06,GPGRS;07,GPGST;08,GPZDA; //
09,GPGBS;0A,GPDTM;0D,GPGNS; //uart1set:0,輸出關閉;1,輸出開啟、
//返回值:0,執行成功;其她,執行失敗、 u8 Ublox_Cfg_Msg(u8 msgid,u8 uart1set) {
_ublox_cfg_msg *cfg_msg=(_ublox_cfg_msg *)USART1_TX_BUF;
cfg_msg->header=0X62B5;
//cfg header
cfg_msg->id=0X0106;
//cfg msg id
cfg_msg->dlength=8;
//數據區長度為 8 個字節、
cfg_msg->msgclass=0XF0;
//NMEA 消息
cfg_msg->msgid=msgid;
//要操作的 NMEA 消息條目
cfg_msg->iicset=1;
//默認開啟
cfg_msg->uart1set=uart1set; //開關設置
cfg_msg->uart2set=1;
//默認開啟
cfg_msg->usbset=1;
//默認開啟
cfg_msg->spiset=1;
//默認開啟
cfg_msg->ncset=1;
//默認開啟
Ublox_CheckSum((u8*)(&cfg_msg->id),sizeof(_ublox_cfg_msg)-4,&cfg_msg->cka,&cfg_msg->ckb);
while(DMA1_Channel4->CNDTR!=0); //等待通道 7 傳輸完成
UART_DMA_Enable(DMA1_Channel4,sizeof(_ublox_cfg_msg)); //通過 dma 發送出去
return Ublox_Cfg_Ack_Check(); } //配置 NMEA 輸出信息格式 //baudrate:波特率,4800/9600/19200/38400/57600/115200/230400
//返回值:0,執行成功;其她,執行失敗(這里不會返回 0 了) u8 Ublox_Cfg_Prt(u32 baudrate) {
_ublox_cfg_prt *cfg_prt=(_ublox_cfg_prt *)USART1_TX_BUF;
cfg_prt->header=0X62B5;
//cfg header
cfg_prt->id=0X0006;
//cfg prt id
cfg_prt->dlength=20;
//數據區長度為 20 個字節、
cfg_prt->portid=1;
//操作串口 1
cfg_prt->reserved=0;
//保留字節,設置為 0
cfg_prt->txready=0;
//TX Ready 設置為 0
cfg_prt->mode=0X08D0;
//8 位,1 個停止位,無校驗位
cfg_prt->baudrate=baudrate; //波特率設置
cfg_prt->inprotomask=0X0007;//0+1+2
cfg_prt->outprotomask=0X0007;//0+1+2
cfg_prt->reserved4=0;
//保留字節,設置為 0
cfg_prt->reserved5=0;
//保留字節,設置為 0
Ublox_CheckSum((u8*)(&cfg_prt->id),sizeof(_ublox_cfg_prt)-4,&cfg_prt->cka,&cfg_prt->ckb);
while(DMA1_Channel4->CNDTR!=0); //等待通道 7 傳輸完成
UART_DMA_Enable(DMA1_Channel4,sizeof(_ublox_cfg_prt)); //通過 dma 發送出去
delay_ms(200);
//等待發送完成
USART1_Init(baudrate); //重新初始化串口 1
return Ublox_Cfg_Ack_Check();//這里不會反回 0,因為 UBLOX 發回來的應答在串口重新初始化的時候已經被丟棄了、 }
//配置 UBLOX NEO-6 的時鐘脈沖輸出 //interval:脈沖間隔(us) //length:脈沖寬度(us) //status:脈沖配置:1,高電平有效;0,關閉;-1,低電平有效、 //返回值:0,發送成功;其她,發送失敗、 u8 Ublox_Cfg_Tp(u32 interval,u32 length,signed char status) {
_ublox_cfg_tp *cfg_tp=(_ublox_cfg_tp *)USART1_TX_BUF;
cfg_tp->header=0X62B5;
//cfg header
cfg_tp->id=0X0706;
//cfg tp id
cfg_tp->dlength=20;
//數據區長度為 20 個字節、
cfg_tp->interval=interval; //脈沖間隔,us
cfg_tp->length=length;
//脈沖寬度,us
cfg_tp->status=status;
//時鐘脈沖配置
cfg_tp->timeref=0;
//參考 UTC 時間
cfg_tp->flags=0;
//flags 為 0
cfg_tp->reserved=0;
//保留位為 0
cfg_tp->antdelay=820;
//天線延時為 820ns
cfg_tp->rfdelay=0;
//RF 延時為 0ns
cfg_tp->userdelay=0;
//用戶延時為 0ns
Ublox_CheckSum((u8*)(&cfg_tp->id),sizeof(_ublox_cfg_tp)-4,&cfg_tp->cka,&cfg_tp->ckb);
while(DMA1_Channel4->CNDTR!=0); //等待通道 7 傳輸完成
UART_DMA_Enable(DMA1_Channel4,sizeof(_ublox_cfg_tp)); //通過 dma 發送出去
return Ublox_Cfg_Ack_Check(); } //配置 UBLOX NEO-6 的更新速率
//measrate:測量時間間隔,單位為 ms,最少不能小于 200ms(5Hz) //reftime:參考時間,0=UTC Time;1=GPS Time(一般設置為 1) //返回值:0,發送成功;其她,發送失敗、 u8 Ublox_Cfg_Rate(u16 measrate,u8 reftime) {
_ublox_cfg_rate *cfg_rate=(_ublox_cfg_rate *)USART1_TX_BUF;
if(measrate<200)return 1; //小于 200ms,直接退出
cfg_rate->header=0X62B5; //cfg header
cfg_rate->id=0X0806;
//cfg rate id
cfg_rate->dlength=6;
//數據區長度為 6 個字節、
cfg_rate->measrate=measrate;//脈沖間隔,us
cfg_rate->navrate=1;
//導航速率(周期),固定為 1
cfg_rate->timeref=reftime;
//參考時間為 GPS 時間
Ublox_CheckSum((u8*)(&cfg_rate->id),sizeof(_ublox_cfg_rate)-4,&cfg_rate->cka,&cfg_rate->ckb);
while(DMA1_Channel4->CNDTR!=0); //等待通道 7 傳輸完成
UART_DMA_Enable(DMA1_Channel4,sizeof(_ublox_cfg_rate));//通過 dma 發送出去
return Ublox_Cfg_Ack_Check(); }
推薦訪問: 嵌入式 實驗 報告上一篇:網絡協議分析實驗報告
同志們:今天這個大會,是市委全面落實黨要管黨、從嚴治黨要求的一項重大舉措,也是對縣市區委書記履行基層黨建工作第一責任人情況的一次集中檢閱,同時是對全市基層黨建工作的一次再部署、再落實的會議。前面,**
***年,我認真履行領班子、帶隊伍、抓黨員、保穩定的基層黨建工作思路,以學習貫徹習近平新時代中國特色社會主義思想和黨的十九大歷次全會精神為主線,以市局基層黨建工作考核細則為落腳點,落實全面從嚴治黨主體
根據會議安排,現將2022年履行抓基層黨建工作職責情況報告如下:一、履職工作特色和亮點1 突出政治建設,著力在思想認識上提高。牢固樹立抓黨建就是抓政績的理念,以“黨建工作抓引領、社區治理求突破,為民服
2022年以來,在**黨委的正確領導下,堅持以習近平新時代中國特色社會主義思想為指導,深入學習宣傳貫徹黨的二十大精神,以黨建工作為統領,扎實開展夯實“三個基本”活動,以“四化四力”行動為抓手,聚力創建
各位領導,同志們:根據會議安排,現就2022年度抓基層黨建工作情況匯報如下:一、主要做法及成效(一)強化政治引領。一是不斷強化理論武裝。堅持通過黨組會、中心組學習會和“三會一課”,第一時間、第一議題學
2022年度抓基層黨建工作述職報告按照黨委工作部署,現將本人2022年度抓基層黨建工作情況報告如下:一、2022年度抓基層黨建工作情況(一)旗幟鮮明講政治將旗幟鮮明講政治放在全局發展首要位置,積極開展
2022年,是我在數計系黨總支書記這個新崗位上度過的第一個完整的工作年度。回首一年來在校黨委的正確領導下,與數計系領導班子和全體師生共同走過的日子,艱辛歷歷在目,收獲溫潤心田。作為黨總支書記,我始終牢
按照考核要求,現將本人一年來,作為統戰部長履行職責、廉潔自律等方面情況報告如下:一、著眼增強政治素質,不斷深化理論學習堅持把旗幟鮮明講政治作為履職從政的第一位要求,帶領統戰系統干部堅決擁護“兩個確立”
**年,緊緊圍繞黨工委、管委會的決策部署,全體人員團結協作、凝心聚力,緊扣黨工委“**”基本工作思路,全力開拓進取,認真履職盡責,圓滿完成各項工作任務。一、個人思想政治狀況檸檬文苑www bgzjy
按照縣委關于開展抓基層黨建述職評議會議的有關要求,經請示縣委組織部同意,今天,我們在此召開2022年度基層黨組織書記抓基層黨建述職評議會議。1 首先,請**黨委書記,**同志述職。**黨委能夠主動研究