最新51单片机GPS解码程序

时间:2022-06-01 19:04:10

这是头文件需要把这部分代码拷贝到 **.h的文件中

/*

LCD1602驱动,兼容LCD2402

*/

sbit LCD_DB0= P0^0;

sbit LCD_DB1= P0^1;

sbit LCD_DB2= P0^2;

sbit LCD_DB3= P0^3;

sbit LCD_DB4= P0^4;

sbit LCD_DB5= P0^5;

sbit LCD_DB6= P0^6;

sbit LCD_DB7= P0^7;

sbit LCD1602_RS=P1^0;

sbit LCD1602_RW=P1^1; 

sbit LCD1602_EN=P1^2;

void LCD_write_char( unsigned x,unsigned char y,unsigned char dat);//在指定位置显示字符

void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s);//在指定位置显示字符串

void LCD_cls(void);//清屏

void LCD_en_command(unsigned char command);

void LCD_en_dat(unsigned char temp);

void LCD_set_xy( unsigned char x, unsigned char y );

void LCD_init(unsigned char bw);

void SET_LCD(unsigned char IO_temp);

void delayms(unsigned char ms);

void lcddelay(void);

unsigned char LCDIO; 

unsigned char BitWidth;

void LCD_cls(void)

{

LCD_en_command(0x01);//0x01 清屏

    delayms(2);

}

void LCD_en_command(unsigned char command)

{

LCD1602_RS=0;   

LCD1602_RW=0;

LCD1602_EN=0;

switch(BitWidth){

  case 4:

LCDIO=(command & 0xf0);  //取高4

break;

  case 8:

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;

}

}

void SET_LCD(unsigned char IO_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;

}

}

void LCD_en_dat(unsigned char dat)

{

LCD1602_RS=1;

LCD1602_RW=0;

LCD1602_EN=0;

switch(BitWidth){

  case 4:

LCDIO=(dat & 0xf0); //取高4

break;

  case 8:

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

输入参数:xy : 显示字符串的坐标,X:0-15Y:0-1

*LCD第一行显示寄存器地址:0X80-0X8F

*LCD第二行显示寄存器地址:0XC0-0XCF  

*2404

*LCD1行显示地址:1~20(0x80~0x93) 

*LCD2行显示地址:1~20(0xc0~0xd3) 

*LCD3行显示地址:1~20(0x94~0xa7) 

*LCD4行显示地址:1~20(0xd4~0xe7) 

=======================================================*/ 

void LCD_set_xy( unsigned char x, unsigned char y )

{

unsigned char address;

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); 

}

void LCD_write_char( unsigned x,unsigned char y,unsigned char dat)

{

LCD_set_xy( x, y ); 

LCD_en_dat(dat);

}

void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s)

{

    LCD_set_xy( X, Y );    //set address 

    while (*s)       // write character

    {

LCDIO=*s;

SET_LCD(LCDIO);

LCD_en_dat(*s);   

s ++;

    }

}

void LCD_init(unsigned char bw)

{

BitWidth=bw;

switch(BitWidth){

  case 4:

LCD_en_command(0x33);//

delayms(20);

LCD_en_command(0x32);//

delayms(20);

break;

      case 8:

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);

}

void delayms(unsigned char ms)

{

unsigned char i;

while(ms--)

{

for(i = 0; i < 115; i++);

}

}

void lcddelay(void)

{

unsigned char i;

for(i = 0; i < 2; i++);

}

这是主程序拷贝到**.c 的文件中

/*************************************

GPS解码显示程序

***************************************/

#include<reg52.h>

#include "1602.h"

sbit GPS_SPD=P2^1;//GPS模块速率设置

sbit KEY1=P2^0;//显示内容分屏切换

char code TIME_AREA= 8;//时区

//GPS数据存储数组

unsigned char JD[10];//经度

unsigned char JD_a;//经度方向

unsigned char WD[9];//纬度

unsigned char WD_a;//纬度方向

unsigned char date[6];//日期

unsigned char time[6];//时间

unsigned char speed[5]={'0','0','0','0','0'};//速度

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;

void sys_init(void);

bit chk_key(void);

main()

{

unsigned char i;

char Bhour;

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,"No GPS connect..");

LCD_write_string(0,1,"Please Check..");

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<10;i++){

  LCD_write_char(i+1,0,JD[i]);

}

LCD_write_char(0,1,WD_a);//显示纬度

LCD_write_char(1,1,' ');

for(i=0;i<9;i++){

LCD_write_char(i+2,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<10;i++){

  LCD_write_char(i+1,0,JD[i]);

}

LCD_write_char(0,1,WD_a);//显示纬度

LCD_write_char(1,1,' ');

for(i=0;i<9;i++){

LCD_write_char(i+2,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;

}else if(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,"knot A");

if(lock=='0'){//如果未定位

LCD_write_string(0,0,"---.-");

LCD_write_string(11,0,"---.-");

}else{//已经定位

for(i=0;i<5;i++){//knot显示

LCD_write_char(i,0,speed[i]);

}

 for(i=0;i<5;i++){

LCD_write_char(11+i,0,angle[i]);

}

}

buf_full&=~0x04;

dsp_count=0;

}

}

}

}

}

bit chk_key(void)

{

if(!KEY1){

delayms(10);

if(!KEY1){

while(!KEY1);

delayms(10);

return(1);

}

}

return(0);

}

//系统初始化

void sys_init() {

unsigned char i;

SCON = 0x50; /* SCON: mode 1, 8-bit UART, enable rcvr */

TMOD = 0x21; /* TMOD: timer 1, mode 2, 8-bit reload */

if(GPS_SPD){

TH1 = 0xfa; /* TH1: reload value for 4800 baud @ 11.059MHz */

}else{

TH1 = 0xfd;/* TH1: reload value for 9600 baud @ 11.059MHz */

}

TR1 = 1; /* TR1: timer 1 run */

LCD_init(8);//初始化LCD

LCD_write_string(0,0," GPS SIRF II 2 ");

LCD_write_string(0,1," 11-11-23 1342 ");

for(i=1;i<4;i++){

delayms(250);

}

//LCD_cls();

IE=0x90;//开总中断、串口中断

}

//串口接收中断

void uart(void) interrupt 4

{

unsigned char tmp;

if(RI){

tmp=SBUF;

      //  SBUF=tmp;

      //  if(TI)TI=0;

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]=='G'){

if(cmd[3]=='G'){

if(cmd[4]=='A'){

cmd_number=1;

mode=2;

seg_count=0;

byte_count=0;

}

}

else if(cmd[3]=='S'){

if(cmd[4]=='V'){

cmd_number=2;

mode=2;

seg_count=0;

byte_count=0;

}

}

}

else 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 1://类型1数据接收。GPGGA

switch(seg_count){

case 2://纬度处理

if(byte_count<9){

WD[byte_count]=tmp;

}

break;

case 3://纬度方向处理

if(byte_count<1){

WD_a=tmp;

}

break;

case 4://经度处理

if(byte_count<10){

JD[byte_count]=tmp;

}

break;

case 5://经度方向处理

if(byte_count<1){

JD_a=tmp;

}

break;

case 6://定位判断

if(byte_count<1){

lock=tmp;

}

break;

case 7://定位使用的卫星数

if(byte_count<2){

use_sat[byte_count]=tmp;

}

break;

case 9://高度处理

if(byte_count<6){

high[byte_count]=tmp;

}

break;

}

break;

case 2://类型2数据接收。GPGSV

switch(seg_count){

case 3://天空中的卫星总数

if(byte_count<2){

total_sat[byte_count]=tmp;

}

break;

}

break;

case 3://类型3数据接收。GPRMC

switch(seg_count){

case 1://时间处理

if(byte_count<6){

time[byte_count]=tmp;

}

break;

case 2://定位判断

if(byte_count<1){

  if (tmp=='A') {lock=1;}

  else{

    lock=0;}

}

break;

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;

}