找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 4747|回复: 5
收起左侧

基于51单片机做的GPS定位

  [复制链接]
ID:953261 发表于 2021-7-17 23:35 | 显示全部楼层 |阅读模式
这是我特想做的一个装置,在学长的帮助下,我们完成了它,直接上图。

这是板子出了点小故障,没点着

带烧录,点火成功,哈哈

仿真,不太会用这个东西

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

单片机源程序如下:
  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. //主函数
  14. //****************************************************
  15. void main()
  16. {
  17.     unsigned char i = 0;
  18.     Init_LCD1602();
  19.     LCD1602_write_com(0x80);                        //指针设置
  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"这一帧数据
  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时间转换到北京时间        UTC+8
  33.                                                                                                 //0x30为ASCII转换为数字
  34.             if( Hour >= 24)                //溢出
  35.             {
  36.                 Hour %= 24;                //获取当前Hour
  37.                 Flag_OV = 1;            //日期进位
  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);            //设置指针
  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);            //设置指针
  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]);            //经度
  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"这一帧数据
  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)            //有进位
  106.             {
  107.                 UTCDate2LocalDate();            //UTC日期转换为北京时间        
  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);            //设置指针
  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);            //设置指针
  130.             LCD1602_write_word("Speed:");                //显示内容

  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日期与当地日期转换
  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);                //获取当月 天数 最大值
  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;                //转换日期值为ASCII
  161.     Day_Low = Day%10 + 0x30;

  162.     Month_High = Month/10 + 0x30;            //转换月份值为ASCII
  163.     Month_Low = Month%10 + 0x30;

  164.     Year_High = Year%100/10 + 0x30;            //转换年份值为ASCII
  165.     Year_Low = Year%10 + 0x30;            
  166. }

  167. //****************************************************
  168. //获取当月日期最大值
  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月份比较特殊,需要根据是不是闰年来判断当月是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);                    //延时去抖
  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延时函数(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. }

复制代码
51hei.png
以上4个C语言文件51hei附件下载:
GPS定位源代码.rar (4.32 KB, 下载次数: 95)

评分

参与人数 1黑币 +50 收起 理由
admin + 50 共享资料的黑币奖励!

查看全部评分

回复

使用道具 举报

ID:869650 发表于 2021-7-19 09:30 | 显示全部楼层
请问这是什么仿真软件?
回复

使用道具 举报

ID:953261 发表于 2021-7-19 22:17 | 显示全部楼层
2748768859 发表于 2021-7-19 09:30
请问这是什么仿真软件?

Fritzing,网上直接下载
回复

使用道具 举报

ID:965903 发表于 2021-10-5 13:53 | 显示全部楼层
能分享一下仿真工程吗?
回复

使用道具 举报

ID:140644 发表于 2022-3-28 22:24 | 显示全部楼层
GPRS这么简单么
回复

使用道具 举报

ID:16255 发表于 2022-10-6 10:32 | 显示全部楼层

GPRS
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

快速回复 返回顶部 返回列表