找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 5165|回復(fù): 5
收起左側(cè)

基于51單片機(jī)做的GPS定位

  [復(fù)制鏈接]
ID:953261 發(fā)表于 2021-7-17 23:35 | 顯示全部樓層 |閱讀模式
這是我特想做的一個(gè)裝置,在學(xué)長的幫助下,我們完成了它,直接上圖。

這是板子出了點(diǎn)小故障,沒點(diǎn)著

帶燒錄,點(diǎn)火成功,哈哈

仿真,不太會(huì)用這個(gè)東西

GPS的代碼部分
20210717230726.png 20210717230749.png

單片機(jī)源程序如下:
  1. #include "main.h"
  2. #include "LCD1602.h"
  3. #include "GPS.h"

  4. //定義變量
  5. unsigned char KEY_NUM = 0;
  6. bit Page = 0;
  7. unsigned char xdata Display_GPGGA_Buffer[68];
  8. unsigned char xdata Display_GPRMC_Buffer[68];
  9. bit Flag_OV = 0;
  10. bit Flag_Calc_GPGGA_OK = 0;
  11. bit Flag_Calc_GPRMC_OK = 0;

  12. //****************************************************
  13. //主函數(shù)
  14. //****************************************************
  15. void main()
  16. {
  17.     unsigned char i = 0;
  18.     Init_LCD1602();
  19.     LCD1602_write_com(0x80);                        //指針設(shè)置
  20.     LCD1602_write_word("Welcome to use!");

  21.     Delay_ms(1000);


  22.     Uart_Init();

  23.     while(1)
  24.     {
  25.         Scan_Key();
  26.         if(Flag_GPS_OK == 1 && RX_Buffer[4] == 'G' && RX_Buffer[6] == ',' && RX_Buffer[13] == '.')            //確定是否收到"GPGGA"這一幀數(shù)據(jù)
  27.         {
  28.             for( i = 0; i < 68 ; i++)
  29.             {
  30.                 Display_GPGGA_Buffer[i] = RX_Buffer[i];   
  31.             }
  32.             Hour = (Display_GPGGA_Buffer[7]-0x30)*10+(Display_GPGGA_Buffer[8]-0x30)+8;            //UTC時(shí)間轉(zhuǎn)換到北京時(shí)間        UTC+8
  33.                                                                                                 //0x30為ASCII轉(zhuǎn)換為數(shù)字
  34.             if( Hour >= 24)                //溢出
  35.             {
  36.                 Hour %= 24;                //獲取當(dāng)前Hour
  37.                 Flag_OV = 1;            //日期進(jìn)位
  38.             }
  39.             else
  40.             {
  41.                 Flag_OV = 0;
  42.             }

  43.             Min_High = Display_GPGGA_Buffer[9];
  44.             Min_Low = Display_GPGGA_Buffer[10];
  45.    
  46.             Sec_High = Display_GPGGA_Buffer[11];
  47.             Sec_Low = Display_GPGGA_Buffer[12];

  48.             Flag_Calc_GPGGA_OK = 1;
  49.         }

  50.         if(Page == 0 && Flag_Calc_GPGGA_OK == 1)
  51.         {
  52.             LED1 = ~LED1;
  53.             Flag_Calc_GPGGA_OK = 0;
  54.             LCD1602_write_com(0x80);            //設(shè)置指針
  55.             LCD1602_write_data(Hour/10+0x30);
  56.             LCD1602_write_data(Hour%10+0x30);

  57.             LCD1602_write_data(':');

  58.             LCD1602_write_data(Min_High);
  59.             LCD1602_write_data(Min_Low);

  60.             LCD1602_write_data(':');
  61.    
  62.             LCD1602_write_data(Sec_High);
  63.             LCD1602_write_data(Sec_Low);

  64.             LCD1602_write_word("  ");
  65.             
  66.             LCD1602_write_data(Display_GPGGA_Buffer[54]);   
  67.             LCD1602_write_data(Display_GPGGA_Buffer[55]);   
  68.             LCD1602_write_data(Display_GPGGA_Buffer[56]);   
  69.             LCD1602_write_data(Display_GPGGA_Buffer[57]);
  70.             LCD1602_write_word("m");
  71.    
  72.             LCD1602_write_com(0x80+0x40);            //設(shè)置指針
  73.             
  74.             LCD1602_write_data(Display_GPGGA_Buffer[28]);            //N 或者 S

  75.             LCD1602_write_data(Display_GPGGA_Buffer[17]);            //緯度
  76.             LCD1602_write_data(Display_GPGGA_Buffer[18]);            //緯度
  77.             LCD1602_write_data(0xdf);                                //度
  78.             LCD1602_write_data(Display_GPGGA_Buffer[19]);            //緯度
  79.             LCD1602_write_data(Display_GPGGA_Buffer[20]);            //緯度
  80.             LCD1602_write_word("'");                                //秒
  81.             
  82.             LCD1602_write_data(Display_GPGGA_Buffer[42]);            //E 或者 W

  83.             LCD1602_write_data(Display_GPGGA_Buffer[30]);            //經(jīng)度
  84.             LCD1602_write_data(Display_GPGGA_Buffer[31]);   
  85.             LCD1602_write_data(Display_GPGGA_Buffer[32]);   
  86.             LCD1602_write_data(0xdf);                                
  87.             LCD1602_write_data(Display_GPGGA_Buffer[33]);            
  88.             LCD1602_write_data(Display_GPGGA_Buffer[34]);        
  89.             LCD1602_write_word("'");

  90.                         
  91.         }
  92.         
  93.         if(Flag_GPS_OK == 1 && RX_Buffer[4] == 'M' && RX_Buffer[52] == ',' && RX_Buffer[59] == ',')            //確定是否收到"GPRMC"這一幀數(shù)據(jù)
  94.         {
  95.             for( i = 0; i < 68 ; i++)
  96.             {
  97.                 Display_GPRMC_Buffer[i] = RX_Buffer[i];   
  98.             }

  99.             Year_High = Display_GPRMC_Buffer[57];
  100.             Year_Low = Display_GPRMC_Buffer[58];

  101.             Month_High = Display_GPRMC_Buffer[55];
  102.             Month_Low = Display_GPRMC_Buffer[56];

  103.             Day_High = Display_GPRMC_Buffer[53];
  104.             Day_Low = Display_GPRMC_Buffer[54];


  105.             if(Flag_OV == 1)            //有進(jìn)位
  106.             {
  107.                 UTCDate2LocalDate();            //UTC日期轉(zhuǎn)換為北京時(shí)間        
  108.             }

  109.             Flag_Calc_GPRMC_OK = 1;
  110.         }

  111.         if(Page == 1 && Flag_Calc_GPRMC_OK == 1)
  112.         {
  113.             LED1 = ~LED1;
  114.             Flag_Calc_GPRMC_OK = 0;
  115.             LCD1602_write_com(0x80);            //設(shè)置指針
  116.             LCD1602_write_word("20");
  117.             LCD1602_write_data(Year_High);
  118.             LCD1602_write_data(Year_Low);
  119.             LCD1602_write_data('-');
  120.    
  121.             LCD1602_write_data(Month_High);
  122.             LCD1602_write_data(Month_Low);
  123.             LCD1602_write_data('-');
  124.    
  125.             LCD1602_write_data(Day_High);
  126.             LCD1602_write_data(Day_Low);
  127.             
  128.             
  129.             LCD1602_write_com(0x80+0x40);            //設(shè)置指針
  130.             LCD1602_write_word("Speed:");                //顯示內(nèi)容

  131.             LCD1602_write_data(Display_GPRMC_Buffer[46]);        
  132.             LCD1602_write_data(Display_GPRMC_Buffer[47]);        
  133.             LCD1602_write_data(Display_GPRMC_Buffer[48]);            
  134.             LCD1602_write_data(Display_GPRMC_Buffer[49]);   
  135.             LCD1602_write_data(Display_GPRMC_Buffer[50]);
  136.             
  137.             LCD1602_write_word("m/s");               
  138.         }        
  139.     }
  140. }
  141. //****************************************************
  142. //UTC日期與當(dāng)?shù)厝掌谵D(zhuǎn)換
  143. //****************************************************
  144. void UTCDate2LocalDate(void)
  145. {
  146.     Day = (Day_High - 0x30) * 10 + (Day_Low-0x30) + 1;        //日  加一
  147.     Month = (Month_High - 0x30) * 10 + (Month_Low - 0x30);
  148.     Year = 2000 + (Year_High - 0x30) * 10 + (Year_Low - 0x30);
  149.    
  150.     MaxDay = GetMaxDay(Month,Year);                //獲取當(dāng)月 天數(shù) 最大值
  151.     if(Day > MaxDay)        //溢出
  152.     {
  153.         Day = 1;
  154.         Month += 1;
  155.         if(Month > 12)
  156.         {
  157.             Year+=1;
  158.         }
  159.     }

  160.     Day_High = Day/10 + 0x30;                //轉(zhuǎn)換日期值為ASCII
  161.     Day_Low = Day%10 + 0x30;

  162.     Month_High = Month/10 + 0x30;            //轉(zhuǎn)換月份值為ASCII
  163.     Month_Low = Month%10 + 0x30;

  164.     Year_High = Year%100/10 + 0x30;            //轉(zhuǎn)換年份值為ASCII
  165.     Year_Low = Year%10 + 0x30;            
  166. }

  167. //****************************************************
  168. //獲取當(dāng)月日期最大值
  169. //****************************************************
  170. unsigned char GetMaxDay(unsigned char Month_Value,unsigned int Year_Value)
  171. {
  172.     unsigned char iDays;
  173.     switch(Month_Value)
  174.     {
  175.         case 1:
  176.         case 3:
  177.         case 5:
  178.         case 7:
  179.         case 8:
  180.         case 10:
  181.         case 12:
  182.             {
  183.                 iDays = 31;
  184.             }
  185.             break;
  186.         case 2:
  187.             {
  188.                 //2月份比較特殊,需要根據(jù)是不是閏年來判斷當(dāng)月是28天還29天
  189.                 iDays = IsLeapYear(Year_Value)?29:28;
  190.             }
  191.             break;
  192.         case 4:
  193.         case 6:
  194.         case 9:
  195.         case 11:
  196.             {
  197.                 iDays = 30;
  198.             }
  199.             break;
  200.         default : break;
  201.     }
  202.     return(iDays);                        
  203. }

  204. //****************************************************
  205. //閏年檢測
  206. //****************************************************
  207. bit IsLeapYear(unsigned int uiYear)
  208. {
  209.     return (((uiYear%4)==0)&&((uiYear%100)!=0))||((uiYear%400)==0);
  210. }


  211. //****************************************************
  212. //按鍵掃描程序
  213. //****************************************************
  214. void Scan_Key()
  215. {
  216.     if( KEY4 == 0 )                         //按鍵1掃描
  217.     {
  218.         Delay_ms(10);                    //延時(shí)去抖
  219.         if( KEY4 == 0 )
  220.         {
  221.             while(KEY4 == 0);            //等待松手
  222.             KEY_NUM = 3;
  223.             Page = ~Page;
  224.             LCD1602_write_com(0X01);    //清屏
  225.         }
  226.     }
  227. }
  228. //****************************************************
  229. //MS延時(shí)函數(shù)(12M晶振下測試)
  230. //****************************************************
  231. void Delay_ms(unsigned int n)
  232. {
  233.     unsigned int  i,j;
  234.     for(i=0;i<n;i++)
  235.         for(j=0;j<123;j++);
  236. }

復(fù)制代碼
51hei.png
以上4個(gè)C語言文件51hei附件下載:
GPS定位源代碼.rar (4.32 KB, 下載次數(shù): 95)

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評分

回復(fù)

使用道具 舉報(bào)

ID:869650 發(fā)表于 2021-7-19 09:30 | 顯示全部樓層
請問這是什么仿真軟件?
回復(fù)

使用道具 舉報(bào)

ID:953261 發(fā)表于 2021-7-19 22:17 | 顯示全部樓層
2748768859 發(fā)表于 2021-7-19 09:30
請問這是什么仿真軟件?

Fritzing,網(wǎng)上直接下載
回復(fù)

使用道具 舉報(bào)

ID:965903 發(fā)表于 2021-10-5 13:53 | 顯示全部樓層
能分享一下仿真工程嗎?
回復(fù)

使用道具 舉報(bào)

ID:140644 發(fā)表于 2022-3-28 22:24 | 顯示全部樓層
GPRS這么簡單么
回復(fù)

使用道具 舉報(bào)

ID:16255 發(fā)表于 2022-10-6 10:32 | 顯示全部樓層

GPRS
回復(fù)

使用道具 舉報(bào)

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

本版積分規(guī)則

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

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表