标题: 单片机GPS定位LCD1602液晶显示经纬度海拔及时间日期的实物制作 [打印本页]

作者: Maxdodo    时间: 2019-3-28 10:34
标题: 单片机GPS定位LCD1602液晶显示经纬度海拔及时间日期的实物制作
此贴与我上一帖所用元器件一样,只是对程序做了改进,加了一个切屏按键,附上原理图
原理图.pdf (83.78 KB, 下载次数: 255)

制作出来的实物图如下:


单片机源程序如下:
  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. ……………………

  210. …………限于本文篇幅 余下代码请从51黑下载附件…………
复制代码

所有资料51hei提供下载:
GPS程序.zip (203.45 KB, 下载次数: 412)





作者: 仓与无涯    时间: 2019-4-2 00:10
GPS模块是哪个?
作者: tieq1952    时间: 2019-4-2 07:27
谢谢分享!!!
作者: zzt1747    时间: 2019-4-24 16:10
谢谢分享学习一个
作者: 大君    时间: 2019-5-19 14:19
请问一下,为什么我用计算机串口模拟gps信息给单片机发送,液晶屏就有显示。而我用gps给单片机串口发送就不好使呢
作者: 老柴柴电    时间: 2019-5-28 22:28
我觉得这个GPS模块还是挺有开发价值的
作者: huaaaa    时间: 2019-5-28 23:47
这个太牛了
作者: rsx9583    时间: 2019-5-30 20:12
大君 发表于 2019-5-19 14:19
请问一下,为什么我用计算机串口模拟gps信息给单片机发送,液晶屏就有显示。而我用gps给单片机串口发送就不 ...

你在单片机发送和读取程序之间增加一段延时。有时候是因为模块还没来得及反应过来,单片机就读取数据,导致读取错误。
作者: myhj    时间: 2019-7-26 17:39
请问,GPS模块与单片机如何联接呢?
作者: zqy1818    时间: 2019-10-19 10:18
感谢楼主分享
作者: 刘钊天下无敌    时间: 2019-10-22 09:30
楼主有没有gps仿真图
作者: 长头发小光头    时间: 2019-10-23 16:16
我觉得可以试试
作者: maxmini    时间: 2019-10-23 16:28
感谢楼主分享
作者: 1655    时间: 2019-10-23 21:16
GPS模块是什么型号的?
作者: 1255230    时间: 2019-11-17 22:51
谢谢大神的分享
作者: 野比大雄    时间: 2019-12-18 18:32
有仿真图吗

作者: ynzsc001    时间: 2019-12-30 14:26
昨天我点下载,提示忙,币也扣了,资料没见着
作者: ynzsc001    时间: 2019-12-30 16:50
下载看看,行不行在反馈
作者: 112253    时间: 2019-12-30 22:35
效果很不错
作者: 温xyz    时间: 2019-12-30 22:51
谢谢分享。这个能精确到秒吗?1分精度有点低。
作者: 持勤补拙    时间: 2019-12-31 14:26
感谢楼主分享
作者: 1589777657    时间: 2019-12-31 18:08
现在这个一个简单APP就能实现了,玩玩好了。
作者: zkele    时间: 2019-12-31 19:45
谢谢分享学习一下
作者: 机电男神    时间: 2020-1-5 16:27
把这个程序移植到STC15上可以直接用么,还是要改程序,LCD才能显示
作者: ynzsc001    时间: 2020-1-30 10:18
楼主你好。我在此程序基础上增加 DS 18B20  测温功能,结果是只有温度 没有GPS信息了!!!
作者: 51hei**1140    时间: 2020-1-30 10:31
机电男神 发表于 2020-1-5 16:27
把这个程序移植到STC15上可以直接用么,还是要改程序,LCD才能显示

你好!
1、显示部分有可能直接能用
2、需要改程序初始化部分
3、带有延时的地方,需要修改
作者: 51hei**1140    时间: 2020-1-31 16:09
ynzsc001 发表于 2020-1-30 10:18
楼主你好。我在此程序基础上增加 DS 18B20  测温功能,结果是只有温度 没有GPS信息了!!!

你好!没有程序没有图纸,没法知道是因为什么
作者: 1234sue    时间: 2020-4-25 20:40
楼主为什么我用虚拟gps串口通讯,lcd显示黑块

XE~6Y8F9C]8D5$JEVDAQ(62.png (5.05 KB, 下载次数: 141)

XE~6Y8F9C]8D5$JEVDAQ(62.png

作者: daocheng    时间: 2020-4-26 11:45
真厉害!用的是什么GPS模块?
一直想做单片机GPS定位,学习到了,谢谢分享!
作者: 舒##    时间: 2020-5-4 10:41
这个资料真的很棒!已经使用过了,显示效果很好,顶!!!
作者: dh51    时间: 2020-12-26 11:08
请问GPS模块用的什么型号?
作者: dhc51    时间: 2020-12-26 15:16
请问楼主单片机和GPS模块怎么连接?
作者: wwh2382    时间: 2020-12-26 17:37
正点原子的,ATK1218-BD或ATK-S1216,价格在百元左右
作者: liliyuyuqingqin    时间: 2020-12-30 17:10
本人请问有小白请问有32的,请问大佬有3有32的源代码吗
作者: 黄黄黄12138    时间: 2021-2-4 11:27
啊,我是个小白,想问问这种怎么做上位机呢
作者: Cf13655859831    时间: 2021-4-11 22:56
有原理图吗,楼主

作者: xiexugang    时间: 2021-4-12 00:28
这个定位制作,太有用了.
作者: usaboy    时间: 2021-4-12 03:18
excellent job, thank you Sir!
作者: shumivan    时间: 2021-4-12 08:48
简单的产品定位操作还可以,如果是实时的,比如车载,那么这个就满足不了实际需求,存在飘移的问题.这个GPS目测是串口的吧.看着和UBLOX相似.
作者: reking8    时间: 2021-6-2 14:35
这个不错 挺简单的 正好需要

作者: 747864037    时间: 2021-6-4 08:44
真的是好文章,对51单片机理解更深了,原来程序还能这么写
作者: ak333    时间: 2021-6-8 11:11
先收下了,谢谢分享,好东西,
作者: hstdj    时间: 2022-11-29 12:21
太好了,正在找资料,准备做个装摩托车上,下次摩旅高原就能随时知道海拔了
作者: ge52    时间: 2022-12-8 20:05
开阔眼界
作者: park05pc    时间: 2023-7-17 17:34
赞楼主作品! 我完全模仿做一个试试。 有问题, 还得要请教老师你呀!
作者: 15699183053    时间: 2023-7-23 11:28
这个不错 挺简单的 正好需要
作者: cnfloatleaf    时间: 2023-7-23 17:21
某一个宝上有北斗GPS天线和模块一体的,价格也就小几十,直接输出TTL的串行数据报文,用起来也方便。
作者: 范莉萍    时间: 2023-8-11 13:30
刚好正在学习GPS




欢迎光临 (http://www.51hei.com/bbs/) Powered by Discuz! X3.1