久久久久久久999_99精品久久精品一区二区爱城_成人欧美一区二区三区在线播放_国产精品日本一区二区不卡视频_国产午夜视频_欧美精品在线观看免费

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 1804|回復: 0
打印 上一主題 下一主題
收起左側

STM32單片機AIR551G GPS定位程序

[復制鏈接]
跳轉到指定樓層
樓主
合軸551G模塊,移植了正點原子的開發板程序

STM32單片機源程序如下:
  1. #include "gps.h"
  2. #include "led.h"
  3. #include "SysTick.h"                                                           
  4. #include "usart3.h"                                                                    
  5. #include "stdio.h"         
  6. #include "stdarg.h"         
  7. #include "string.h"         
  8. #include "math.h"
  9.          

  10.                                                   
  11. u8 NMEA_Comma_Pos(u8 *buf,u8 cx)
  12. {                             
  13.         u8 *p=buf;
  14.         while(cx)
  15.         {                 
  16.                 if(*buf=='*'||*buf<' '||*buf>'z')return 0XFF;//遇到'*'或者非法字符,則不存在第cx個逗號
  17.                 if(*buf==',')cx--;
  18.                 buf++;
  19.         }
  20.         return buf-p;         
  21. }
  22. //m^n函數
  23. //返回值:m^n次方.
  24. u32 NMEA_Pow(u8 m,u8 n)
  25. {
  26.         u32 result=1;         
  27.         while(n--)result*=m;   
  28.         return result;
  29. }
  30. //str轉換為數字,以','或者'*'結束
  31. //buf:數字存儲區
  32. //dx:小數點位數,返回給調用函數
  33. //返回值:轉換后的數值
  34. int NMEA_Str2num(u8 *buf,u8*dx)
  35. {
  36.         u8 *p=buf;
  37.         u32 ires=0,fres=0;
  38.         u8 ilen=0,flen=0,i;
  39.         u8 mask=0;
  40.         int res;
  41.         while(1) //得到整數和小數的長度
  42.         {
  43.                 if(*p=='-'){mask|=0X02;p++;}//是負數
  44.                 if(*p==','||(*p=='*'))break;//遇到結束了
  45.                 if(*p=='.'){mask|=0X01;p++;}//遇到小數點了
  46.                 else if(*p>'9'||(*p<'0'))        //有非法字符
  47.                 {        
  48.                         ilen=0;
  49.                         flen=0;
  50.                         break;
  51.                 }        
  52.                 if(mask&0X01)flen++;
  53.                 else ilen++;
  54.                 p++;
  55.         }
  56.         if(mask&0X02)buf++;        //去掉負號
  57.         for(i=0;i<ilen;i++)        //得到整數部分數據
  58.         {  
  59.                 ires+=NMEA_Pow(10,ilen-1-i)*(buf[i]-'0');
  60.         }
  61.         if(flen>5)flen=5;        //最多取5位小數
  62.         *dx=flen;                         //小數點位數
  63.         for(i=0;i<flen;i++)        //得到小數部分數據
  64.         {  
  65.                 fres+=NMEA_Pow(10,flen-1-i)*(buf[ilen+1+i]-'0');
  66.         }
  67.         res=ires*NMEA_Pow(10,flen)+fres;
  68.         if(mask&0X02)res=-res;                  
  69.         return res;
  70. }                                                                  
  71. //分析GPGSV信息    可見衛星信息
  72. //gpsx:nmea信息結構體
  73. //buf:接收到的GPS數據緩沖區首地址
  74. void NMEA_GPGSV_Analysis(nmea_msg *gpsx,u8 *buf)
  75. {
  76.         u8 *p,*p1,dx;
  77.         u8 len,i,j,slx=0;
  78.         u8 posx;            
  79.         p=buf;
  80.         p1=(u8*)strstr((const char *)p,"$GPGSV");
  81.         len=p1[7]-'0';                                                                //得到GPGSV的條數
  82.         posx=NMEA_Comma_Pos(p1,3);                                         //得到可見衛星總數
  83.         if(posx!=0XFF)gpsx->svnum=NMEA_Str2num(p1+posx,&dx);
  84.         for(i=0;i<len;i++)
  85.         {         
  86.                 p1=(u8*)strstr((const char *)p,"$GPGSV");  
  87.                 for(j=0;j<4;j++)
  88.                 {         
  89.                         posx=NMEA_Comma_Pos(p1,4+j*4);
  90.                         if(posx!=0XFF)gpsx->slmsg[slx].num=NMEA_Str2num(p1+posx,&dx);        //得到衛星編號
  91.                         else break;
  92.                         posx=NMEA_Comma_Pos(p1,5+j*4);
  93.                         if(posx!=0XFF)gpsx->slmsg[slx].eledeg=NMEA_Str2num(p1+posx,&dx);//得到衛星仰角
  94.                         else break;
  95.                         posx=NMEA_Comma_Pos(p1,6+j*4);
  96.                         if(posx!=0XFF)gpsx->slmsg[slx].azideg=NMEA_Str2num(p1+posx,&dx);//得到衛星方位角
  97.                         else break;
  98.                         posx=NMEA_Comma_Pos(p1,7+j*4);
  99.                         if(posx!=0XFF)gpsx->slmsg[slx].sn=NMEA_Str2num(p1+posx,&dx);        //得到衛星信噪比
  100.                         else break;
  101.                         slx++;           
  102.                 }   
  103.                  p=p1+1;//切換到下一個GPGSV信息
  104.         }   
  105. }
  106. //分析BDGSV信息
  107. //gpsx:nmea信息結構體
  108. //buf:接收到的GPS數據緩沖區首地址
  109. void NMEA_BDGSV_Analysis(nmea_msg *gpsx,u8 *buf)
  110. {
  111.         u8 *p,*p1,dx;
  112.         u8 len,i,j,slx=0;
  113.         u8 posx;            
  114.         p=buf;
  115.         p1=(u8*)strstr((const char *)p,"$BDGSV");
  116.         len=p1[7]-'0';                                                                //得到BDGSV的條數
  117.         posx=NMEA_Comma_Pos(p1,3);                                         //得到可見北斗衛星總數
  118.         if(posx!=0XFF)gpsx->beidou_svnum=NMEA_Str2num(p1+posx,&dx);
  119.         for(i=0;i<len;i++)
  120.         {         
  121.                 p1=(u8*)strstr((const char *)p,"$BDGSV");  
  122.                 for(j=0;j<4;j++)
  123.                 {         
  124.                         posx=NMEA_Comma_Pos(p1,4+j*4);
  125.                         if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_num=NMEA_Str2num(p1+posx,&dx);        //得到衛星編號
  126.                         else break;
  127.                         posx=NMEA_Comma_Pos(p1,5+j*4);
  128.                         if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_eledeg=NMEA_Str2num(p1+posx,&dx);//得到衛星仰角
  129.                         else break;
  130.                         posx=NMEA_Comma_Pos(p1,6+j*4);
  131.                         if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_azideg=NMEA_Str2num(p1+posx,&dx);//得到衛星方位角
  132.                         else break;
  133.                         posx=NMEA_Comma_Pos(p1,7+j*4);
  134.                         if(posx!=0XFF)gpsx->beidou_slmsg[slx].beidou_sn=NMEA_Str2num(p1+posx,&dx);        //得到衛星信噪比
  135.                         else break;
  136.                         slx++;           
  137.                 }   
  138.                  p=p1+1;//切換到下一個BDGSV信息
  139.         }   
  140. }
  141. //分析GNGGA信息
  142. //gpsx:nmea信息結構體
  143. //buf:接收到的GPS數據緩沖區首地址
  144. void NMEA_GNGGA_Analysis(nmea_msg *gpsx,u8 *buf)
  145. {
  146.         u8 *p1,dx;                        
  147.         u8 posx;   
  148.         p1=(u8*)strstr((const char *)buf,"$GNGGA");
  149.         posx=NMEA_Comma_Pos(p1,6);                                                                //得到GPS狀態
  150.         if(posx!=0XFF)gpsx->gpssta=NMEA_Str2num(p1+posx,&dx);        
  151.         posx=NMEA_Comma_Pos(p1,7);                                                                //得到用于定位的衛星數
  152.         if(posx!=0XFF)gpsx->posslnum=NMEA_Str2num(p1+posx,&dx);
  153.         
  154.         posx=NMEA_Comma_Pos(p1,8);                                                                //水平位置精度
  155.         if(posx!=0XFF)gpsx->hdop=NMEA_Str2num(p1+posx,&dx);
  156.         
  157.         posx=NMEA_Comma_Pos(p1,9);                                                                //得到海拔高度  
  158.         if(posx!=0XFF)gpsx->altitude=NMEA_Str2num(p1+posx,&dx);  
  159. }
  160. //分析GNGSA信息
  161. //gpsx:nmea信息結構體
  162. //buf:接收到的GPS數據緩沖區首地址
  163. void NMEA_GNGSA_Analysis(nmea_msg *gpsx,u8 *buf)
  164. {
  165.         u8 *p1,dx;                        
  166.         u8 posx;
  167.         u8 i;   
  168.         p1=(u8*)strstr((const char *)buf,"$GNGSA");
  169.         posx=NMEA_Comma_Pos(p1,2);                                                                //得到定位類型
  170.         if(posx!=0XFF)gpsx->fixmode=NMEA_Str2num(p1+posx,&dx);        
  171.         for(i=0;i<12;i++)                                                                                //得到定位衛星編號
  172.         {
  173.                 posx=NMEA_Comma_Pos(p1,3+i);                                         
  174.                 if(posx!=0XFF)gpsx->possl[i]=NMEA_Str2num(p1+posx,&dx);
  175.                 else break;
  176.         }                                 
  177.         posx=NMEA_Comma_Pos(p1,15);                                                                //得到PDOP位置精度因子
  178.         if(posx!=0XFF)gpsx->pdop=NMEA_Str2num(p1+posx,&dx);  
  179.         posx=NMEA_Comma_Pos(p1,16);                                                                //得到HDOP位置精度因子
  180.         if(posx!=0XFF)gpsx->hdop=NMEA_Str2num(p1+posx,&dx);  
  181.         posx=NMEA_Comma_Pos(p1,17);                                                                //得到VDOP位置精度因子
  182.         if(posx!=0XFF)gpsx->vdop=NMEA_Str2num(p1+posx,&dx);  
  183. }
  184. //分析GNRMC信息
  185. //gpsx:nmea信息結構體
  186. //buf:接收到的GPS數據緩沖區首地址
  187. void NMEA_GNRMC_Analysis(nmea_msg *gpsx,u8 *buf)
  188. {
  189.         u8 *p1,dx;                        
  190.         u8 posx;     
  191.         u32 temp;           
  192.         float rs;  
  193.         p1=(u8*)strstr((const char *)buf,"$GNRMC");//"$GNRMC",經常有&和GNRMC分開的情況,故只判斷GPRMC.
  194.         posx=NMEA_Comma_Pos(p1,1);                                                                //得到UTC時間
  195.         if(posx!=0XFF)
  196.         {
  197.                 temp=NMEA_Str2num(p1+posx,&dx)/NMEA_Pow(10,dx);                 //得到UTC時間,去掉ms
  198.                 gpsx->utc.hour=temp/10000;
  199.                 gpsx->utc.min=(temp/100)%100;
  200.                 gpsx->utc.sec=temp%100;                  
  201.         }        
  202.         posx=NMEA_Comma_Pos(p1,3);                                                                //得到緯度
  203.         if(posx!=0XFF)
  204.         {
  205.                 temp=NMEA_Str2num(p1+posx,&dx);                          
  206.                 gpsx->latitude=temp/NMEA_Pow(10,dx+2);        //得到°
  207.                 rs=temp%NMEA_Pow(10,dx+2);                                //得到'                 
  208.                 gpsx->latitude=gpsx->latitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//轉換為°
  209.         }
  210.         posx=NMEA_Comma_Pos(p1,4);                                                                //南緯還是北緯
  211.         if(posx!=0XFF)gpsx->nshemi=*(p1+posx);                                         
  212.          posx=NMEA_Comma_Pos(p1,5);                                                                //得到經度
  213.         if(posx!=0XFF)
  214.         {                                                                                                  
  215.                 temp=NMEA_Str2num(p1+posx,&dx);                          
  216.                 gpsx->longitude=temp/NMEA_Pow(10,dx+2);        //得到°
  217.                 rs=temp%NMEA_Pow(10,dx+2);                                //得到'                 
  218.                 gpsx->longitude=gpsx->longitude*NMEA_Pow(10,5)+(rs*NMEA_Pow(10,5-dx))/60;//轉換為°
  219.         }
  220.         posx=NMEA_Comma_Pos(p1,6);                                                                //東經還是西經
  221.         if(posx!=0XFF)gpsx->ewhemi=*(p1+posx);        
  222.    posx=NMEA_Comma_Pos(p1,7);              //獲取地面速度
  223.         if(posx!=0XFF)gpsx->lspeed=*(p1+posx);        
  224.         
  225.         posx=NMEA_Comma_Pos(p1,9);                                                                //得到UTC日期
  226.         if(posx!=0XFF)
  227.         {
  228.                 temp=NMEA_Str2num(p1+posx,&dx);                                                 //得到UTC日期
  229.                 gpsx->utc.date=temp/10000;
  230.                 gpsx->utc.month=(temp/100)%100;
  231.                 gpsx->utc.year=2000+temp%100;                  
  232.         }
  233. }
  234. //分析GNVTG信息
  235. //gpsx:nmea信息結構體
  236. //buf:接收到的GPS數據緩沖區首地址
  237. void NMEA_GNVTG_Analysis(nmea_msg *gpsx,u8 *buf)
  238. {
  239.         u8 *p1,dx;                        
  240.         u8 posx;   
  241.         p1=(u8*)strstr((const char *)buf,"$GNVTG");                                                         
  242.         posx=NMEA_Comma_Pos(p1,7);                                                                //得到地面速率
  243.         if(posx!=0XFF)
  244.         {
  245.                 gpsx->speed=NMEA_Str2num(p1+posx,&dx);
  246.                 if(dx<3)gpsx->speed*=NMEA_Pow(10,3-dx);                                  //確保擴大1000倍
  247.         }
  248. }  
  249. //提取NMEA-0183信息
  250. //gpsx:nmea信息結構體
  251. //buf:接收到的GPS數據緩沖區首地址
  252. void GPS_Analysis(nmea_msg *gpsx,u8 *buf)
  253. {
  254.         NMEA_GPGSV_Analysis(gpsx,buf);        //GPGSV解析
  255.         NMEA_BDGSV_Analysis(gpsx,buf);        //BDGSV解析
  256.         NMEA_GNGGA_Analysis(gpsx,buf);        //GNGGA解析         
  257.         NMEA_GNGSA_Analysis(gpsx,buf);        //GPNSA解析
  258.         NMEA_GNRMC_Analysis(gpsx,buf);        //GPNMC解析
  259.         NMEA_GNVTG_Analysis(gpsx,buf);        //GPNTG解析
  260. }

  261. /**********************************
  262. 功能:發送數據到GPS模塊
  263. 日期:2022.12.14
  264. 參數:cmd AT命令
  265. 返回值: 無
  266. *****************************/
  267. void SendAtToGps(u8 *cmd)
  268. {
  269.   while (*cmd !='\0')
  270.         {
  271.          USART_SendData(USART3,*cmd++);
  272.                 while(USART_GetFlagStatus(USART3,USART_FLAG_TXE)==Bit_RESET);
  273.         }
  274. }


  275. /****************************
  276. 功能:檢查GPS模塊應答是否符合預期
  277. 日期:2022.12.14
  278. 參數:str 正確應答
  279. 返回值:無
  280. ***************************/
  281. u8 GpsAckChack(u8 *str)
  282. {
  283. //u8 str[225];
  284.         delay_ms(500);
  285. if(USART3_RX_STA !=0)
  286. {
  287.    USART3_RX_STA=0;
  288.          if(strstr ((const char*)USART3_RX_BUF,(const char*)str))
  289.          {
  290.            memset(USART3_RX_BUF,0, sizeof USART3_RX_BUF);  //符合預期
  291.                  return 0;
  292.          }
  293.          else
  294.          {
  295.          memset(USART3_RX_BUF,0, sizeof USART3_RX_BUF);  //不符合預期
  296.                  return 1;
  297.                  //清空數組
  298.          }
  299. }
  300. else
  301. {
  302. memset(USART3_RX_BUF,0, sizeof USART3_RX_BUF);  
  303.          return  1;
  304. }  
  305. }

  306. /*********************************************
  307. 功能:GPS模塊初始化
  308. 日期:2022.12.14
  309. 參數: 無
  310. 返回值:無
  311. *********************************************/

  312. void Gps_Init()
  313. {
  314.         cmd1:SendAtToGps (ColdStart); //發送冷啟動指令
  315.         delay_ms(50);
  316.         if(!GpsAckChack ("$GNTXT,GK9701*7E..$GNTXT,HW:V190"));
  317.                 else goto cmd1;
  318.         cmd2:SendAtToGps (GPSL1L5); //全系統模式
  319.         delay_ms(50);
  320.         if (!GpsAckChack("$GNTXT,GK9701*7E..$GNTXT,HW:V190"))  ;
  321.           else goto  cmd2;
  322.         cmd3:SendAtToGps(OpenSBAS);    //開啟SBAS 功能
  323.              delay_ms(50);        
  324.                          if (!GpsAckChack("$GNTXT,GK9701*7E..$GNTXT,HW:V190"))  ;
  325.              else goto  cmd3;
  326.         cmd4:SendAtToGps(delay1sNMEA); //配置輸出 NMEA 消息的間隔 1s
  327.        delay_ms(50);        
  328.              if (!GpsAckChack("$GNTXT,GK9701*7E..$GNTXT,HW:V190"))  ;
  329.              else goto  cmd4;
  330.         cmd5:SendAtToGps(EnableRMC);   //設置 NMEA 語句輸出使能  使能RMC
  331.        delay_ms(50);        
  332.              if (!GpsAckChack("$GNTXT,GK9701*7E..$GNTXT,HW:V190"))  ;
  333.              else goto  cmd5;

  334.                          SendAtToGps(MoreFast);//加速定位信息

  335. }
復制代碼


Keil代碼下載:
AIR551G.7z (6.28 MB, 下載次數: 18)

評分

參與人數 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎勵!

查看全部評分

分享到:  QQ好友和群QQ好友和群 QQ空間QQ空間 騰訊微博騰訊微博 騰訊朋友騰訊朋友
收藏收藏 分享淘帖 頂 踩
回復

使用道具 舉報

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規則

手機版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術交流QQ群281945664

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 美日韩中文字幕 | 天堂精品视频 | 爱综合| 亚洲一区二区中文字幕 | 欧美一区二区免费视频 | 国产精品久久久久久238 | 夜夜夜夜夜夜曰天天天 | 精品国产伦一区二区三区观看方式 | 久久成人国产精品 | 一区二区激情 | 天天看天天操 | 亚洲视频自拍 | 国产精品久久久一区二区三区 | 国产午夜久久久 | 欧美日韩亚洲国产综合 | 日韩看片| 国产乱码精品1区2区3区 | 精品视频成人 | 欧美午夜激情在线 | 精品亚洲一区二区三区 | а_天堂中文最新版地址 | 国产97在线视频 | 国产精品一区二区电影 | 在线三级网址 | 亚洲最大的黄色网址 | 99精品视频免费观看 | 精品国产乱码久久久久久老虎 | 久久久男人的天堂 | 免费一二区| 成人免费网站视频 | 日韩视频一区 | 中文字幕在线不卡 | 精品一区二区久久久久久久网站 | 日本久久久久久 | 怡红院成人在线视频 | 你懂的av | 欧美日韩精品久久久免费观看 | 在线第一页 | 亚洲色图图片 | 国产99久久久国产精品 | 一区二区三区精品在线视频 |