找回密码
 立即注册

QQ登录

只需一步,快速开始

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

51单片机GPS系统Proteus仿真程序,显示经纬度 串口模拟

  [复制链接]
跳转到指定楼层
楼主
基于51单片机的GPS系统,显示经纬度,由于gps是无法仿真的硬件 所以只能用串口来模拟
仿真原理图如下(proteus仿真工程文件可到本帖附件中下载)


单片机源程序如下:
  1. /*************************************
  2.     GPS解码显示程序,
  3. ***************************************/
  4. #include<reg52.h>
  5. #include "1602.h"
  6. //#include"math.h"
  7. //#include <stdlib.h>

  8. sbit GPS_SPD=P1^1;                //GPS模块速率设置
  9. sbit KEY1=P1^0;            //显示内容分屏切换,(T0,T1引脚 的第二功能为计数器。)
  10. char code TIME_AREA= 8;        //时区
  11. /***************************************
  12.        这是做的部分更改
  13. ************************************/
  14. unsigned long maxspeed,b;
  15. unsigned int count=0;
  16. unsigned int a[5];
  17. unsigned char hspeed[5];
  18. unsigned int dot_count;    //小数点计数器
  19. //unsigned char x;
  20. //GPS数据存储数组
  21. unsigned char JD[10];        //经度
  22. unsigned char JD_a;        //经度方向
  23. unsigned char WD[9];        //纬度
  24. unsigned char WD_a;        //纬度方向
  25. unsigned char date[6];        //日期
  26. unsigned char time[6];        //时间
  27. unsigned char speed[5]={'0','0','0','.','0'};        //速度
  28. unsigned char high[6];        //高度
  29. unsigned char angle[5]={'0','0','0','0','0'};        //方位角
  30. unsigned char use_sat[2];    //使用的卫星数
  31. unsigned char total_sat[2];    //天空中总卫星数
  32. unsigned char lock;            //定位状态

  33. //串口中断需要的变量
  34. unsigned char seg_count;    //逗号计数器
  35. unsigned char byte_count;    //位数计数器
  36. unsigned char cmd_number;    //命令类型
  37. unsigned char mode;            //0:结束模式,1:命令模式,2:数据模式
  38. unsigned char buf_full;        //1:整句接收完成,相应数据有效。0:缓存数据无效。
  39. unsigned char cmd[5];        //命令类型存储数组

  40. //显示需要的变量
  41. unsigned int dsp_count;        //刷新次数计数器
  42. //unsigned char time_count;
  43. bit page;

  44. void sys_init(void);
  45. bit chk_key(void);

  46. main()
  47. {
  48.     unsigned char i;
  49.     char Bhour;
  50.     sys_init();

  51.     lock=1;
  52.     use_sat[0]='0';
  53.     use_sat[1]='0';
  54.     total_sat[0]='0';
  55.     total_sat[1]='0';

  56.     while(1){
  57.         if(buf_full==0)                //无GPS信号时
  58.         {
  59.             dsp_count++;
  60.             if(dsp_count>=65000){
  61.                 LCD_cls();            //清屏
  62.                 LCD_write_string(0,0,"No GPS connect..");
  63.                 LCD_write_string(0,1,"Please Check..");
  64.                 while(buf_full==0);
  65.                 LCD_cls();   
  66.                 dsp_count=0;
  67.             }
  68.         }
  69.         else{                        //有GPS信号时
  70. /*************************************
  71.     最大速度处理
  72. *************************************/
  73.                      dot_count=0;
  74.                       b=0;
  75.                       for(i=0;i<5;i++)
  76.                       {
  77.                           if(speed[i]!='.')
  78.                              dot_count++;
  79.                           else

  80.                              break ;
  81.                       }
  82.                       switch(dot_count)
  83.                       {
  84.                         
  85.                          case 1:
  86.                               b=((speed[0]-'0')*10+(speed[2]-'0'))*1.852;
  87.                               break;
  88.                          case 2:
  89.                               b=((speed[0]-'0')*100+(speed[1]-'0')*10+(speed[4]-'0'))*1.852;
  90.                               break;
  91.                          case 3:
  92.                               b=((speed[0]-'0')*1000+(speed[1]-'0')*100+(speed[2]-'0')*10+(speed[4]-'0'))*1.852;
  93.                               break;
  94.                         
  95.                        }
  96.                       if(b>maxspeed)
  97.                       {
  98.                         maxspeed=b;
  99.                       }


  100. /*************************************
  101.     最大速度处理
  102. *************************************/



  103.             

  104.             if(chk_key()){                //检测到按键切换显示
  105.                 page=!page;
  106.                 LCD_cls();
  107.             }

  108.             if(!page){                        //页面1


  109.                               
  110.                 if(buf_full|0x01){                //GGA语句
  111.                     if(lock==0){                    //如果未定位
  112.                         LCD_write_string(0,0,"*---.--.----  ");
  113.                         LCD_write_string(0,1,"* --.--.----  ");                    
  114.                     }else{                            //如果已定位


  115.                         LCD_write_char(0,0,JD_a);            //显示经度
  116.                         for(i=0;i<3;i++)
  117.                         {
  118.                           LCD_write_char(i+1,0,JD[i]);
  119.                           }
  120.                         LCD_write_char(4,0,'.');
  121.                         for(i=3;i<10;i++)
  122.                         {
  123.                           LCD_write_char(i+2,0,JD[i]);
  124.                           }

  125.                         LCD_write_char(0,1,WD_a);            //显示纬度
  126.                         LCD_write_char(1,1,' ');
  127.                         for(i=0;i<2;i++)
  128.                         {
  129.                             LCD_write_char(i+2,1,WD[i]);
  130.                         }
  131.                         LCD_write_char(4,1,'.');

  132.                         for(i=2;i<9;i++)
  133.                         {
  134.                             LCD_write_char(i+3,1,WD[i]);
  135.                         }
  136.                                                 
  137.                         }
  138.                     LCD_write_char(14,1,use_sat[0]);        //显示接收卫星数
  139.                     LCD_write_char(15,1,use_sat[1]);
  140.                     buf_full&=~0x01;
  141.                     dsp_count=0;
  142.             }
  143.                 if(buf_full|0x02){                //GSV语句
  144.                     LCD_write_char(14,1,total_sat[0]);
  145.                     LCD_write_char(15,1,total_sat[1]);
  146.                     buf_full&=~0x02;
  147.                     dsp_count=0;
  148.                 }
  149.                 if(buf_full|0x04){
  150.                     if(lock==0){                    //如果未定位
  151.                         LCD_write_string(0,0,"*---.--.----  ");
  152.                         LCD_write_string(0,1,"* --.--.----  ");                    
  153.                     }else{                            //如果已定位



  154.                     LCD_write_char(0,0,JD_a);            //显示经度
  155.                     for(i=0;i<3;i++)
  156.                     {
  157.                       LCD_write_char(i+1,0,JD[i]);
  158.                       }
  159.                     LCD_write_char(4,0,'.');
  160.                     for(i=3;i<10;i++)
  161.                     {
  162.                       LCD_write_char(i+2,0,JD[i]);
  163.                       }
  164.                     LCD_write_char(0,1,WD_a);            //显示纬度
  165.                
  166.                     LCD_write_char(1,1,' ');
  167.                     for(i=0;i<2;i++)
  168.                     {
  169.                         LCD_write_char(i+2,1,WD[i]);
  170.                     }
  171.                     LCD_write_char(4,1,'.');

  172.                     for(i=2;i<9;i++)
  173.                     {
  174.                         LCD_write_char(i+3,1,WD[i]);
  175.                     }

  176.                      }
  177.                     LCD_write_char(14,0,use_sat[0]);        //显示接收卫星数
  178.                     LCD_write_char(15,0,use_sat[1]);
  179.                     buf_full&=~0x04;
  180.                     dsp_count=0;
  181.                 }
  182.             }
  183.             else{                            //页面2
  184.                 if(buf_full|0x01){                //GGA语句
  185.                     buf_full&=~0x01;
  186.                     dsp_count=0;
  187.                 }
  188.                 if(buf_full|0x02){
  189.                     buf_full&=~0x02;
  190.                     dsp_count=0;
  191.                 }
  192.                 if(buf_full|0x04){                //RMC语句
  193.                     Bhour=((time[0]-0x30)*10+time[1]-0x30)+TIME_AREA;
  194.                     if(Bhour>=24){
  195.                         Bhour-=24;
  196.                     }else if(Bhour<0){
  197.                         Bhour+=24;
  198.                     }

  199.                     LCD_write_char(0,1,date[4]);
  200.                     LCD_write_char(1,1,date[5]);
  201.                     LCD_write_char(2,1,date[2]);
  202.                     LCD_write_char(3,1,date[3]);
  203.                     LCD_write_char(4,1,date[0]);
  204.                     LCD_write_char(5,1,date[1]);

  205.                     LCD_write_char(8,1,Bhour/10+0x30);
  206.                     LCD_write_char(9,1,Bhour%10+0x30);
  207.                     LCD_write_char(10,1,':');
  208.                     LCD_write_char(11,1,time[2]);
  209.                     LCD_write_char(12,1,time[3]);
  210.                     LCD_write_char(13,1,':');
  211.                     LCD_write_char(14,1,time[4]);
  212.                     LCD_write_char(15,1,time[5]);

  213.                     LCD_write_string(5,0,"knot A");         

  214.                     if(lock=='0'){                    //如果未定位
  215.                         LCD_write_string(0,0,"---.-");
  216.                         LCD_write_string(11,0,"---.-");
  217.                     }else{                                                      //已经定位,在此处做的改动。
  218. /*******************************************************************************/


  219.               
  220.                            
  221.                            if(count<10)
  222.                            {
  223.                            
  224.                             for(i=0;i<5;i++)
  225.                             {            
  226.                             LCD_write_char(i,0,speed[i]);//knot显示
  227.                             }
  228.                             count++;
  229.                           }
  230.                           else
  231.                           {
  232.                             if(count>15)
  233.                             {  
  234.                                count=0;
  235.                             }

  236.                               hspeed[0]=maxspeed/1000+0x30;                     //把小数转成字符数组
  237.                               hspeed[1]=(maxspeed/100)%10+0x30;
  238.                               hspeed[2]=(maxspeed/10)%10+0x30;
  239.                               hspeed[3]='.';
  240.                               hspeed[4]= maxspeed%10+0x30;

  241.                              
  242.                             count++;
  243.                             LCD_write_string(5,0,"Km/h A");
  244.                             LCD_write_char(0,0,hspeed[0]);
  245.                             LCD_write_char(1,0,hspeed[1]);   
  246.                             LCD_write_char(2,0,hspeed[2]);
  247.                             LCD_write_char(3,0,hspeed[3]);
  248.                             LCD_write_char(4,0,hspeed[4]);    //最大速度显  */
  249.                         }
  250.                         
  251. /*******************************************************************************/
  252.                              for(i=0;i<5;i++){
  253.                                 LCD_write_char(11+i,0,angle[i]);
  254.                         }
  255.                     }
  256.                     buf_full&=~0x04;
  257.                     dsp_count=0;
  258.                 }
  259.             }

  260.         }
  261.     }
  262. }

  263. bit chk_key(void)
  264. {
  265.     if(!KEY1){
  266.         delayms(10);
  267.         if(!KEY1){
  268.             while(!KEY1);
  269.             delayms(10);
  270.             return(1);
  271.         }
  272.     }
  273.     LCD_cls();            //清屏
  274.     return(0);
  275. }

  276. //系统初始化
  277. void sys_init() {
  278.     unsigned char i;
  279.     SCON = 0x50;     /* SCON: mode 1, 8-bit UART, enable rcvr */
  280.     TMOD = 0x21;     /* TMOD: timer 1, mode 2, 8-bit reload */
  281.     if(GPS_SPD){
  282.         TH1 = 0xfa;         /* TH1: reload value for 9600 baud @ 11.059MHz */
  283.     }else{
  284.         TH1 = 0xfd;            /* TH1: reload value for 4800 baud @ 11.059MHz */
  285.     }
  286.     TR1 = 1;         /* TR1: timer 1 run */
  287.     LCD_init(8);        //初始化LCD
  288.     LCD_write_string(0,0," GPS SIRF II 2 ");
  289.     LCD_write_string(0,1," 11-11-23 1342 ");



  290.    
  291.     for(i=1;i<4;i++){
  292.         delayms(250);
  293.     }
  294.     //LCD_cls();
  295.     IE=0x90;            //开总中断、串口中断
  296. }

  297. //串口接收中断
  298. void uart(void) interrupt 4
  299. {
  300.     unsigned char tmp;
  301.     if(RI){
  302.         tmp=SBUF;
  303.         switch(tmp){
  304.             case '

  305.                 cmd_number=0;        //命令类型清空
  306.                 mode=1;                //接收命令模式
  307.                 byte_count=0;        //接收位数清空
  308.                 break;
  309.             case ',':
  310.                 seg_count++;        //逗号计数加1
  311.                 byte_count=0;
  312.                 break;
  313.             case '*':
  314.                 switch(cmd_number){
  315.                     case 1:
  316.                         buf_full|=0x01;
  317.                         break;
  318.                     case 2:
  319.                         buf_full|=0x02;
  320.                         break;
  321.                     case 3:
  322.                         buf_full|=0x04;
  323.                         break;
  324.                 }
  325.                 mode=0;
  326.                 break;
  327.             default:
  328.                 if(mode==1){
  329.                     //命令种类判断

  330.                     cmd[byte_count]=tmp;            //接收字符放入类型缓存
  331.                     if(byte_count>=4){                //如果类型数据接收完毕,判断类型
  332.                         if(cmd[0]=='G'){
  333.                             if(cmd[1]=='P'){
  334.                                 if(cmd[2]=='G'){
  335.                                     if(cmd[3]=='G'){
  336.                                         if(cmd[4]=='A'){
  337.                                             cmd_number=1;
  338.                                             mode=2;
  339.                                             seg_count=0;
  340.                                             byte_count=0;
  341.                                         }
  342.                                     }
  343.                                     else if(cmd[3]=='S'){
  344.                                         if(cmd[4]=='V'){
  345.                                             cmd_number=2;
  346.                                             mode=2;
  347.                                             seg_count=0;
  348.                                             byte_count=0;
  349.                                         }
  350.                                     }
  351.                                 }
  352.                                 else if(cmd[2]=='R'){
  353.                                     if(cmd[3]=='M'){
  354.                                         if(cmd[4]=='C'){
  355.                                             cmd_number=3;
  356.                                             mode=2;
  357.                                             seg_count=0;
  358.                                             byte_count=0;
  359.                                         }
  360.                                     }
  361.                                 }
  362.                             }
  363.                         }
  364.                     }
  365.                 }
  366.                 else if(mode==2){
  367.                     //接收数据处理
  368.                     switch (cmd_number){
  369.                         case 1:                //类型1数据接收。GPGGA
  370.                             switch(seg_count){
  371.                                 case 2:        //纬度处理
  372.                                     if(byte_count<9){
  373.                                         WD[byte_count]=tmp;
  374.                                     }
  375.                                     break;
  376.                                 case 3:        //纬度方向处理
  377.                                     if(byte_count<1){
  378.                                         WD_a=tmp;
  379.                                     }
  380.                                     break;
  381.                                 case 4:        //经度处理
  382.                                     if(byte_count<10){
  383.                                         JD[byte_count]=tmp;
  384.                                     }
  385.                                     break;
  386.                                 case 5:        //经度方向处理
  387.                                     if(byte_count<1){
  388.                                         JD_a=tmp;
  389.                                     }
  390.                                     break;
  391.                                 case 6:        //定位判断
  392.                                     if(byte_count<1){
  393.                                         lock=tmp;
  394.                                     }
  395.                                     break;
  396.                                 case 7:        //定位使用的卫星数
  397.                                     if(byte_count<2){
  398.                                         use_sat[byte_count]=tmp;
  399.                                     }
  400.                                     break;
  401.                                 case 9:        //高度处理
  402.                                     if(byte_count<6){
  403.                                         high[byte_count]=tmp;
  404.                                     }
  405.                                     break;
  406.                             }
  407.                             break;
  408.                         case 2:                //类型2数据接收。GPGSV
  409.                             switch(seg_count){
  410.                                 case 3:        //天空中的卫星总数
  411.                                     if(byte_count<2){
  412.                                         total_sat[byte_count]=tmp;
  413.                                     }
  414.                                     break;
  415.                             }
  416.                             break;
  417.                         case 3:                //类型3数据接收。GPRMC
  418.                             switch(seg_count){
  419.                                 case 1:        //时间处理
  420.                                     if(byte_count<6){               
  421.                                         time[byte_count]=tmp;   
  422.                                     }
  423.                                     break;
  424.                                 case 2:        //定位判断                        
  425.                                     if(byte_count<1){
  426.                                       if (tmp=='A') {lock=1;}
  427.                                       else{
  428.                                         lock=0;}
  429.                                     }
  430.                                     break;
  431.                                 case 3:        //纬度处理                        
  432.                                     if(byte_count<9){
  433.                                         WD[byte_count]=tmp;
  434.                                     }
  435.                                     break;
  436.                                 case 4:        //纬度方向处理                        
  437.                                     if(byte_count<1){
  438.                                         WD_a=tmp;
  439.                                     }
  440.                                     break;
  441.                                 case 5:        //经度处理                        
  442.                                     if(byte_count<10){
  443.                                         JD[byte_count]=tmp;
  444.                                     }
  445.                                     break;
  446.                                 case 6:        //经度方向处理                        
  447.                                     if(byte_count<1){
  448.                                         JD_a=tmp;
  449.                                     }
  450.                                     break;
  451.                                 case 7:        //速度处理                        
  452.                                     if(byte_count<5){
  453.                                         speed[byte_count]=tmp;
  454.                                     }
  455.                                     

  456.                                     break;
  457.                                 case 8:        //方位角处理                        
  458.                                     if(byte_count<5){
  459.                                         angle[byte_count]=tmp;
  460.                                     }
  461.                                     break;
  462.                                 case 9:        //方位角处理                        
  463.                                     if(byte_count<6){
  464.                                         date[byte_count]=tmp;
  465.                                     }
  466.                                     break;

  467.                             }
  468.                             break;
  469.                     }
  470.                 }
  471.                 byte_count++;        //接收数位加1
  472.                 break;
  473.         }
  474.     }
  475.     RI=0;
  476. }

复制代码
由于gps是无法仿真的硬件 所以只能用串口来模拟
Keil代码与Proteus仿真下载:
基于51单片机的GPS系统.zip (102.6 KB, 下载次数: 168)


评分

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

查看全部评分

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

使用道具 举报

沙发
ID:102963 发表于 2022-4-27 22:29 | 只看该作者
楼主,你的复位电路都没接对!
回复

使用道具 举报

板凳
ID:64053 发表于 2022-4-27 22:50 | 只看该作者
仿真接错复位也能工作真不靠谱
回复

使用道具 举报

地板
ID:748788 发表于 2022-4-28 08:32 | 只看该作者
省略晶振、复位也一样仿真
回复

使用道具 举报

5#
ID:1008194 发表于 2022-5-12 10:55 | 只看该作者
proteu中不是有GPS模块了嘛
回复

使用道具 举报

6#
ID:748788 发表于 2022-5-22 08:22 | 只看该作者
是的,加上vgps,再将at89c52的时钟频率改为11.0592就可以仿真了。另外楼主的例程功能还是比较全的。
回复

使用道具 举报

7#
ID:1056483 发表于 2023-1-9 13:38 | 只看该作者
如何实现仿真呀
回复

使用道具 举报

8#
ID:1063315 发表于 2023-2-17 13:25 | 只看该作者
另外楼主的例程功能还是比较全的
回复

使用道具 举报

9#
ID:257174 发表于 2023-3-3 17:36 | 只看该作者
wwh2382 发表于 2022-5-22 08:22
是的,加上vgps,再将at89c52的时钟频率改为11.0592就可以仿真了。另外楼主的例程功能还是比较全的。

请问需要发送发什么数据
回复

使用道具 举报

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

本版积分规则

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

Powered by 单片机教程网

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