#include <reg52.h>
#include "LCD1602.h"
#include "UART.h"
#include "Delay.h"
#include "GPS.h"
#include "config.h"
void main(void)
{
unsigned char i;
Uart_Init();
LCD1602_Init();
GPS_lock=1;
GPSUSE_satellite[0]='0';
GPSUSE_satellite[1]='0';
while(1)
{
if(Data_legitimate==0) //无GPS信号时
{
LCD1602_WriteCMD(CMD_clear);
Print_String(line_one," RTrobot GPS");
Print_String(line_two,"Please Waiting. ");
while(Data_legitimate==0);
Delay_Ms(200);
LCD1602_WriteCMD(CMD_clear);
}
else //有GPS信号
{
if(Data_legitimate|0x01) //GPGGA处理
{
if(GPS_lock==0) //未定位
{
Print_String(line_one," RTrobot GPS");
Print_String(line_two,"Waiting...");
}
else //已定位
{
Print_Char(line_one,0,GPS_longitude_dir); //显示经度
for(i=0;i<3;i++)
{
Print_Char(line_one,i+1,GPS_longitude[i]);
}
Print_Char(line_one,4,'.');
for(i=3;i<10;i++)
{
Print_Char(line_one,i+2,GPS_longitude[i]);
}
Print_Char(line_two,0,GPS_latitude_dir); //显示纬度
Print_Char(line_two,1,' ');
for(i=0;i<2;i++)
{
Print_Char(line_two,i+2,GPS_latitude[i]);
}
Print_Char(line_two,4,'.');
for(i=2;i<9;i++)
{
Print_Char(line_two,i+3,GPS_latitude[i]);
}
}
Data_legitimate&=~0x01;
}
Delay_Ms(500);
}
}
}
/*****************************************************************************
串口中断
/****************************************************************************/
void uart(void) interrupt 4
{
unsigned char UART_data;
if(RI)
{
UART_data=SBUF;
switch(UART_data)
{
case '$':
GPSDATA_number=0; //GPS数据类型清空
GPSDATA_mode=1; //接收命令模式
GPSDATA_count=0; //接收位数清空
break;
case ',':
GPSDOT_count++; //逗号计数加1
GPSDATA_count=0;
break;
case '*':
switch(GPSDATA_number)
{
case 1:
Data_legitimate|=0x01;//GPGGA
break;
case 2:
Data_legitimate|=0x02;//GPGSV
break;
case 3:
Data_legitimate|=0x04;//GPRMC
break;
}
GPSDATA_mode=0;
break;
default:
if(GPSDATA_mode==1) //类型种类判断
{
GPSDATA_cmd[GPSDATA_count]=UART_data; //接收字符放入类型缓存
if(GPSDATA_count==4) //如果类型数据接收完毕,判断类型
{
if(GPSDATA_cmd[0]=='G'&&GPSDATA_cmd[1]=='P'&&GPSDATA_cmd[2]=='G'&&GPSDATA_cmd[3]=='G'&&GPSDATA_cmd[4]=='A')//判断GPGGA
{
GPSDATA_number=1;
GPSDATA_mode=2;
GPSDOT_count=0;
GPSDATA_count=0;
}
if(GPSDATA_cmd[0]=='G'&&GPSDATA_cmd[1]=='P'&&GPSDATA_cmd[2]=='G'&&GPSDATA_cmd[3]=='S'&&GPSDATA_cmd[4]=='V')//判断GPGSV
{
GPSDATA_number=2;
GPSDATA_mode=2;
GPSDOT_count=0;
GPSDATA_count=0;
}
if(GPSDATA_cmd[0]=='G'&&GPSDATA_cmd[1]=='P'&&GPSDATA_cmd[2]=='R'&&GPSDATA_cmd[3]=='M'&&GPSDATA_cmd[4]=='C')//判断GPRMC
{
GPSDATA_number=3;
GPSDATA_mode=2;
GPSDOT_count=0;
GPSDATA_count=0;
}
/****************
....
其他类型照搬
****************/
}
}
else if(GPSDATA_mode==2) //接收数据处理
{
switch (GPSDATA_number)
{
case 1: //类型1数据接收。GPGGA
switch(GPSDOT_count)
{
case 2: //纬度处理
if(GPSDATA_count<9)
GPS_latitude[GPSDATA_count]=UART_data;
break;
case 3: //纬度方向处理
if(GPSDATA_count<1)
GPS_latitude_dir=UART_data;
break;
case 4: //经度处理
if(GPSDATA_count<10)
GPS_longitude[GPSDATA_count]=UART_data;
break;
case 5: //经度方向处理
if(GPSDATA_count<1)
GPS_longitude_dir=UART_data;
break;
case 6: //定位判断
if(GPSDATA_count<1)
GPS_lock=UART_data;
break;
case 7: //GPS使用卫星个数
if(GPSDATA_count<2)
GPSUSE_satellite[GPSDATA_count]=UART_data;
break;
case 9: //海拔高度处理
if(GPSDATA_count<6)
GPS_altitude[GPSDATA_count]=UART_data;
break;
}
break;
case 2: //类型2数据接收。GPGSV
switch(GPSDOT_count)
{
case 3: //GPS可见卫星个数
if(GPSDATA_count<2)
GPSVISIBLE_satellite[GPSDATA_count]=UART_data;
break;
}
break;
case 3: //类型3数据接收。GPRMC
switch(GPSDOT_count)
{
case 1: //时间处理
if(GPSDATA_count<6)
GPS_time[GPSDATA_count]=UART_data;
break;
case 2: //定位判断
if(GPSDATA_count<1)
{
if(UART_data=='A')
GPS_lock=1;
if(UART_data=='V')
GPS_lock=0;
}
break;
case 3: //纬度处理
if(GPSDATA_count<9)
{
GPS_latitude[GPSDATA_count]=UART_data;
}
break;
case 4: //纬度方向处理
if(GPSDATA_count<1)
{
GPS_latitude_dir=UART_data;
}
break;
case 5: //经度处理
if(GPSDATA_count<10)
{
GPS_longitude[GPSDATA_count]=UART_data;
}
break;
case 6: //经度方向处理
if(GPSDATA_count<1)
{
GPS_longitude_dir=UART_data;
}
break;
case 7: //速度处理
if(GPSDATA_count<5)
{
GPS_speed[GPSDATA_count]=UART_data;
}
break;
case 8: //方位角处理
if(GPSDATA_count<5)
{
GPS_Angle[GPSDATA_count]=UART_data;
}
break;
case 9: //日期
if(GPSDATA_count<6)
{
GPS_date[GPSDATA_count]=UART_data;
}
break;
}
break;
}
}
GPSDATA_count++; //接收数位加1
break;
}
}
#define LCD1602_DB0_DB7 P0 //1602液晶数据端口
sbit LCD1602_RS = P1^0; //1602液晶指令/数据选择引脚
sbit LCD1602_RW = P1^1; //1602液晶读写引脚
sbit LCD1602_E = P1^5; //1602液晶使能引脚
/*****************************************************************************
定义LCD1602指令集 (详细请见查看1602指令集手册)
/****************************************************************************/
#define CMD_clear 0x01 // 清除屏幕
#define CMD_back 0x02 // DDRAM回零位
#define CMD_ac 0x06 // 读入后AC(指针)加1,向右写
#define CMD_display 0x0c // 开显示_关光标_关光标闪烁
#define CMD_set 0x38 // 8位总线_2行显示
#define line_one 0x80 // 第一行写入地址
#define line_two 0xc0 // 第二行写入地址
/*****************************************************************************
LCD1602测忙,若LCD1602处于忙状态,本函数将等待至非忙状态
/****************************************************************************/
void LCD1602_TestBusy(void)
{
LCD1602_DB0_DB7 = 0xff; //设备读状态
LCD1602_RS = 0;
LCD1602_RW = 1;
LCD1602_E = 1;
while(LCD1602_DB0_DB7&0x80); //等待LCD空闲
LCD1602_E = 0;
}
/*****************************************************************************
写指令程序
/****************************************************************************/
void LCD1602_WriteCMD(unsigned char LCD1602_command)
{
LCD1602_TestBusy();
LCD1602_DB0_DB7 = LCD1602_command;
LCD1602_RS = 0;
LCD1602_RW = 0;
LCD1602_E = 1;
LCD1602_E = 0;
}
/*****************************************************************************
向LCD1602写数据
/****************************************************************************/
void LCD1602_WriteData(unsigned char LCD1602_data)
{
LCD1602_TestBusy();
LCD1602_DB0_DB7 = LCD1602_data;
LCD1602_RS = 1;
LCD1602_RW = 0;
LCD1602_E = 1;
LCD1602_E = 0;
}
/*****************************************************************************
打印字符串程序(本函数调用指针函数)
向LCD发送一个字符串,长度48字符之内
在第一行第一位处从左向右打印字符串
/****************************************************************************/
void Print_String(unsigned char line,unsigned char *str)
{
LCD1602_WriteCMD(line);
while(*str != '\0')
{
LCD1602_WriteData(*str++);
}
*str = 0;
}
/********************************************************************************************
打印字符程序
向LCD发送一个字符,
line为行数(使用line_one,line_two定义使用),num为位置,data为打印字符
/********************************************************************************************/
void Print_Char (unsigned char line,unsigned char num,unsigned char date)
{
LCD1602_WriteCMD(line+num);
LCD1602_WriteData(date);
}
/*****************************************************************************
LCD1602初始化
/****************************************************************************/
void LCD1602_Init(void)
{
LCD1602_WriteCMD(CMD_set); // 显示模式设置:显示2行,每个字符为5*7个像素
LCD1602_WriteCMD(CMD_clear); // 显示清屏
LCD1602_WriteCMD(CMD_back); // 数据指针指向第1行第1个字符位置
LCD1602_WriteCMD(CMD_ac); // 显示光标移动设置:文字不动,光标右移
LCD1602_WriteCMD(CMD_display); // 显示开及光标设置:显示开,光标开,闪烁开
}
void Uart_Init(void)
{
EA=1;
ES=1;
SCON = 0x50;
TMOD = 0x20;
PCON=0x00;
TH1 = 0xFD;
TL1 = 0xfd;
TR1 = 1;
RI = 0;
}
接收数据是否完整
1有效
0无效
*****************************/
unsigned char Data_legitimate=0;
/****************************
GPS是否定位
1有效
0无效
*****************************/
unsigned char GPS_lock;
/****************************
GPS使用卫星个数
*****************************/
unsigned char GPSUSE_satellite[2];
/****************************
GPS可见卫星个数
*****************************/
unsigned char GPSVISIBLE_satellite[2];
/****************************
GPS数据类型
1GPGGA
2GPGSV
3GPRMC
*****************************/
unsigned char GPSDATA_number;
/****************************
GPS数据模式
0结束模式
1类型模式
2数据模式
*****************************/
unsigned char GPSDATA_mode;
/****************************
逗号计数器
*****************************/
unsigned char GPSDOT_count;
/****************************
位数计数器
*****************************/
unsigned char GPSDATA_count;
/****************************
类型模式存储数组
*****************************/
unsigned char GPSDATA_cmd[5];
/****************************
纬度
*****************************/
unsigned char GPS_latitude[9];
/****************************
纬度方向
*****************************/
unsigned char GPS_latitude_dir;
/****************************
经度
*****************************/
unsigned char GPS_longitude[10];
/****************************
经度方向
*****************************/
unsigned char GPS_longitude_dir;
/****************************
GPS速度
*****************************/
unsigned char GPS_speed[5]={'0','0','0','.','0'};
/****************************
海拔高度
*****************************/
unsigned char GPS_altitude[6];
/****************************
日期
*****************************/
unsigned char GPS_date[6];
/****************************
时间
*****************************/
unsigned char GPS_time[6];
/****************************
方位角
*****************************/
unsigned char GPS_Angle[5]={'0','0','0','0','0'};
/****************************
方位角
*****************************/
unsigned char OUT_speed[5];
void Delay_Ms (unsigned int a)
{
unsigned int i;
while( a-- != 0)
{
for(i = 0; i < 600; i++);
}
}
|