#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++);
}
}
|