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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

最簡GPS數據接收程序

  [復制鏈接]
跳轉到指定樓層
樓主
ID:73833 發表于 2015-6-2 16:33 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
本帖最后由 dingmingzhou 于 2015-7-14 14:20 編輯

寫在前面的話:一段時間以來,以8051為對象學單片機。有寫感受,寫出來和大家共商酌。一開始我也是從流水燈、數碼管、1602、12864一路趕來,感覺單片機這玩意,就是“SWRD”這幾下子:S(Set):設置--設置寄存器、變量……;W(Wrte):就是寫數據寫命令;R(Read):就是讀數據;D(display):就是顯示.也沒神魔大意思,但是,遵從規則--器件和C語言規則是必須的,頭疼人的時候,都是這“規則”鬧得,把他拿下,多半就艷陽天了。
最近俺看上TFT彩屏了,還沒研究出個啥來,不多啰嗦,估計也離不開 SWRD這幾下子。
      GPS,沒接觸前,感覺這東西可是一個“高、大、上”的東西。神妙莫測,沒出下手----衛星在天上呢!其實有了GPS模塊,研究了一下材料(2天呀),沒想到,這東西比DS18B20\DS1302都好搞---就是串口以4800(或9600)比特率輸出一串串格式化的ASCII串,且每秒鐘更新一次。呵呵。處理這個字符串基本有兩種法子:一是:”下載“整串,在進行復制、截取、轉換;二是”單摳“有用的、想要的東西。鑒于51單片機片內RAM的拮據、處理浮點數的囧態,下面貼上來的程序是按第二種法子做的。說明如下:
1、只”摳“經緯度及方向、海拔、速度、時間、日期、方位角這幾項
2、定義單項的字符數組,分別賦值,并規整成 通常的格式,以便顯示時,順序顯示字符數組元素。
3、本程序僅是數據包解析部分,顯示函數沒寫,想著把TFT搞懂了,顯在那上邊,過一把癮。
4、程序是按照我自己的理解去寫的、也去參考別人的;蛴蠦UG多多,不反對拍磚。
程序清單

評分

參與人數 1黑幣 +4 收起 理由
qjzyx + 4 贊一個!

查看全部評分

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

使用道具 舉報

沙發
ID:73833 發表于 2015-6-2 17:27 | 只看該作者
本帖最后由 dingmingzhou 于 2015-7-14 14:23 編輯
  1. #include<reg52.h>
  2. #define  uchar unsigned char
  3. #define  uint unsigned int
  4. /***********GPS數據存儲數組***********/
  5. uchar JD[10]; //經度準備存為***.**.**. 形式,
  6. uchar JD_a; //經度方向
  7. uchar WD[9];  //緯度準備存為**.**.**.形式,
  8. uchar WD_a; //緯度方向
  9. uchar date[9];//日期準備存為**-**-** 形式
  10. uchar time[9];//時間準備存為**:**:** 形式。
  11. uchar speed[6];//速度準備存為        ***.*形式
  12. uchar high[8];//高度準備存為        ****.* 形式
  13. uchar angle[6]; //方位角準備存為  ***.* 形式
  14. bit lock; //定位狀態  0 ,1
  15. /*********串口中斷及數據處理需要的變量***********/
  16. uchar tmp;                //串口數據緩沖
  17. uchar seg_count; //逗號計數器
  18. uchar byte_count; //位數計數器
  19. uchar cmd_number; //命令類型 0:無效;1:GGA;2:RMC
  20. uchar mode;       //0:結束模式,1:命令模式,2:數據模式
  21. uchar buf_full=0; //設定語句接收完成,相應數據有效。0:無效。
  22. uchar cmd[5];      //命令內容存儲數組
  23. /******************        系統初始化*************/
  24. void sys_init()        
  25. {
  26.         SCON = 0x50;  /*  定時器1 M0=0,M1=1,REN=1 */
  27.         TMOD = 0x20;  /* TMOD: 定時器1模式2自動重裝*/  
  28.         TH1 = 0xfa;  /* 11.0592MHZ 波特率4800*/               
  29.         TL1 = 0xfa;
  30.         ES=1;
  31.         TR1=1;   
  32.         EA=1;                                         
  33.   }
  34. /******************        顯示函數*************/
  35. void display()
  36. {
  37. ;
  38. }
  39. /******************        主函數********************/
  40. main()
  41. {
  42.      uchar Bhh,Bdd,Bmm,Byy;         //格倫威治時間轉換為北京時間變量
  43.      unsigned long mn;         //定義經度緯度局部變量   
  44.           uint mnn;            
  45.      sys_init();         //系統初始化        
  46.          while(1)
  47.          {                     
  48.           switch(tmp)         //傳來的數據(即ASCII碼,一個ASCII碼是8位,一個字節)進行對號入座
  49.             {
  50.              case ':        //起始符
  51.                                cmd_number=0; //命令類型清空        
  52.                                mode=1;       //接收命令模式  0:結束模式,1:命令模式,2:數據模式
  53.                                byte_count=0; //接收位數清空,位數計數器=0;標記一種(如高度、速度等)數據多少位
  54.                        break;            
  55.                                 
  56.                  case ',':                   //分隔符,它分隔各種數據
  57.                                    seg_count++; //逗號計數加1        ,一個”,”號前是一個有效數據
  58.                                    byte_count=0; //接收位數清空
  59.                        break;
  60.              case '*':                   //一旦遇到*, 如下處理:
  61.                                switch(cmd_number)         //命令類型共2種???
  62.                                    {
  63.                                     case 1: {buf_full|=0x01; break;}//或上的0x01標志第1種命令                                                                                                                                                                                                                    
  64.                                                 case 2: {buf_full|=0x04; break;}//或上的0x04標志第2種命令                                                                 
  65.                                    }
  66.                                    mode=0;  //結束模式
  67.                                         while(buf_full==0x05)  //如果GGA和RMC語句都解析完成。
  68.                                           {
  69.                                                   EA=0; REN=0;        //        顯示時關中斷和串口接收,                                 
  70.                                                   buf_full=0;                 //為下一個循環做準備
  71.                                                   display();         //顯示函數。
  72.                                                     EA=1; REN=1;        // 顯示完成再打開中斷和串口。
  73.                                            }
  74.                             break; //跳出 switch(tmp)去重新尋找“$”符號。
  75.              default:          //到這里是tmp不等于“*”和“,”及“$”的情況下。                                       
  76.                         if(mode==1)           //判斷命令種類
  77.                         {               
  78.                            cmd[byte_count]=tmp; //接收字符放入類型緩存
  79.                            if(byte_count>=4)         //如果類型數據接收完畢,只判斷語句名
  80.                            {                                 
  81.                                  if((cmd[2]=='G')&&(cmd[3]=='G')&&(cmd[4]=='A'))
  82.                                    {
  83.                                     cmd_number=1;           //GGA
  84.                                         mode=2;
  85.                                         seg_count=0;
  86.                                         byte_count=0;         
  87.                                    }
  88.                                  if((cmd[2]=='R')&&(cmd[3]=='M')&&(cmd[4]=='C'))
  89.                                     {
  90.                                       cmd_number=2;         //RMC
  91.                                           mode=2;
  92.                                           seg_count=0;
  93.                                           byte_count=0;
  94.                                     }
  95.                            }                                                
  96.                         }else if(mode==2)
  97.                                    {        
  98.                             switch (cmd_number)         
  99.                               {
  100.                                   case 1: //接收GPGGA                                                                           
  101.                                                  if((seg_count==9)&&(byte_count<7))high[byte_count]=tmp;//高度是7位                                                
  102.                                                                    high[byte_count+1] ='\0';   //高度輸出的位數不固定,但byte_count+1個元素一定應該加'\0'.
  103.                                                                  break;         //跳出        switch (cmd_number)        
  104.                                   case 2: //接收GPRMC
  105.                                                 switch(seg_count)
  106.                                                                         {
  107.                                                    case 1: //UTC時間暫存
  108.                                                           if(byte_count<6)time[byte_count]=tmp;
  109.                                                                                           break;                 
  110.                                                    case 2: //定位判斷
  111.                                                           if(byte_count<1)          //狀態
  112.                                                             { if (tmp=='A') lock=1;        else  lock=0; }                                             
  113.                                                                                            break;
  114.                                                    case 3: //緯度處理小數點后的數據
  115.                                                            if(byte_count<9)WD[byte_count]=tmp;
  116.                                                                                               if(byte_count==8)
  117.                                                                                                    {
  118.                                                                                                    mn=((WD[5]-'0')*1000+(WD[6]-'0')*100+(WD[7]-'0')*10+(WD[8]-'0'))*60;        //僅處理4位小數位
  119.                                                                                                    mnn=mn/10000;
  120.                                                                                                    WD[3]=WD[2];
  121.                                                                                                    WD[4]=WD[3];
  122.                                                                                                    WD[2]='.';
  123.                                                                                                    WD[5]='.';
  124.                                                                                                    WD[6]= mnn/10+'0';
  125.                                                                                                    WD[7]= mnn%10+'0';
  126.                                                                                                    WD[8]= '\0';
  127.                                                                                                   }
  128.                                                                                            break;
  129.                                                    case 4: //緯度方向處理
  130.                                                            if(byte_count<1)WD_a=tmp;
  131.                                                                                     
  132.                                                                                            break;
  133.                                                    case 5: //經度處理小數點后的數據
  134.                                                            if(byte_count<10) JD[byte_count]=tmp;
  135.                                                                                        if(byte_count==9)
  136.                                                                                                    {
  137.                                                                                                    mn=((JD[6]-'0')*1000+(JD[7]-'0')*100+(JD[8]-'0')*10+(JD[9]-'0'))*60;        //僅處理4位小數位        
  138.                                                                                                    mnn=mn/10000;                                                                                                                                                                                                      
  139.                                                                                                    JD[4]=JD[3];
  140.                                                                                                    JD[5]=JD[4];
  141.                                                                                                    JD[3]='.';
  142.                                                                                                    JD[6]='.';
  143.                                                                                                    JD[7]=mnn/10+'0';
  144.                                                                                                    JD[8]=mnn%10+'0';
  145.                                                                                                    JD[9]='\0';
  146.                                                                                                   }
  147.                                                                                            break;
  148.                                                    case 6: //經度方向處理
  149.                                                            if(byte_count<1)JD_a=tmp;         
  150.                                                                                        
  151.                                                                                            break;
  152.                                                    case 7: //速度是格式輸出 //本量程處理于540節以下即1000公里/小時以內,一位小數點。
  153.                                                            if(byte_count<5)speed[byte_count]=tmp;
  154.                                                                                        if(byte_count==4)
  155.                                                                                             {
  156.                                                                                                     mn=((speed[0]-'0')*1000+(speed[1]-'0')*100+(speed[2]-'0')*10+(speed[4]-'0'))*185;
  157.                                                                                                     mnn=mn/100;                // 此時速度仍然被擴大了10倍。
  158.                                                                                                         if(mnn/1000==0)speed[0]=0x20;                           //高位消隱
  159.                                                                                                                             else  speed[0]=mnn/1000+'0';
  160.                                                                                                         if((mnn/1000==0)&&((mnn%1000 )/100)==0)speed[1]=0x20;//高位消隱
  161.                                                                                                                             else  speed[1]=(mnn%1000 )/100+'0';
  162.                                                                                                         if(((mnn/1000==0)&&((mnn%1000 )/100)==0)&&((mnn%100)/10==0))speed[2]=0x20; //高位消隱
  163.                                                                                                                            else  speed[2]=(mnn%100)/10+'0';
  164.                                                                                                                                                 
  165.                                                                                                         speed[4]=mnn%10+'0';        //  小數位         
  166.                                                                                                                      speed[5]='\0';
  167.                                                                                             }
  168.                                                                                            break;                 
  169.                                                    case 8: //方位角處理
  170.                                                            if(byte_count<5) angle[byte_count]=tmp;
  171.                                                                                                angle[5]='\0';
  172.                                                                                            break;
  173.                                                    case 9: //日期處理
  174.                                                            if(byte_count<6)date[byte_count]=tmp;         
  175.                                                                                            if( byte_count==5)
  176.                                                                                                     {
  177.                                                                                                     Bhh=((time[0]-'0')*10+time[1]-'0')+8;//加8小時轉換北京時間 加8小時會影響日期,故需調整
  178.                                                                                                     Bdd=(date[0]-'0')*10+(date[1]-'0');                                    
  179.                                                                                                     Bmm=(date[2]-'0')*10+(date[3]-'0');         
  180.                                                                                                     Byy=(date[4]-'0')*10+(date[5]-'0');
  181.                                                                                                    if(Bhh>23)
  182.                                                                                                      {
  183.                                                                                                            Bhh-=24;
  184.                                                                                                    Bdd+=1;
  185.                                                                                                                   if(Bmm==2&&Bmm==4&&Bmm==6&&Bmm==9&&Bmm==11)
  186.                                                                                                                         {
  187.                                                                                                                           if(Bdd>30){Bdd=1; Bmm++;}

  188.                                                                                                                          } else        if(Bdd>31){ Bdd=1; Bmm++;}               
  189.                
  190.                                                                                                               if(Byy % 4 == 0 )
  191.                                                                             {
  192.                                                                  if(Bdd > 29 && Bmm ==2){ Bdd=1;Bmm++; } //閏年的二月是29天
  193.         
  194.                                                                  } else if(Bdd>28 &&Bmm ==2){Bdd=1;Bmm++;}
  195.         
  196.                                                                                                           if(Bmm>12){Bmm-=12;Byy++;}
  197.                                                                                                   }  
  198.                                                                                                /*以下重新整理time[]和date[]數組*/
  199.                                                                                                          time[0]=Bhh/10+'0';        //把日期數組整理成 hh:mm:ss
  200.                                                                                                         time[1]=Bhh%10+'0';         
  201.                                                                                                         time[3]=time[2];        
  202.                                                                                                         time[4]=time[3];
  203.                                                                                                         time[2]=':';        
  204.                                                                                                         time[6]=time[4];        
  205.                                                                                                         time[7]=time[5];                 
  206.                                                                                                         time[5]=':';        
  207.                                                                                                         time[8]='\0';

  208.                                                                                                         date[0]=Byy/10+'0';//把日期數組整理成 yy-mo-dd
  209.                                                                                                         date[1]=Byy%10+'0';
  210.                                                                                                         date[2]='-';
  211.                                                                                                         date[3]=Bmm/10+'0';
  212.                                                                                                         date[4]=Bmm%10+'0';
  213.                                                                                                         date[5]='-';        
  214.                                                                                                         date[6]=Bdd/10+'0';
  215.                                                                                                         date[7]=Bdd%10+'0';
  216.                                                                                                         date[8]='\0';
  217.                                                                                                   }
  218.                                                                                     break;
  219.                                                           default:        break;
  220.                                                                     }
  221.                                        break;        //跳出        switch (cmd_number)        
  222.                                     }
  223.                                  }
  224.                         byte_count++; //接收數位加1
  225.                         break; //跳出 switch(tmp)                              
  226.                 }
  227.            
  228.     }
  229. }           
  230. /******************        中斷服務函數*************/
  231. void uart(void) interrupt 4          //串口接收中斷
  232.   {        
  233.          tmp=SBUF;                           
  234.          RI=0;  
  235.   }        
  236. /********************************************/
復制代碼

評分

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

查看全部評分

回復

使用道具 舉報

板凳
ID:264279 發表于 2017-12-20 15:25 | 只看該作者
這個就是拿液晶屏能顯示的程序嗎
回復

使用道具 舉報

地板
ID:253767 發表于 2017-12-22 15:20 | 只看該作者
學習了
回復

使用道具 舉報

5#
ID:265683 發表于 2017-12-23 15:13 | 只看該作者
可不可以把原工程發上來呀
回復

使用道具 舉報

6#
ID:88269 發表于 2018-1-27 16:31 | 只看該作者
正要學習這方面的東西
回復

使用道具 舉報

7#
ID:266116 發表于 2018-1-28 11:48 | 只看該作者
謝謝分享
回復

使用道具 舉報

8#
ID:88269 發表于 2018-1-30 09:22 | 只看該作者
好資料,學習一下,謝謝分享
回復

使用道具 舉報

9#
ID:162136 發表于 2018-2-5 23:52 | 只看該作者
學習了,總結的在理。
回復

使用道具 舉報

10#
ID:43383 發表于 2019-1-5 14:35 | 只看該作者
只有GPS天線搞出來才高大上,有模塊不是什么問題
回復

使用道具 舉報

11#
ID:239793 發表于 2019-1-14 19:33 | 只看該作者
第一個CASE 為什么會報錯
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 欧美特级黄色 | 日韩成人免费av | av资源中文在线 | 国产精品久久久久久久久久三级 | 精品久| 成人激情视频免费观看 | 天天干天天爽 | 日本综合在线观看 | 91久久看片| caoporn视频| 一区二区三区欧美在线 | 一区二区视屏 | 狠狠的干| 亚洲视频在线观看免费 | 激情av在线| 欧美精品在线播放 | 久久精品亚洲一区二区三区浴池 | 久久无毛| 亚洲一区二区三区桃乃木香奈 | 在线观看亚 | 欧美大片一区 | 中文字幕在线一区 | 久久久久av| 精品视频一区二区三区在线观看 | 久久精品中文字幕 | 久久精品久久久 | 成人在线观看中文字幕 | julia中文字幕久久一区二区 | 97人人澡人人爽91综合色 | 99成人精品| 国产特级毛片aaaaaa喷潮 | 午夜一区二区三区在线观看 | 91久久精品一区二区二区 | 亚洲一一在线 | 国产成人久久av免费高清密臂 | 久久久久9999亚洲精品 | 国产精品一区二区久久 | 一区二区国产精品 | 成人1区 | 久久久久久亚洲欧洲 | 中文字幕精品视频在线观看 |