找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 15211|回复: 23
打印 上一主题 下一主题
收起左侧

51单片机GPS定位12864显示程序与原理图

  [复制链接]
跳转到指定楼层
楼主
系统硬件电路主要有GPS、液晶显示器、STC12C5A60S2、LED状态指示单片机上电复位和电源等部分组成。GPS发送的串行数据送至单片机串行口经处理后通过键盘选择要显示的信息,送至LCD液晶显示器。LCD液晶显示器会定时更新,更新周期约为1 s。上电复位电路为单片机上电提供上电复位。电源电路为各个电路提供稳定的电源。

电路图用AD画的




STC12C5A60S2单片机源程序如下:
  1. #include "STC12C5A.H"
  2. #include "stdio.h"
  3. #include "stdlib.h"
  4. #include "string.h"
  5. #include "uart.h"
  6. #include "timer0.h"
  7. #include "key.h"
  8. #include "lcd12864.h"
  9. #include "GPS.h"
  10. #include "GPS_PacketQueue.h"

  11. extern unsigned long Timer0_Count;             // 系统时基

  12. unsigned char Display_Flag = 0;                          // 显示界面(0 - 时间经纬度,1 - 速度等)

  13. unsigned char xdata DateTime[7] = {0};                // 时间和日期缓冲:秒,时,分,日,月,星期,年

  14. /*-------------GPS相关变量-------- --------------------*/
  15. GPS_INFO   xdata GPS;  
  16. unsigned char GPS_Flag = 0;                 // GPS数据有效标志

  17. // 函数声明
  18. void LCD_Display_DateTime(unsigned char *pDataTime);    // LCD显示时间,日期
  19. void LCD_Display_Longitude_Latitude(GPS_INFO *GPS);     // LCD显示经纬度
  20. void LCD_Display_Speed(GPS_INFO *GPS);                  // LCD显示速度,航向等


  21. /****************************************
  22.         主函数       
  23. /****************************************/
  24. void main(void)
  25. {       
  26.     char key_value = 0;
  27.            struct timer  Display_Time;
  28.         struct timer  Flag_Time;
  29.         struct timer  Error_Time;
  30.     GPS_PACKET *Packet = NULL;
  31.     memset(&GPS,0,sizeof(GPS));             // 一定要清0
  32.          
  33.         timer_set(&Display_Time, CLOCK_SECOND/5);        // 200ms
  34.         timer_set(&Error_Time,   CLOCK_SECOND*2);        // 2S
  35.         timer_set(&Flag_Time,   CLOCK_SECOND*5);        // 3S
  36.     LCD_Init();   
  37.     GPS_PacketInit();                       // 接收缓冲区初始化
  38.    
  39.     UART_Init();                            // 初始化UART
  40.     Timer0_Init();                          // 启动定时器
  41.     while(1)
  42.     {                  
  43.         /*  处理GPS信号 */
  44.         Packet = NULL;
  45.         Packet = (GPS_PACKET *)GPS_GetPacket();

  46.         if( Packet ){      
  47.             timer_restart(&Error_Time);                         // 接收正确更新时间
  48.             if(Packet->DataType == 1){
  49.                 if(GPS_RMC_Parse(Packet->DataBuffer, &GPS))     // 解析GPRMC     
  50.                 {
  51.                     memset(Packet,0,sizeof(GPS_PACKET));   
  52.                     DateTime[6] = GPS.D.year;
  53.                     DateTime[4] = GPS.D.month;
  54.                     DateTime[3] = GPS.D.day;
  55.                     DateTime[2] = GPS.D.hour;
  56.                     DateTime[1] = GPS.D.minute;
  57.                     DateTime[0] = GPS.D.second;                                       
  58.                     GPS_Flag = 1;
  59.                 }
  60.                 else{                                           // 解析错误要清空缓冲区
  61.                     memset(Packet,0,sizeof(GPS_PACKET));
  62.                 }
  63.             }
  64.             else if(Packet->DataType == 2){
  65.                 if(GPS_GGA_Parse(Packet->DataBuffer, &GPS)){               
  66.                     memset(Packet,0,sizeof(GPS_PACKET));
  67.                     GPS_Flag = 1;
  68.                 }
  69.                 else{                                           // 解析错误要清空缓冲区
  70.                     memset(Packet,0,sizeof(GPS_PACKET));
  71.                 }
  72.             }
  73.         }
  74.         else{
  75.                         // 接收错误,且时长超过100*20ms = 2S,复位硬件
  76.                         if( timer_expired(&Error_Time) )
  77.                         {                               
  78.                                 UART_Init();
  79.                                 GPS_PacketInit();
  80.                                 timer_restart(&Error_Time);
  81.                                 GPS_Flag = 0;
  82.                         }
  83.         }
  84.                
  85.         
  86.                 if( timer_expired(&Flag_Time) )                         // 切换画面
  87.         {
  88.                         Display_Flag = ++Display_Flag % 2;
  89.                         LCD_Clear();
  90.                         timer_reset(&Flag_Time);
  91.                 }
  92.                
  93.         if( timer_expired(&Display_Time) )
  94.         {
  95.             timer_reset(&Display_Time);
  96.                        
  97.                         if(GPS_Flag == 0)
  98.                         {
  99.                                 memset(DateTime,0,sizeof(DateTime));
  100.                                 memset(&GPS,0,sizeof(GPS));
  101.                         }
  102.                         if(Display_Flag == 0)
  103.             {
  104.                                 LCD_Display_DateTime(DateTime);                 // 时间显示
  105.                                 LCD_Display_Longitude_Latitude(&GPS);                                
  106.            }
  107.                    else
  108.                    {
  109.                 LCD_Display_Speed(&GPS);   
  110.            }
  111.         }
  112.     }       
  113. }

  114. /*
  115.     日期和时间显示
  116. */
  117. void LCD_Display_DateTime(unsigned char *pDataTime)
  118. {
  119.     unsigned char temp_buffer[9] = {0};
  120.    
  121.     // 显示年,月,日
  122.     temp_buffer[0] = pDataTime[6]/10+0x30;
  123.     temp_buffer[1] = pDataTime[6]%10+0x30;   
  124.     Display_String(1,1,"20");
  125.     Display_String(2,1,temp_buffer);   
  126.         Display_String(3,1,"年");

  127.     temp_buffer[0] = pDataTime[4]/10+0x30;
  128.     temp_buffer[1] = pDataTime[4]%10+0x30;
  129.     Display_String(4,1,temp_buffer);   
  130.     Display_String(5,1,"月");

  131.     temp_buffer[0] = pDataTime[3]/10+0x30;
  132.     temp_buffer[1] = pDataTime[3]%10+0x30;
  133.     Display_String(6,1,temp_buffer);
  134.     temp_buffer[8] = '\0';
  135.         Display_String(7,1,"日");       
  136.    
  137.     // 显示时,分,秒
  138.     temp_buffer[0] = pDataTime[2]/10+0x30;
  139.     temp_buffer[1] = pDataTime[2]%10+0x30;
  140.     temp_buffer[2] = ':';
  141.     temp_buffer[3] = pDataTime[1]/10+0x30;
  142.     temp_buffer[4] = pDataTime[1]%10+0x30;
  143.     temp_buffer[5] = ':';
  144.     temp_buffer[6] = pDataTime[0]/10+0x30;
  145.     temp_buffer[7] = pDataTime[0]%10+0x30;
  146.     temp_buffer[8] = '\0';
  147.     Display_String(1,2,temp_buffer);
  148.    
  149.     // 显示星期
  150.     switch(DateTime[5]%10 -1)
  151.         {
  152.                 case 0:        Display_String(6,2,"星期日\0");break;
  153.                 case 1:        Display_String(6,2,"星期一\0");break;
  154.                 case 2:        Display_String(6,2,"星期二\0");break;
  155.                 case 3:        Display_String(6,2,"星期三\0");break;
  156.                 case 4: Display_String(6,2,"星期四\0");break;
  157.                 case 5:        Display_String(6,2,"星期五\0");break;
  158.                 case 6:        Display_String(6,2,"星期六\0");break;
  159.                 default: break;
  160.         }
  161. }

  162. /*
  163.     显示纬度和经度
  164. */
  165. void LCD_Display_Longitude_Latitude(GPS_INFO *GPS)
  166. {
  167.     unsigned char ch, i;
  168.     char info[20];
  169.    
  170.     if (GPS->NS == 'N')                                              //判断是北纬还是南纬
  171.         {
  172.         Display_String(1,3,"北纬");
  173.     }
  174.         else if (GPS->NS == 'S')
  175.     {
  176.         Display_String(1,3,"南纬");
  177.     }

  178.         if (GPS->EW == 'E')                                              //判断是东经还是西经
  179.         {
  180.         Display_String(1,4,"东经");
  181.     }       
  182.         else if (GPS->EW == 'W')
  183.     {
  184.         Display_String(1,4,"西经");
  185.     }

  186.     sprintf(info,":%3d\0",GPS->latitude_Degree);
  187.         LCD_XY(3, 3);
  188.         i = 0;
  189.         while(info[i] != '\0')
  190.         {
  191.                 ch = info[i++];
  192.                 LCD_Write_Data(ch);
  193.         }
  194.         LCD_Write_Data(0xA1);
  195.         LCD_Write_Data(0xE3);

  196.         Int_To_Str(GPS->latitude_Cent, info);   
  197.         i = 0;
  198.         while(info[i] != '\0')
  199.         {
  200.                 ch = info[i++];
  201.                 LCD_Write_Data(ch);
  202.         }
  203.         LCD_Write_Data(0xA1);
  204.         LCD_Write_Data(0xE4);

  205.         Int_To_Str(GPS->latitude_Second, info);
  206.         i = 0;
  207.         while(info[i] != '\0')
  208.         {
  209.                 ch = info[i++];
  210.                 LCD_Write_Data(ch);
  211.         }

  212.     sprintf(info,":%3d\0",GPS->longitude_Degree);
  213.     LCD_XY(3, 4);
  214.         i = 0;
  215.         while(info[i] != '\0')
  216.         {
  217.                 ch = info[i++];
  218.                 LCD_Write_Data(ch);
  219.         }
  220.         LCD_Write_Data(0xA1);
  221.         LCD_Write_Data(0xE3);

  222.         Int_To_Str(GPS->longitude_Cent, info);
  223.         i = 0;
  224.         while(info[i] != '\0')
  225.         {
  226.                 ch = info[i++];
  227.                 LCD_Write_Data(ch);
  228.         }
  229.         LCD_Write_Data(0xA1);
  230.         LCD_Write_Data(0xE4);

  231.         Int_To_Str(GPS->longitude_Second, info);  
  232.         i = 0;
  233.         while(info[i] != '\0')
  234.         {
  235.                 ch = info[i++];
  236.                 LCD_Write_Data(ch);
  237.         }

  238. }

  239. /*
  240.     把浮点数fla显示在LCD的坐标(x,y)位置
  241. */
  242. void Show_Float(float fla, unsigned char x, unsigned char y)
  243. {
  244.         int integar;
  245.         char Info[10],ch;
  246.         unsigned char i;
  247.        
  248.         LCD_XY(x, y);               
  249.         integar = (int)fla;             // 得到浮点数的整数部分
  250.         Int_To_Str(fla, Info);      
  251.         i = 0;
  252.         while(Info[i] !='\0')
  253.         {
  254.                 ch=Info[i++];
  255.                 LCD_Write_Data(ch);
  256.         }
  257.         LCD_Write_Data('.');   
  258.         fla = fla - integar;            // 得到浮点数的小数部分      
  259.        
  260.         fla =  fla * 10;                // 小数位第一位      
  261.         integar = (int)fla;
  262.         fla = fla - integar;            
  263.         ch = integar + 0x30;
  264.         LCD_Write_Data(ch);
  265.        
  266.         fla =  fla*10;                  // 小数位第二位                  
  267.         integar = (int)fla;
  268.         fla = fla - integar;
  269.         ch = integar + 0x30 ;
  270.     LCD_Write_Data(ch);
  271. }


  272. /*
  273.     显示速度,航向,海拔
  274. ……………………

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

所有资料51hei提供下载:
1. DXP版本原理图 & PCB.rar (478.27 KB, 下载次数: 291)
3. 程序.rar (172.8 KB, 下载次数: 310)



分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏14 分享淘帖 顶2 踩
回复

使用道具 举报

沙发
ID:293622 发表于 2018-3-18 17:20 来自手机 | 只看该作者
为啥出来一片乱码[惊讶.jpg]
回复

使用道具 举报

板凳
ID:293738 发表于 2018-3-19 16:30 | 只看该作者
以前见过一篇相近的 ,这次有源码,看看
回复

使用道具 举报

地板
ID:300840 发表于 2018-5-7 12:05 | 只看该作者
请问这个程序能用于stc89c52上吗
回复

使用道具 举报

5#
ID:348732 发表于 2018-6-10 14:12 | 只看该作者
不是很懂为什么编译报错*** ERROR L107: ADDRESS SPACE OVERFLOW
回复

使用道具 举报

6#
ID:373174 发表于 2018-7-21 19:53 | 只看该作者
楼主用的是什么型号的gps呢
回复

使用道具 举报

7#
ID:407830 发表于 2018-10-10 23:38 | 只看该作者
楼主用的是什么型号的gps呢
回复

使用道具 举报

8#
ID:424298 发表于 2018-11-10 22:17 | 只看该作者
谢谢分享
回复

使用道具 举报

9#
ID:424298 发表于 2018-11-10 22:19 | 只看该作者
GPS用的是芯片是什么,是用现成的模块吗
回复

使用道具 举报

10#
ID:462450 发表于 2019-1-5 14:26 | 只看该作者
什么型号呀
回复

使用道具 举报

11#
ID:148126 发表于 2019-3-4 16:47 | 只看该作者
这个有没有成品
回复

使用道具 举报

12#
ID:417470 发表于 2019-3-4 17:29 | 只看该作者
成品是啥样子的?
回复

使用道具 举报

13#
ID:99056 发表于 2019-4-24 21:45 | 只看该作者
下载来学习学习
回复

使用道具 举报

14#
ID:111376 发表于 2020-1-4 09:00 | 只看该作者
谢谢分享,学习了
回复

使用道具 举报

15#
ID:393707 发表于 2020-4-27 09:00 | 只看该作者
楼主用的是什么型号的gps呢
回复

使用道具 举报

16#
ID:600952 发表于 2020-4-27 10:22 | 只看该作者
GPS、液晶显示器、STC12C5A60S2实现的51单片机GPS定位12864显示,学习到了,谢谢分享!
我对GPS项目比较感兴趣,觉得比较高级,问一下楼主用的是什么型号的gps?新手买什么GPS模块比较好呢?再问一下可以用旧手机的GPS模块连到单片机上用吗?
回复

使用道具 举报

17#
ID:47032 发表于 2021-7-14 22:38 | 只看该作者
GPS都是通知的串口通信,应该是不分型号
回复

使用道具 举报

18#
ID:1111461 发表于 2024-3-2 19:37 | 只看该作者
谢谢楼主有这么好的程序
回复

使用道具 举报

19#
ID:98880 发表于 2024-3-12 11:20 | 只看该作者
谢谢了,我分析测试一下。看能用不?
回复

使用道具 举报

20#
ID:98880 发表于 2024-3-12 11:24 | 只看该作者
12864的主控是什么的?
回复

使用道具 举报

21#
ID:164146 发表于 2024-3-20 17:18 | 只看该作者
homedou 发表于 2024-3-12 11:24
12864的主控是什么的?

看代码,能带字库的,大概率是 ST7920,有PSB引脚的
回复

使用道具 举报

22#
ID:229502 发表于 2024-4-19 18:49 | 只看该作者
准备做个gps时钟。感谢楼主
回复

使用道具 举报

23#
ID:229502 发表于 2024-4-19 18:58 | 只看该作者
楼主,没看到key.c文件?
---
文件夹里看到了。再次感谢
回复

使用道具 举报

24#
ID:688460 发表于 2024-4-20 08:29 | 只看该作者
编译通过,0个错误,1个警告。OK
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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