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

 找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

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

如何使GPS的經緯度實時刷新(1秒刷新1次)附單片機程序

[復制鏈接]
跳轉到指定樓層
樓主
ID:284050 發表于 2021-9-1 23:28 | 只看該作者 回帖獎勵 |倒序瀏覽 |閱讀模式
我在網上找了一些解析GPS的程序,并用OLED顯示出來。目前可以做到解析和顯示,但做不到實時刷新。請高手指點一下。謝謝
IIC的程序就不貼出來了。
單片機源程序如下:
  1. #include <reg51.h>
  2. #include "iic_oled.h"


  3. #define u8 unsigned char
  4. #define u16 unsigned int
  5. #define u32 unsigned long

  6. u8 RX_Buffer[68];                //此數組用于直接儲存來自GPS的原始數據
  7. u8 RX_Count = 0;
  8. //u8 Hour = 0,Min_High = 0,Min_Low = 0,Sec_High = 0,Sec_Low = 0;
  9. u8 Month = 0,Day = 0,Month_High = 0, Month_Low = 0,Day_Low = 0 ,Day_High = 0, Year_High = 0,Year_Low = 0;
  10. u16 Year = 0;
  11. bit Flag_GPS_OK = 0;
  12. u8 MaxDay = 0;


  13. u8 xdata Display_GPGGA_Buffer[68]={0};                //用于儲存GPGGA的數據




  14. bit Flag_Calc_GPGGA_OK = 0;           //GPGGA完整有效的數據已收到的標志變量


  15. void Uart_Init();
  16. u8 GetMaxDay(u8 Month_Value,u16 Year_Value);
  17. bit IsLeapYear(u16 uiYear);
  18. void Delay500ms()        ;



  19. //****************************************************
  20. //主函數
  21. //****************************************************
  22. void main()
  23. {
  24.         u16 i = 0;

  25.         Uart_Init();                                                                        //串口初始化
  26.         OLED_Init();//初始化OLED
  27.   OLED_Clear();//清屏

  28.         while(1)
  29.         {



  30.                 if (   Flag_GPS_OK  == 1         && RX_Buffer[4] == 'G'
  31.                         && RX_Buffer[6] == ','   && RX_Buffer[13] == '.'
  32.                     )                //確認是否收到"GPGGA"這一幀完整有效的數據
  33.                 {
  34.                         for( i = 0; i < 67 ; i++)                                                  //必須為i<67,因為要確保Display_GPGGA_Buffer[67]為'\0',便于串口發送
  35.                         {
  36.                                 Display_GPGGA_Buffer[i] = RX_Buffer[i];                  //儲存到數組中
  37.                         }
  38.                         Flag_Calc_GPGGA_OK = 1;                                                          //收到完整有效數據后,置為1
  39.                         
  40.                 }
  41.                 if(Display_GPGGA_Buffer[28] == 'N')
  42.                 {
  43.                 OLED_ShowChar(0, 0, 'G');
  44.                 OLED_ShowChar(8, 0, 'P');
  45.                 OLED_ShowChar(16, 0, 'S');
  46.                 OLED_ShowChar(24, 0, ':');
  47.                         
  48.                 OLED_ShowChar(0, 2, Display_GPGGA_Buffer[28]);//N
  49.                 OLED_ShowChar(8, 2, ':'); //:
  50.                 OLED_ShowChar(16, 2, Display_GPGGA_Buffer[17]);               
  51.                 OLED_ShowChar(24, 2, Display_GPGGA_Buffer[18]);
  52.                 OLED_ShowChar(32, 2, 127);               
  53.                 OLED_ShowChar(40, 2, Display_GPGGA_Buffer[19]);
  54.                 OLED_ShowChar(48, 2, Display_GPGGA_Buffer[20]);        
  55.                 OLED_ShowChar(56, 2, '.');        
  56.                 OLED_ShowChar(64, 2, Display_GPGGA_Buffer[22]);        
  57.                 OLED_ShowChar(72, 2, Display_GPGGA_Buffer[23]);                        
  58.                 OLED_ShowChar(80, 2, Display_GPGGA_Buffer[24]);                        
  59.                 OLED_ShowChar(88, 2, Display_GPGGA_Buffer[25]);                        
  60.                 OLED_ShowChar(96, 2, Display_GPGGA_Buffer[26]);                                
  61.                 OLED_ShowChar(104, 2, 39);               
  62.                
  63.                 OLED_ShowChar(0, 4, Display_GPGGA_Buffer[42]);//E
  64.                 OLED_ShowChar(8, 4, ':'); //:
  65.                 OLED_ShowChar(16, 4, Display_GPGGA_Buffer[30]);               
  66.                 OLED_ShowChar(24, 4, Display_GPGGA_Buffer[31]);
  67.           OLED_ShowChar(32, 4, Display_GPGGA_Buffer[32]);
  68.                 OLED_ShowChar(40, 4, 127);               
  69.                 OLED_ShowChar(48, 4, Display_GPGGA_Buffer[33]);
  70.                 OLED_ShowChar(56, 4, Display_GPGGA_Buffer[34]);        
  71.                 OLED_ShowChar(64, 4, '.');        
  72.                 OLED_ShowChar(72, 4, Display_GPGGA_Buffer[36]);        
  73.                 OLED_ShowChar(80, 4, Display_GPGGA_Buffer[37]);                        
  74.                 OLED_ShowChar(88, 4, Display_GPGGA_Buffer[38]);                        
  75.                 OLED_ShowChar(96, 4, Display_GPGGA_Buffer[39]);                        
  76.                 OLED_ShowChar(104, 4, Display_GPGGA_Buffer[40]);                                
  77.                 OLED_ShowChar(112, 4, 39);        
  78.         }
  79.                 else
  80.                 {
  81.                 OLED_ShowChar(0, 0, 'G');
  82.                 OLED_ShowChar(8, 0, 'P');
  83.                 OLED_ShowChar(16, 0, 'S');
  84.                 OLED_ShowChar(24, 0, ':');

  85.                 OLED_ShowChar(0, 2, 'n');//N
  86.                 OLED_ShowChar(8, 2, 'o'); //:
  87.                 OLED_ShowChar(16, 2, 't');               
  88.                 OLED_ShowChar(24, 2, 32);
  89.                 OLED_ShowChar(32, 2, 'c');               
  90.                 OLED_ShowChar(40, 2, 'o');
  91.                 OLED_ShowChar(48, 2, 'n');        
  92.                 OLED_ShowChar(56, 2, 'n');        
  93.                 OLED_ShowChar(64, 2, 'e');        
  94.                 OLED_ShowChar(72, 2, 'c');                        
  95.                 OLED_ShowChar(80, 2, 't');                        
  96.                 OLED_ShowChar(88, 2, 32);                        
  97.                 OLED_ShowChar(96, 2, 32);                                
  98.                 OLED_ShowChar(104, 2, 32);               
  99.                
  100.                 OLED_ShowChar(0,4, 32);//E
  101.                 OLED_ShowChar(8,4, 32); //:
  102.                 OLED_ShowChar(16,4, 32);               
  103.                 OLED_ShowChar(24,4, 32);
  104.           OLED_ShowChar(32,4, 32);
  105.                 OLED_ShowChar(40,4, 32);               
  106.                 OLED_ShowChar(48,4, 32);
  107.                 OLED_ShowChar(56,4, 32);        
  108.                 OLED_ShowChar(64,4, 32);        
  109.                 OLED_ShowChar(72,4, 32);        
  110.                 OLED_ShowChar(80,4, 32);                        
  111.                 OLED_ShowChar(88,4, 32);                        
  112.                 OLED_ShowChar(96,4, 32);                        
  113.                 OLED_ShowChar(104,4, 32);                                
  114.                 OLED_ShowChar(112,4, 32);
  115.                
  116.                 }
  117.                
  118.         }
  119. }



  120. void Uart_Init()                                                                     
  121. {
  122.         SCON = 0X50;  //UART方式1;8位UART
  123.         REN  = 1;     //允許串行口接收數據
  124.         PCON = 0x00;  //SMOD=0;波特率不加倍
  125.         TMOD = 0x20;  //T1方式2,用于產生波特率
  126.         TH1  = 0xFD;  //裝初值
  127.         TL1  = 0xFD;
  128.         TR1  = 1;     //啟動定時器1
  129.         EA   = 1;     //打開全局中斷控制
  130.         ES   = 1;     //打開串行口中斷        
  131. }


  132. void RECEIVE_DATA(void) interrupt 4 using 3                  //串口中斷函數,收到GPS的數據時進入此中斷        
  133. {
  134.         u8 temp = 0;
  135.         ES=0;                //先關閉串行口中斷
  136. if(RI)
  137. {        
  138.         temp = SBUF;                                                                //接收SBUF中的數據
  139.         if(temp == '

  140. )                                                                //若是統一的數據頭,則作為數組第一個元素
  141.         {
  142.                 RX_Count = 0;
  143.                 Flag_GPS_OK = 0;               
  144.         }

  145.         RX_Buffer[RX_Count++] = temp;                                //收到的數據放到數組中

  146.         if(RX_Count >= 66)                                                        //序號大于66的數據無用,統一放到第66位覆蓋掉
  147.         {
  148.                 RX_Count = 66;
  149.         }

  150.         if(temp == '*')                                                                //收到*,則完成一幀數據的接收,不管是否完整有效
  151.         {
  152.                 Flag_GPS_OK = 1;                                                //標志變量置為1
  153.         }
  154. }
  155.         RI = 0;                                                                                //接收完成的標志位清零
  156.         ES=1;                                                                                 //重新打開串行口中斷

  157. }

復制代碼

全部資料51hei下載地址:
改版.rar (57.14 KB, 下載次數: 16)

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

使用道具 舉報

沙發
ID:702863 發表于 2021-9-2 09:43 | 只看該作者
將接收緩存RX_Buffer改成環形緩存LOOP_Buffer,即串口中斷每次按字節寫入環形緩存中。新增緩存數組GPS_Buffer,while(1)循環體遍歷按字節取出LOOP_Buffer的數據存儲到GPS_Buffer中,并判斷是否完幀,最后OLED顯示。
回復

使用道具 舉報

板凳
ID:702863 發表于 2021-9-2 10:04 | 只看該作者
a1093941419 發表于 2021-9-2 09:43
將接收緩存RX_Buffer改成環形緩存LOOP_Buffer,即串口中斷每次按字節寫入環形緩存中。新增緩存數組GPS_Buff ...

或者更簡單的說,程序應該設計成串口中斷一邊接收,主體部分一邊解析,而不是等到串口都接收完成再去解析。
回復

使用道具 舉報

地板
ID:401564 發表于 2021-9-2 10:36 | 只看該作者
我這兩天也是在搞這上GPS,數據有點多,不過也是慢慢的理清了
定義一個結構體
串口中斷一邊接收,主函數一邊處理數據
串口接收到一幀的完整數據之后,直接用結構體復制過來,感覺比數組好用
struct                                                           //GPS_Buffer結構
{
char GPS_Buffer[80];                                //留80個地址來存放GPS的數據
}xdata GPS_Buffer0,GPS_Buffer1;                 //兩個結構變量,讓串口接收和保存不相互影響

GPS_Buffer1=GPS_Buffer0; //這個是在串口中斷中完成的

在主函數中把GPS_Buffer1結構體中的數據提取出來處理就可以了,先處理好數據,時間一到就刷新
回復

使用道具 舉報

5#
ID:284050 發表于 2021-9-2 12:37 | 只看該作者
本帖最后由 川人在柳 于 2021-9-2 12:41 編輯
a1093941419 發表于 2021-9-2 10:04
或者更簡單的說,程序應該設計成串口中斷一邊接收,主體部分一邊解析,而不是等到串口都接收完成再去解析 ...

你這樣說,感覺有點明白了。晚上回去試試。我的理解是給中斷一個數組(目前程序中的RX_Buffer),讓他存串口接收到的數據;然后再while(1)里面再給一個數組LOOP_Buffer。當RX_Buffer接收完數據后,再把RX_Buffer數據給LOOP_Buffer。
回復

使用道具 舉報

6#
ID:284050 發表于 2021-9-2 12:40 | 只看該作者
Y_G_G 發表于 2021-9-2 10:36
我這兩天也是在搞這上GPS,數據有點多,不過也是慢慢的理清了
定義一個結構體
串口中斷一邊接收,主函數一邊 ...

謝謝回復。你這個說法似乎和你的樓上說的差不多。我的理解是給中斷一個數組(目前程序中的RX_Buffer),讓他存串口接收到的數據;然后再while(1)里面再給一個LOOP_Buffer,當RX_Buffer接收完數據后,再把RX_Buffer數據給LOOP_Buffer。
回復

使用道具 舉報

7#
ID:401564 發表于 2021-9-2 19:52 | 只看該作者
川人在柳 發表于 2021-9-2 12:40
謝謝回復。你這個說法似乎和你的樓上說的差不多。我的理解是給中斷一個數組(目前程序中的RX_Buffer), ...

我這個是懶人做法,GPS_Buffer1始終保存的是上一幀數據,不用檢測什么接收完成沒有
GPS_Buffer0在中斷中完成后自動把數據復制到GPS_Buffer1
用結構的好處就是可以直接GPS_Buffer1=GPS_Buffer0
回復

使用道具 舉報

8#
ID:284050 發表于 2021-9-3 11:29 | 只看該作者
a1093941419 發表于 2021-9-2 09:43
將接收緩存RX_Buffer改成環形緩存LOOP_Buffer,即串口中斷每次按字節寫入環形緩存中。新增緩存數組GPS_Buff ...

自己晚上試了一下,沒有搞定。感覺還是不能特別理解你講的內容。
回復

使用道具 舉報

9#
ID:284050 發表于 2021-9-3 11:30 | 只看該作者
Y_G_G 發表于 2021-9-2 19:52
我這個是懶人做法,GPS_Buffer1始終保存的是上一幀數據,不用檢測什么接收完成沒有
GPS_Buffer0在中斷中完 ...

能開源一下你的關于GPS數據解析的代碼么
回復

使用道具 舉報

10#
ID:401564 發表于 2021-9-3 22:51 | 只看該作者
川人在柳 發表于 2021-9-3 11:30
能開源一下你的關于GPS數據解析的代碼么

我在現在也是還在調試中
我接收的信息是最簡的GPS定位信息      $GNRMC

Uart_Isr() interrupt 4    串口中斷函數負責接收GPS數據和保存,接收到一個幀的數據就保存

GPS_Data_Disp()   這個函數是負責把GPS_Buffer1.GPS_Buffer[] 中的GPS相關信息提取出來的,因為室內沒有GPS信號,找了ATGM336H-5N數據手冊上數據進行調試,因為數據手冊上給我數據并不是完整的$GNRMC幀信息,考慮到會亂碼,所以,在讀取數組的時候是用++a這種形式去讀取的
調試好之后,有了完整的GPS信息,可以直接指定GPS_Buffer1.GPS_Buffer[] 數組位置進行讀取,代碼就沒有那么亂了

其實這個東西沒那么難的
1,先保證串口程序是一定正確的,這個好反復驗證,不能仿真,以實際開發板結果為準,有時候串口出問題,接收一兩字節就沒有問題,接收多了就有問題
2,串口接收到   $GNRMC  或者你自己想要的字符之后,就開始保存,不然就不用保存
3,GPS信息是以ASCII字符發送的,不是字符串,是字符,比如5,串口接收到的數據就是'5',也就是53
$GNRMC,084852.000,A,2236.9453,N,11408.4790,E,0.53,292.44,141216,,,A*7
5

以上的信息就是一幀的信息,逗號,小數點,*都是
調試的時候可以檢測','就是逗號,數據是以逗號分隔
你可以數相關信息在什么位置,也可以檢測逗號來提取
我這個代碼也可以用,可以接收和提取GPS信息,試了一下,GPS的經緯度定位基本就是我這樓位置,一般來說,GPS定位準確了,就可以認為其它的信息也是準確的了 uart.rar (1.81 KB, 下載次數: 18)


回復

使用道具 舉報

11#
ID:982011 發表于 2021-11-17 22:04 | 只看該作者
樓主:4g模塊用的是什么樣的?
回復

使用道具 舉報

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

本版積分規則

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

Powered by 單片機教程網

快速回復 返回頂部 返回列表
主站蜘蛛池模板: 亚洲欧美综合精品久久成人 | 午夜在线影院 | 成人在线免费观看视频 | 九九热免费视频在线观看 | 91麻豆精品国产91久久久更新资源速度超快 | 久久爆操 | 日韩欧美国产精品一区二区三区 | 视频在线观看一区二区 | 日韩欧美精品在线 | 羞羞视频在线观免费观看 | 国产欧美日韩一区二区三区在线观看 | 欧美一区二区三区国产精品 | 视频一区中文字幕 | 国产观看| 久久这里只有精品首页 | 欧美888| 亚洲男人天堂 | 亚洲精品在线免费 | 久久久久久久久国产精品 | 无人区国产成人久久三区 | 超碰最新在线 | 国产福利资源 | 日韩免费视频 | 激情网站在线观看 | 色播99| 蜜桃视频在线观看www社区 | 99re在线 | 在线免费国产 | 欧洲一区二区三区 | 亚洲最大av网站 | 国产精品日韩一区二区 | 黄视频网站免费观看 | 色橹橹欧美在线观看视频高清 | 91资源在线| 国产一区不卡在线观看 | 色www精品视频在线观看 | 亚洲第一视频网 | 国产九一精品 | 亚洲欧洲在线看 | 日韩精品一区二区三区久久 | 天天天操天天天干 |