合軸551G模塊,移植了正點原子的開發板程序
STM32單片機源程序如下:
- #include "gps.h"
- #include "led.h"
- #include "SysTick.h"
- #include "usart3.h"
- #include "stdio.h"
- #include "stdarg.h"
- #include "string.h"
- #include "math.h"
-
-
- 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信息
- }
- }
- //分析BDGSV信息
- //gpsx:nmea信息結構體
- //buf:接收到的GPS數據緩沖區首地址
- void NMEA_BDGSV_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,"$BDGSV");
- len=p1[7]-'0'; //得到BDGSV的條數
- posx=NMEA_Comma_Pos(p1,3); //得到可見北斗衛星總數
- if(posx!=0XFF)gpsx->beidou_svnum=NMEA_Str2num(p1+posx,&dx);
- for(i=0;i<len;i++)
- {
- p1=(u8*)strstr((const char *)p,"$BDGSV");
- for(j=0;j<4;j++)
- {
- posx=NMEA_Comma_Pos(p1,4+j*4);
- if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_num=NMEA_Str2num(p1+posx,&dx); //得到衛星編號
- else break;
- posx=NMEA_Comma_Pos(p1,5+j*4);
- if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_eledeg=NMEA_Str2num(p1+posx,&dx);//得到衛星仰角
- else break;
- posx=NMEA_Comma_Pos(p1,6+j*4);
- if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_azideg=NMEA_Str2num(p1+posx,&dx);//得到衛星方位角
- else break;
- posx=NMEA_Comma_Pos(p1,7+j*4);
- if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_sn=NMEA_Str2num(p1+posx,&dx); //得到衛星信噪比
- else break;
- slx++;
- }
- p=p1+1;//切換到下一個BDGSV信息
- }
- }
- //分析GNGGA信息
- //gpsx:nmea信息結構體
- //buf:接收到的GPS數據緩沖區首地址
- void NMEA_GNGGA_Analysis(nmea_msg *gpsx,u8 *buf)
- {
- u8 *p1,dx;
- u8 posx;
- p1=(u8*)strstr((const char *)buf,"$GNGGA");
- 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,8); //水平位置精度
- if(posx!=0XFF)gpsx->hdop=NMEA_Str2num(p1+posx,&dx);
-
- posx=NMEA_Comma_Pos(p1,9); //得到海拔高度
- if(posx!=0XFF)gpsx->altitude=NMEA_Str2num(p1+posx,&dx);
- }
- //分析GNGSA信息
- //gpsx:nmea信息結構體
- //buf:接收到的GPS數據緩沖區首地址
- void NMEA_GNGSA_Analysis(nmea_msg *gpsx,u8 *buf)
- {
- u8 *p1,dx;
- u8 posx;
- u8 i;
- p1=(u8*)strstr((const char *)buf,"$GNGSA");
- 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);
- }
- //分析GNRMC信息
- //gpsx:nmea信息結構體
- //buf:接收到的GPS數據緩沖區首地址
- void NMEA_GNRMC_Analysis(nmea_msg *gpsx,u8 *buf)
- {
- u8 *p1,dx;
- u8 posx;
- u32 temp;
- float rs;
- p1=(u8*)strstr((const char *)buf,"$GNRMC");//"$GNRMC",經常有&和GNRMC分開的情況,故只判斷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=temp/10000;
- 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,7); //獲取地面速度
- if(posx!=0XFF)gpsx->lspeed=*(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;
- }
- }
- //分析GNVTG信息
- //gpsx:nmea信息結構體
- //buf:接收到的GPS數據緩沖區首地址
- void NMEA_GNVTG_Analysis(nmea_msg *gpsx,u8 *buf)
- {
- u8 *p1,dx;
- u8 posx;
- p1=(u8*)strstr((const char *)buf,"$GNVTG");
- 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_BDGSV_Analysis(gpsx,buf); //BDGSV解析
- NMEA_GNGGA_Analysis(gpsx,buf); //GNGGA解析
- NMEA_GNGSA_Analysis(gpsx,buf); //GPNSA解析
- NMEA_GNRMC_Analysis(gpsx,buf); //GPNMC解析
- NMEA_GNVTG_Analysis(gpsx,buf); //GPNTG解析
- }
- /**********************************
- 功能:發送數據到GPS模塊
- 日期:2022.12.14
- 參數:cmd AT命令
- 返回值: 無
- *****************************/
- void SendAtToGps(u8 *cmd)
- {
- while (*cmd !='\0')
- {
- USART_SendData(USART3,*cmd++);
- while(USART_GetFlagStatus(USART3,USART_FLAG_TXE)==Bit_RESET);
- }
- }
- /****************************
- 功能:檢查GPS模塊應答是否符合預期
- 日期:2022.12.14
- 參數:str 正確應答
- 返回值:無
- ***************************/
- u8 GpsAckChack(u8 *str)
- {
- //u8 str[225];
- delay_ms(500);
- if(USART3_RX_STA !=0)
- {
- USART3_RX_STA=0;
- if(strstr ((const char*)USART3_RX_BUF,(const char*)str))
- {
- memset(USART3_RX_BUF,0, sizeof USART3_RX_BUF); //符合預期
- return 0;
- }
- else
- {
- memset(USART3_RX_BUF,0, sizeof USART3_RX_BUF); //不符合預期
- return 1;
- //清空數組
- }
- }
- else
- {
- memset(USART3_RX_BUF,0, sizeof USART3_RX_BUF);
- return 1;
- }
- }
- /*********************************************
- 功能:GPS模塊初始化
- 日期:2022.12.14
- 參數: 無
- 返回值:無
- *********************************************/
- void Gps_Init()
- {
- cmd1:SendAtToGps (ColdStart); //發送冷啟動指令
- delay_ms(50);
- if(!GpsAckChack ("$GNTXT,GK9701*7E..$GNTXT,HW:V190"));
- else goto cmd1;
- cmd2:SendAtToGps (GPSL1L5); //全系統模式
- delay_ms(50);
- if (!GpsAckChack("$GNTXT,GK9701*7E..$GNTXT,HW:V190")) ;
- else goto cmd2;
- cmd3:SendAtToGps(OpenSBAS); //開啟SBAS 功能
- delay_ms(50);
- if (!GpsAckChack("$GNTXT,GK9701*7E..$GNTXT,HW:V190")) ;
- else goto cmd3;
- cmd4:SendAtToGps(delay1sNMEA); //配置輸出 NMEA 消息的間隔 1s
- delay_ms(50);
- if (!GpsAckChack("$GNTXT,GK9701*7E..$GNTXT,HW:V190")) ;
- else goto cmd4;
- cmd5:SendAtToGps(EnableRMC); //設置 NMEA 語句輸出使能 使能RMC
- delay_ms(50);
- if (!GpsAckChack("$GNTXT,GK9701*7E..$GNTXT,HW:V190")) ;
- else goto cmd5;
- SendAtToGps(MoreFast);//加速定位信息
- }
復制代碼
51hei.png (7.85 KB, 下載次數: 49)
下載附件
2022-12-17 04:40 上傳
Keil代碼下載:
AIR551G.7z
(6.28 MB, 下載次數: 18)
2022-12-17 04:40 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|