STC89C58串口接收GPS信号(GPRMC)读取经纬度,时间。1604液晶(HD44780)显示

来源:互联网 发布:天文望远镜知乎 编辑:程序博客网 时间:2024/05/19 19:57
 

/******************************************************************************
Copyright 2007
All rights reserved.

文件名 :gps1602.c
模块名称:
功能概要:

取代版本:0.0.1
修改人 :
完成日期:2007.07.27
升级说明:create
cpu:stc89c58    晶振频率:11.0592Mhz
硬件连接:
---------------------------------------------------------------
|DB0-----P0.0 | DB4-----P0.4 | WR-------P2.2 | A0--------P2.1 |
|DB1-----P0.1 | DB5-----P0.5 | RD-------P2.4 | Vo悬空 |
|DB2-----P0.2 | DB6-----P0.6 | CS-------P2.5 |
|DB3-----P0.3 | DB7-----P0.7 | RST-------P2.3 |   
---------------------------------------------------------------
******************************************************************************/

#include <reg52.h>
#include <string.h>

#define LCM_Data P0
#define Busy 0x80   //用于检测LCM状态字中的Busy标识
sbit LCM_RW = P2^2;  //1602定义引脚
sbit LCM_RS = P2^1;
sbit LCM_E = P2^5;

//sbit GPS_SPD=P1^2;
//sbit SPD_TYPE=P1^3;
sbit KEY1=P1^1;


char code TIME_AREA= 8;            //时区

//GPS数据存储数组
unsigned char JD[10];            //经度
unsigned char JD_a;            //经度方向
unsigned char WD[9];            //纬度
unsigned char WD_a;            //纬度方向
unsigned char time[6];        //时间
unsigned char date[6];        //日期
unsigned char speed[5];        //速度
unsigned char high[6];        //高度
unsigned char angle[5];        //方位角
unsigned char use_sat[2];        //使用的卫星数
unsigned char total_sat[2];    //天空中总卫星数
unsigned char lock;            //定位状态

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

//显示需要的变量
unsigned int dsp_count;        //刷新次数计数器
unsigned char time_count;
bit page;
bit spd_type;

void sys_init(void);
bit chk_key(void);

void WriteDataLCM(unsigned char WDLCM);
void WriteCommandLCM(unsigned char WCLCM,BuysC);
unsigned char ReadDataLCM(void);
unsigned char ReadStatusLCM(void);
void LCMInit(void);
void LCD_cls(void);
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData);
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData);
void Delay5Ms(void);
void Delay400Ms(void);
/******************************************************************************************
* 函数名称    :
* 功能描述    :
* 参数        :  参数名称: 输入/输出? 类型  描述
*
* 返回值      :
* 作者        :
* 创建日期    :2006-12-19
* 全局变量    :
* 全局静态变量:
* 局部静态变量:
*----------------------------------------修改历史------------------------------------------
* 当前版本    :     修改人:                  修改日期:
* 修改说明    :
******************************************************************************************/
main()
{
    unsigned char i;
    char Bhour;
 //   unsigned int Knots;
    sys_init();

    while(1)
    {
        if(buf_full==0)                //无GPS信号时
        {
            dsp_count++;
            if(dsp_count>=65000)
             {
                LCD_cls();            //清屏
                DisplayListChar(0,0,"No GPS connect..");
                while(buf_full==0);
                LCD_cls();   
                dsp_count=0;
             }
        }
        else if(lock=='V')   //GPRMC语句
              {                    //如果未定位
                   DisplayListChar(0,2,"No Positioning");
                   LCD_cls();                  
              }
            else
              {                            //如果已定位
                   DisplayOneChar(0,0,JD_a);            //显示经度
                   DisplayOneChar(1,0,' ');
                   for(i=0;i<3;i++)
                   {
                        DisplayOneChar(i+1,0,JD[i]);
                   }
                   DisplayOneChar(4,0,'.');
                   for(i=3;i<10;i++)
                   {
                        DisplayOneChar(i+2,0,JD[i]);
                   }
       DisplayOneChar(0,1,WD_a);            //显示纬度
                   DisplayOneChar(1,1,' ');
                   for(i=0;i<2;i++)
                   {
                        DisplayOneChar(i+2,1,WD[i]);
                   }           
                   DisplayOneChar(4,1,'.');
                   for(i=2;i<9;i++)
                   {
                        DisplayOneChar(i+3,1,WD[i]);
                   }
                   DisplayOneChar(1,2,'2');        //日期2009-03-24
                   DisplayOneChar(2,2,'0');
       DisplayOneChar(3,2,date[4]);
       DisplayOneChar(4,2,date[5]);
       DisplayOneChar(5,2,'-');
                   DisplayOneChar(6,2,date[2]);
                   DisplayOneChar(7,2,date[3]);
       DisplayOneChar(8,2,'-');
       DisplayOneChar(9,2,date[0]);
       DisplayOneChar(10,2,date[1]);
      
     Bhour=((time[0]-0x30)*10+time[1]-0x30)+TIME_AREA;
                    if(Bhour>=24)
                    {
                        Bhour-=24;
                    }
                    else if(Bhour<0)
                    {
                        Bhour+=24;
                    }
                //    DisplayListChar(2,3,"BJT ");
                    DisplayOneChar(1,3,Bhour/10+0x30);
                    DisplayOneChar(2,3,Bhour%10+0x30);
                    DisplayOneChar(3,3,':');
                    DisplayOneChar(4,3,time[2]);
                    DisplayOneChar(5,3,time[3]);
                    DisplayOneChar(6,3,':');
                    DisplayOneChar(7,3,time[4]);
                    DisplayOneChar(8,3,time[5]);
                 //   if(spd_type)
                 //   {
                 //       DisplayListChar(5,3,"km/h A");
                 //   }
                 //   else
                 //   {
                 //       DisplayListChar(5,3,"knot A");
                 //   }
                                          
                 //   if(spd_type)
                 //   {                    //km/h显示
                  //      for(i=0;i<5;i++)
                 //       {
                 //            DisplayOneChar(i,0,speed[i]);
                 //       }
                  //  }
                  //  else
    // {                             //knot显示
                  //      Knots=    (((speed[0]-0x30)*1000
                  //                 +(speed[1]-0x30)*100
                  //                 +(speed[2]-0x30)*10
                  //                 +(speed[4]-0x30))*1000)/1852;
                  //      DisplayOneChar(0,3,Knots/1000+0x30);
                  //      DisplayOneChar(1,3,(Knots%1000)/100+0x30);
                  //      DisplayOneChar(2,3,(Knots%100)/10+0x30);
                  //      DisplayOneChar(3,3,'.');
                  //      DisplayOneChar(4,3,Knots%10+0x30);
                  //   }
                  //   for(i=0;i<5;i++)
                  //   {
                  //     DisplayOneChar(11+i,0,angle[i]);
                  //   }
                }
                   
                 
            dsp_count=0;
         }
}

/******************************************************************************************
* 函数名称    :
* 功能描述    :
* 参数        :  参数名称: 输入/输出? 类型  描述
*
* 返回值      :
* 作者        :
* 创建日期    :2006-12-19
* 全局变量    :
* 全局静态变量:
* 局部静态变量:
*----------------------------------------修改历史------------------------------------------
* 当前版本    :     修改人:                  修改日期:
* 修改说明    :
******************************************************************************************/
bit chk_key(void)
{
    if(!KEY1)
     {
        Delay5Ms();
        Delay5Ms();
        if(!KEY1)
         {
            while(!KEY1);
            Delay5Ms();
            Delay5Ms();
            return(1);
         }
     }
    return(0);
}

/******************************************************************************************
* 函数名称    :sys_init
* 功能描述    :系统初始化
* 参数        :  参数名称: 输入/输出? 类型  描述
*
* 返回值      :
* 作者        :
* 创建日期    :2006-12-19
* 全局变量    :
* 全局静态变量:
* 局部静态变量:
*----------------------------------------修改历史------------------------------------------
* 当前版本    :     修改人:                  修改日期:
* 修改说明    :
******************************************************************************************/
void sys_init()
{
  
    SCON = 0x50;     /* SCON: mode 1, 8-bit UART, enable rcvr */
    TMOD = 0x21;     /* TMOD: timer 1, mode 2, 8-bit reload */
    TH1 = 0xfa;            /* TH1: reload value for 4800 baud @ 11.059MHz */

  
    spd_type=1;            //速度单位km/h
   
    TR1 = 1;         /* TR1: timer 1 run */
    LCMInit();        //初始化LCD
    DisplayListChar(0,0,"GPS Monitor V1.2");
    Delay400Ms();
    LCD_cls();
    IE=0x90;            //开总中断、串口中断
}

/******************************************************************************************
* 函数名称    :WriteDataLCM
* 功能描述    :写数据
* 参数        :  参数名称: 输入/输出? 类型  描述
*
* 返回值      :
* 作者        :
* 创建日期    :2006-12-19
* 全局变量    :
* 全局静态变量:
* 局部静态变量:
*----------------------------------------修改历史------------------------------------------
* 当前版本    :     修改人:                  修改日期:
* 修改说明    :
******************************************************************************************/
void WriteDataLCM(unsigned char WDLCM)
{
  ReadStatusLCM(); //检测忙
  LCM_Data = WDLCM;
  LCM_RS = 1;
  LCM_RW = 0;
  LCM_E = 0; //若晶振速度太高可以在这后加小的延时
  LCM_E = 0; //延时
  LCM_E = 1;
}

/******************************************************************************************
* 函数名称    :WriteCommandLCM
* 功能描述    :写指令
* 参数        :  参数名称: 输入/输出? 类型  描述
*
* 返回值      :
* 作者        :
* 创建日期    :2006-12-19
* 全局变量    :
* 全局静态变量:
* 局部静态变量:
*----------------------------------------修改历史------------------------------------------
* 当前版本    :     修改人:                  修改日期:
* 修改说明    :
******************************************************************************************/
void WriteCommandLCM(unsigned char WCLCM,BuysC) //BuysC为0时忽略忙检测
{
  if (BuysC)
  ReadStatusLCM(); //根据需要检测忙
  LCM_Data = WCLCM;
  LCM_RS = 0;
  LCM_RW = 0;
  LCM_E = 0;
  LCM_E = 0;
  LCM_E = 1;
}

/******************************************************************************************
* 函数名称    :ReadStatusLCM
* 功能描述    :读状态
* 参数        :  参数名称: 输入/输出? 类型  描述
*
* 返回值      :
* 作者        :
* 创建日期    :2006-12-19
* 全局变量    :
* 全局静态变量:
* 局部静态变量:
*----------------------------------------修改历史------------------------------------------
* 当前版本    :     修改人:                  修改日期:
* 修改说明    :
******************************************************************************************/
unsigned char ReadStatusLCM(void)
{
  LCM_Data = 0xFF;
  LCM_RS = 0;
  LCM_RW = 1;
  LCM_E = 0;
  LCM_E = 0;
  LCM_E = 1;
  while (LCM_Data & Busy); //检测忙信号
  return(LCM_Data);
}
/******************************************************************************************
* 函数名称    :LCMInit
* 功能描述    :LCM初始化
* 参数        :  参数名称: 输入/输出? 类型  描述
*
* 返回值      :
* 作者        :
* 创建日期    :2006-12-19
* 全局变量    :
* 全局静态变量:
* 局部静态变量:
*----------------------------------------修改历史------------------------------------------
* 当前版本    :     修改人:                  修改日期:
* 修改说明    :
******************************************************************************************/
void LCMInit(void)
{
     Delay400Ms();
  LCM_Data = 0;
  WriteCommandLCM(0x38,0); //三次显示模式设置,不检测忙信号
  Delay5Ms();
  WriteCommandLCM(0x38,0);
  Delay5Ms();
  WriteCommandLCM(0x38,0);
  Delay5Ms();

  WriteCommandLCM(0x38,1); //显示模式设置,开始要求每次检测忙信号
  WriteCommandLCM(0x08,1); //关闭显示
  WriteCommandLCM(0x01,1); //显示清屏
  WriteCommandLCM(0x06,1); // 显示光标移动设置
  WriteCommandLCM(0x0C,1); // 显示开及光标设置
}
/******************************************************************************************
* 函数名称    :LCMInit
* 功能描述    :LCM初始化
* 参数        :  参数名称: 输入/输出? 类型  描述
*
* 返回值      :
* 作者        :
* 创建日期    :2006-12-19
* 全局变量    :
* 全局静态变量:
* 局部静态变量:
*----------------------------------------修改历史------------------------------------------
* 当前版本    :     修改人:                  修改日期:
* 修改说明    :
******************************************************************************************/
void LCD_cls(void)
{
  WriteCommandLCM(0x01,0);
  Delay5Ms();
}
/******************************************************************************************
* 函数名称    :DisplayOneChar
* 功能描述    :按指定位置显示一个字符
* 参数        :  参数名称: 输入/输出? 类型  描述
*
* 返回值      :
* 作者        :
* 创建日期    :2006-12-19
* 全局变量    :
* 全局静态变量:
* 局部静态变量:
*----------------------------------------修改历史------------------------------------------
* 当前版本    :     修改人:                  修改日期:
* 修改说明    :
******************************************************************************************/
void DisplayOneChar(unsigned char X, unsigned char Y, unsigned char DData)
{
//  Y &= 0x1;
  X &= 0xF; //限制X不能大于15,Y不能大于1
       
  switch(Y)
  {

   case 0: 
    X += 0x00; //当要显示第一行时地址码+0x40;
    X += 0x80; //算出指令码
    WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
    WriteDataLCM(DData);
   case 1: 
    X += 0x40; //当要显示第二行时地址码+0x40;
    X += 0x80; //算出指令码
    WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
    WriteDataLCM(DData);
       break;
   case 2:
    X += 0x10; //当要显示第三行时地址码+0x10;
    X += 0x80; //算出指令码
    WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
    WriteDataLCM(DData);
       break;
   case 3:
    X += 0x50; //当要显示第四行时地址码+0x50;
    X += 0x80; //算出指令码
    WriteCommandLCM(X, 0); //这里不检测忙信号,发送地址码
    WriteDataLCM(DData);
       break;
   
   default: break;
  }
  
}
/******************************************************************************************
* 函数名称    :DisplayListChar
* 功能描述    :按指定位置显示一串字符  ***原来的遇到空格0x20就不显示***
* 参数        :  参数名称: 输入/输出? 类型  描述
*
* 返回值      :
* 作者        :
* 创建日期    :2006-12-19
* 全局变量    :
* 全局静态变量:
* 局部静态变量:
*----------------------------------------修改历史------------------------------------------
* 当前版本    :     修改人:                  修改日期:
* 修改说明    :
******************************************************************************************/
void DisplayListChar(unsigned char X, unsigned char Y, unsigned char code *DData)
{
   unsigned char ListLength,j;
   ListLength = strlen(DData);
//   Y &= 0x1;
   X &= 0xF; //限制X不能大于15,Y不能大于1
    if (X <= 0xF) //X坐标应小于0xF
      {
      for(j=0;j<ListLength;j++)
       {
              DisplayOneChar(X, Y, DData[j]); //显示单个字符
              X++;
             }
       }
}

/******************************************************************************************
* 函数名称    :Delay5M
* 功能描述    :5ms延时
* 参数        :  参数名称: 输入/输出? 类型  描述
*
* 返回值      :
* 作者        :
* 创建日期    :2006-12-19
* 全局变量    :
* 全局静态变量:
* 局部静态变量:
*----------------------------------------修改历史------------------------------------------
* 当前版本    :     修改人:                  修改日期:
* 修改说明    :
******************************************************************************************/
void Delay5Ms(void)
{
   unsigned int TempCyc = 5552;
   while(TempCyc--);
}
/******************************************************************************************
* 函数名称    :Delay400Ms
* 功能描述    :400ms延时
* 参数        :  参数名称: 输入/输出? 类型  描述
*
* 返回值      :
* 作者        :
* 创建日期    :2006-12-19
* 全局变量    :
* 全局静态变量:
* 局部静态变量:
*----------------------------------------修改历史------------------------------------------
* 当前版本    :     修改人:                  修改日期:
* 修改说明    :
******************************************************************************************/
void Delay400Ms(void)
{
   unsigned char TempCycA = 5;
   unsigned int TempCycB;
   while(TempCycA--)
  {
   TempCycB=7269;
   while(TempCycB--);
  };
}

/******************************************************************************************
* 函数名称    :uart
* 功能描述    :串口接收中断
* 参数        :  参数名称: 输入/输出? 类型  描述
*
* 返回值      :
* 作者        :
* 创建日期    :2006-12-19
* 全局变量    :
* 全局静态变量:
* 局部静态变量:
*----------------------------------------修改历史------------------------------------------
* 当前版本    :     修改人:                  修改日期:
* 修改说明    :
******************************************************************************************/
void uart(void) interrupt 4
{
    unsigned char tmp;
    if(RI)
     {
        tmp=SBUF;
        switch(tmp)
        {
            case '$':
                cmd_number=0;        //命令类型清空
                mode=1;                //接收命令模式
                byte_count=0;        //接收位数清空
                break;
            case ',':
                seg_count++;        //逗号计数加1
                byte_count=0;
                break;
            case '*':
                switch(cmd_number)
                {
                    case 1:
                        buf_full|=0x01;
                        break;
                    case 2:
                        buf_full|=0x02;
                        break;
                    case 3:
                        buf_full|=0x04;
                        break;
                }
                mode=0;
                break;
            default:
                if(mode==1)
                 {
                    //命令种类判断
                    cmd[byte_count]=tmp;            //接收字符放入类型缓存
                    if(byte_count>=4)
                     {                //如果类型数据接收完毕,判断类型
                        if(cmd[0]=='G')
                         {
                            if(cmd[1]=='P')
                             {
                                if(cmd[2]=='R')
                                 {
                                    if(cmd[3]=='M')
                                     {
                                        if(cmd[4]=='C')
                                         {
                                            cmd_number=3;
                                            mode=2;
                                            seg_count=0;
                                            byte_count=0;
                                         }
                                     }
                            
                                 }
                               
                                 
                            }
                        }
                    }
                }
                else if(mode==2)
                 {
                    //接收数据处理
                    switch (cmd_number)
                    {
                       
                        case 3:                //类型3数据接收。GPRMC
                            switch(seg_count)
                            {
                                case 1:
                                    if(byte_count<6)
                                     {                //时间处理
                                        time[byte_count]=tmp;   
                                     }
                                    break;
        case 2:                                //定位判断A or V
                                    if(byte_count<1)
                                     {
                                        lock=tmp;
                                     }
        case 3:                                //纬度处理
                                    if(byte_count<9)
                                     {
                                        WD[byte_count]=tmp;
                                     }
                                    break;
        case 4:                                //纬度方向处理
                                    if(byte_count<1)
                                     {
                                        WD_a=tmp;
                                     }
                                    break;
        case 5:                                //经度处理
                                    if(byte_count<10)
                                     {
                                        JD[byte_count]=tmp;
                                     }
                                    break;
                                case 6:                                //经度方向处理
                                    if(byte_count<1)
                                     {
                                        JD_a=tmp;
                                     }
                                    break;
                                case 7:                                //速度处理
                                    if(byte_count<5)
                                     {
                                        speed[byte_count]=tmp;
                                     }
                                    break;
                                case 8:                                //航向处理
                                    if(byte_count<5)
                                     {
                                        angle[byte_count]=tmp;
                                     }
                                    break;
        case 9:                                //日期处理
                                    if(byte_count<6)
                                     {
                                        date[byte_count]=tmp;
                                     }
                                    break;
                            }
                            break;
                    }
                }
                byte_count++;        //接收数位加1
                break;
        }
    }
    RI=0;
}

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果手机云备份空间不足怎么办 办信用卡不知道公司电话怎么办 办信用卡不知道单位电话怎么办 朋友沉迷网络游戏怎么办英文作文 平板的密码忘了怎么办 白泥面膜过期了怎么办 小米手机桌面短信图标不见了怎么办 亚马逊账号注册扣款不成功怎么办 流量卡不用了怎么办啊 移动卡不想要了怎么办 b站调用速度过快怎么办 苹果系统占用19g怎么办 id被锁定了忘记密码怎么办 360儿童卫士忘记密码怎么办 微信注册忘记密码怎么办 旅行青蛙换手机iphone怎么办 网页邮箱添加不了附件怎么办 pos机密码忘了怎么办 在4楼上课地震了怎么办 微鲸电视待机打不开怎么办 苹果手机微信听不到语音怎么办 电信怎么办腾讯频看电视不要流量 孩子做事效率低怎么办教案 孩子做事效率低怎么办读后感 做事效率低总是焦虑怎么办 红米手机黑屏打不开怎么办 手机萤石云视频下载打不开怎么办 oppo打开网页视频慢怎么办? 晒课显示待提交怎么办 华为手机无法访问移动网络怎么办 晒课上传课堂实录太大怎么办 手机酷狗音乐下载要钱怎么办 手机酷狗下载要钱怎么办 酷我音乐没有声音怎么办 手机酷我音乐没有声音怎么办 酷我音乐歌曲下载收费怎么办 网易云下载超过每日上限怎么办 全民k歌领不了花怎么办 安卓全民k歌延迟怎么办 全民k歌唱歌延迟怎么办 全民k歌耳机延迟怎么办