51单片机解析GPS最新程序文件.docx
《51单片机解析GPS最新程序文件.docx》由会员分享,可在线阅读,更多相关《51单片机解析GPS最新程序文件.docx(26页珍藏版)》请在冰豆网上搜索。
51单片机解析GPS最新程序文件
这其中包括1602驱动头文件,和解析主程序,使用时分开粘贴到对应的文件中
/*
LCD1602驱动,兼容LCD2402
*/
sbitLCD_DB0=P0^0;
sbitLCD_DB1=P0^1;
sbitLCD_DB2=P0^2;
sbitLCD_DB3=P0^3;
sbitLCD_DB4=P0^4;
sbitLCD_DB5=P0^5;
sbitLCD_DB6=P0^6;
sbitLCD_DB7=P0^7;
sbitLCD1602_RS=P2^4;
sbitLCD1602_RW=P2^5;
sbitLCD1602_EN=P2^6;
voidLCD_write_char(unsignedx,unsignedchary,unsignedchardat);//在指定位置显示字符
voidLCD_write_string(unsignedcharX,unsignedcharY,unsignedchar*s);//在指定位置显示字符串
voidLCD_cls(void);//清屏
voidLCD_en_command(unsignedcharcommand);
voidLCD_en_dat(unsignedchartemp);
voidLCD_set_xy(unsignedcharx,unsignedchary);
voidLCD_init(unsignedcharbw);
voidSET_LCD(unsignedcharIO_temp);
voiddelayms(unsignedcharms);
voidlcddelay(void);
unsignedcharLCDIO;
unsignedcharBitWidth;
voidLCD_cls(void)
{
LCD_en_command(0x01);//0x01清屏
delayms
(2);
}
voidLCD_en_command(unsignedcharcommand)
{
LCD1602_RS=0;
LCD1602_RW=0;
LCD1602_EN=0;
switch(BitWidth){
case4:
LCDIO=(command&0xf0);//取高4位
break;
case8:
LCDIO=command;
break;
}
SET_LCD(LCDIO);
LCD1602_EN=1;
lcddelay();
LCD1602_EN=0;
if(BitWidth==4){
LCDIO=(command&0x0f)<<4;//取低4位
SET_LCD(LCDIO);
LCD1602_EN=1;
lcddelay();
LCD1602_EN=0;
}
}
voidSET_LCD(unsignedcharIO_temp)
{
//高4位
LCD_DB7=IO_temp&0x80;
LCD_DB6=IO_temp&0x40;
LCD_DB5=IO_temp&0x20;
LCD_DB4=IO_temp&0x10;
//低4位
if(BitWidth==8){
LCD_DB3=IO_temp&0x08;
LCD_DB2=IO_temp&0x04;
LCD_DB1=IO_temp&0x02;
LCD_DB0=IO_temp&0x01;
}
}
voidLCD_en_dat(unsignedchardat)
{
LCD1602_RS=1;
LCD1602_RW=0;
LCD1602_EN=0;
switch(BitWidth){
case4:
LCDIO=(dat&0xf0);//取高4位
break;
case8:
LCDIO=dat;
break;
}
SET_LCD(LCDIO);
LCD1602_EN=1;
lcddelay();
LCD1602_EN=0;
if(BitWidth==4){
LCDIO=(dat&0x0f)<<4;//取低4位
SET_LCD(LCDIO);
LCD1602_EN=1;
lcddelay();
LCD1602_EN=0;
}
}
/*=======================================================
*1602
*输入参数:
x、y:
显示字符串的坐标,X:
0-15,Y:
0-1
*LCD第一行显示寄存器地址:
0X80-0X8F
*LCD第二行显示寄存器地址:
0XC0-0XCF
*2404
*LCD第1行显示地址:
1~20(0x80~0x93)
*LCD第2行显示地址:
1~20(0xc0~0xd3)
*LCD第3行显示地址:
1~20(0x94~0xa7)
*LCD第4行显示地址:
1~20(0xd4~0xe7)
=======================================================*/
voidLCD_set_xy(unsignedcharx,unsignedchary)
{
unsignedcharaddress;
if(y==0)
address=0x80+x;
else
if(y==1)
address=0xC0+x;
else
if(y==2)
address=0x94+x;
else
if(y==3)
address=0xD4+x;
LCD_en_command(address);
}
voidLCD_write_char(unsignedx,unsignedchary,unsignedchardat)
{
LCD_set_xy(x,y);
LCD_en_dat(dat);
}
voidLCD_write_string(unsignedcharX,unsignedcharY,unsignedchar*s)
{
LCD_set_xy(X,Y);//setaddress
while(*s)//writecharacter
{
LCDIO=*s;
SET_LCD(LCDIO);
LCD_en_dat(*s);
s++;
}
}
voidLCD_init(unsignedcharbw)
{
BitWidth=bw;
switch(BitWidth){
case4:
LCD_en_command(0x33);//
delayms(20);
LCD_en_command(0x32);//
delayms(20);
break;
case8:
LCD_en_command(0x38);//
delayms(20);
LCD_en_command(0x38);//
delayms(20);
break;
}
LCD_en_command(0x08);//0x08令显示器off
delayms(5);
LCD_en_command(0x01);//0x01清屏清屏指令
delayms(5);
LCD_en_command(0x06);//0x06光标模式设置进入模式设置指令写入数据后光标右移
delayms(5);
LCD_en_command(0x0c);//0x0c显示开令光标,0x0c=不显示,0x0d=显示闪动
delayms(5);
}
voiddelayms(unsignedcharms)
{
unsignedchari;
while(ms--)
{
for(i=0;i<115;i++);
}
}
voidlcddelay(void)
{
unsignedchari;
for(i=0;i<2;i++);
}
/*************************************
GPS解码显示程序,
***************************************/
#include
#include"1602.h"
//#include"math.h"
//#include
sbitGPS_SPD=P3^2;//GPS模块速率设置
sbitKEY1=P3^3;//显示容分屏切换,(T0,T1引脚的第二功能为计数器。
)
charcodeTIME_AREA=8;//时区
/***************************************
这是做的部分更改
************************************/
unsignedlongmaxspeed,b;
unsignedintcount=0;
unsignedinta[5];
unsignedcharhspeed[5];
unsignedintdot_count;//小数点计数器
//unsignedcharx;
//GPS数据存储数组
unsignedcharJD[10];//经度
unsignedcharJD_a;//经度方向
unsignedcharWD[9];//纬度
unsignedcharWD_a;//纬度方向
unsignedchardate[6];//日期
unsignedchartime[6];//时间
unsignedcharspeed[5]={'0','0','0','.','0'};//速度
unsignedcharhigh[6];//高度
unsignedcharangle[5]={'0','0','0','0','0'};//方位角
unsignedcharuse_sat[2];//使用的卫星数
unsignedchartotal_sat[2];//天空中总卫星数
unsignedcharlock;//定位状态
//串口中断需要的变量
unsignedcharseg_count;//逗号计数器
unsignedcharbyte_count;//位数计数器
unsignedcharcmd_number;//命令类型
unsignedcharmode;//0:
结束模式,1:
命令模式,2:
数据模式
unsignedcharbuf_full;//1:
整句接收完成,相应数据有效。
0:
缓存数据无效。
unsignedcharcmd[5];//命令类型存储数组
//显示需要的变量
unsignedintdsp_count;//刷新次数计数器
//unsignedchartime_count;
bitpage;
voidsys_init(void);
bitchk_key(void);
main()
{
unsignedchari;
charBhour;
sys_init();
lock=1;
use_sat[0]='0';
use_sat[1]='0';
total_sat[0]='0';
total_sat[1]='0';
while
(1){
if(buf_full==0)//无GPS信号时
{
dsp_count++;
if(dsp_count>=65000){
LCD_cls();//清屏
LCD_write_string(0,0,"NoGPSconnect..");
LCD_write_string(0,1,"PleaseCheck..");
while(buf_full==0);
LCD_cls();
dsp_count=0;
}
}
else{//有GPS信号时
if(chk_key()){//检测到按键切换显示
page=!
page;
LCD_cls();
}
if(!
page){//页面1
if(buf_full|0x01){//GGA语句
if(lock==0){//如果未定位
LCD_write_string(0,0,"*---.--.----");
LCD_write_string(0,1,"*--.--.----");
}else{//如果已定位
LCD_write_char(0,0,JD_a);//显示经度
for(i=0;i<3;i++)
{
LCD_write_char(i+1,0,JD[i]);
}
LCD_write_char(4,0,'.');
for(i=3;i<10;i++)
{
LCD_write_char(i+2,0,JD[i]);
}
LCD_write_char(0,1,WD_a);//显示纬度
LCD_write_char(1,1,'');
for(i=0;i<2;i++)
{
LCD_write_char(i+2,1,WD[i]);
}
LCD_write_char(4,1,'.');
for(i=2;i<9;i++)
{
LCD_write_char(i+3,1,WD[i]);
}
}
LCD_write_char(14,1,use_sat[0]);//显示接收卫星数
LCD_write_char(15,1,use_sat[1]);
buf_full&=~0x01;
dsp_count=0;
}
if(buf_full|0x02){//GSV语句
LCD_write_char(14,1,total_sat[0]);
LCD_write_char(15,1,total_sat[1]);
buf_full&=~0x02;
dsp_count=0;
}
if(buf_full|0x04){
if(lock==0){//如果未定位
LCD_write_string(0,0,"*---.--.----");
LCD_write_string(0,1,"*--.--.----");
}else{//如果已定位
LCD_write_char(0,0,JD_a);//显示经度
for(i=0;i<3;i++)
{
LCD_write_char(i+1,0,JD[i]);
}
LCD_write_char(4,0,'.');
for(i=3;i<10;i++)
{
LCD_write_char(i+2,0,JD[i]);
}
LCD_write_char(0,1,WD_a);//显示纬度
LCD_write_char(1,1,'');
for(i=0;i<2;i++)
{
LCD_write_char(i+2,1,WD[i]);
}
LCD_write_char(4,1,'.');
for(i=2;i<9;i++)
{
LCD_write_char(i+3,1,WD[i]);
}
}
LCD_write_char(14,0,use_sat[0]);//显示接收卫星数
LCD_write_char(15,0,use_sat[1]);
buf_full&=~0x04;
dsp_count=0;
}
}
else{//页面2
if(buf_full|0x01){//GGA语句
buf_full&=~0x01;
dsp_count=0;
}
if(buf_full|0x02){
buf_full&=~0x02;
dsp_count=0;
}
if(buf_full|0x04){//RMC语句
Bhour=((time[0]-0x30)*10+time[1]-0x30)+TIME_AREA;
if(Bhour>=24){
Bhour-=24;
}elseif(Bhour<0){
Bhour+=24;
}
LCD_write_char(0,1,date[4]);
LCD_write_char(1,1,date[5]);
LCD_write_char(2,1,date[2]);
LCD_write_char(3,1,date[3]);
LCD_write_char(4,1,date[0]);
LCD_write_char(5,1,date[1]);
LCD_write_char(8,1,Bhour/10+0x30);
LCD_write_char(9,1,Bhour%10+0x30);
LCD_write_char(10,1,':
');
LCD_write_char(11,1,time[2]);
LCD_write_char(12,1,time[3]);
LCD_write_char(13,1,':
');
LCD_write_char(14,1,time[4]);
LCD_write_char(15,1,time[5]);
LCD_write_string(5,0,"knotA");//在此处做的更改
if(lock=='0'){//如果未定位
LCD_write_string(0,0,"---.-");
LCD_write_string(11,0,"---.-");
}else{//已经定位,在此处做的改动。
/*******************************************************************************/
/*************************************
最大速度处理
*************************************/
dot_count=0;
b=0;
for(i=0;i<5;i++)
{
if(speed[i]!
='.')
dot_count++;
else
break;
}
switch(dot_count)
{
case1:
b=((speed[0]-'0')*10+(speed[2]-'0'))*1.852;
break;
case2:
b=((speed[0]-'0')*100+(speed[1]-'0')*10+(speed[4]-'0'))*1.852;
break;
case3:
b=((speed[0]-'0')*1000+(speed[1]-'0')*100+(speed[2]-'0')*10+(speed[4]-'0'))*1.852;
break;
}
if(b>maxspeed)
{
maxspeed=b;
}
/*************************************
最大速度处理
*************************************/
if(count<10)
{
for(i=0;i<5;i++)
{
LCD_write_char(i,0,speed[i]);//knot显示
}
count++;
}
else
{
if(count>15)
{
count=0;
}
hspeed[0]=maxspeed/1000+0x30;//把小数转成字符数组
hspeed[1]=(maxspeed/100)%10+0x30;
hspeed[2]=(maxspeed/10)%10+0x30;
hspeed[3]='.';
hspeed[4]=maxspeed%10+0x30;
count++;
LCD_write_string(5,0,"Km/hA");
LCD_write_char(0,0,hspeed[0]);
LCD_write_char(1,0,hspeed[1]);
LCD_write_char(2,0,hspeed[2]);
LCD_write_char(3,0,hspeed[3]);
LCD_write_char(4,0,hspeed[4]);//最大速度显*/
}
/*****************************************************************