51 MCU decoding GPS 1602 display

Publisher:诗意世界Latest update time:2017-01-06 Source: eefocus Reading articles on mobile phones Scan QR code
Read articles on your mobile phone anytime, anywhere

Use 51 MCU to analyze the information sent by the serial port GPS module, display it on 1602 LCD, and connect the TXD port of 51 MCU to the RXD port of GPS module. The program is slightly modified and some errors are corrected.

This is the circuit schematic. The program was modified based on my microcontroller board. 

First, solder a 51 single-chip minimum system. In my program, I use the P0 port to communicate with the 1602 LCD.

 

This is an improvement. The original serial port GPS module has been replaced with a Bluetooth GPS module. The rightmost one is Nokia's Bluetooth GPS module. The Bluetooth serial port main module on the small square board is used to receive the signal from the Bluetooth GPS. The program is still the original one. 

 

The program is combined with online information, and I have modified it myself and posted the code here.

//This is the driver header file for the 1602 LCD, the file name is 1602.h

 

 /*

LCD1602 driver, compatible with 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); //Display characters at the specified position

void LCD_write_string(unsigned char X,unsigned char Y,unsigned char *s); //Display the string at the specified position

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 Clear

    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); //Get the upper 4 bits

  break;

   case 8:

  LCDIO=command;

     break;

 }

 SET_LCD(LCDIO);

 LCD1602_EN=1;

 lcddelay();

 LCD1602_EN=0;

 if (BitWidth==4){

  LCDIO=(command & 0x0f)<<4; //Get the lower 4 bits

  SET_LCD(LCDIO);

  LCD1602_EN=1;

  lcddelay();

  LCD1602_EN=0;

 }

}

void SET_LCD(unsigned char IO_temp)

{   

 //High 4 bits

 LCD_DB7=IO_temp&0x80;

 LCD_DB6=IO_temp&0x40;

 LCD_DB5=IO_temp&0x20;

 LCD_DB4=IO_temp&0x10;

 //lower 4 bits

 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); //Get the upper 4 bits

  break;

   case 8:

  LCDIO=that;

  break;

 }

 SET_LCD(LCDIO);

 LCD1602_EN=1;

 lcddelay();

 LCD1602_EN=0;

  

 if (BitWidth==4){

  LCDIO=(dat & 0x0f)<<4; //Get the lower 4 bits

  SET_LCD(LCDIO);

  LCD1602_EN=1;

  lcddelay();

  LCD1602_EN=0;

 }

}

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

*1602

* Input parameters: x, y: coordinates of the displayed string, X: 0-15, Y: 0-1

* LCD first line display register address: 0X80-0X8F

* LCD second line displays register address: 0XC0-0XCF  

*2404

*LCD line 1 display address: 1~20 (0x80~0x93) 

*LCD line 2 display address: 1~20 (0xc0~0xd3) 

*LCD line 3 display address: 1~20 (0x94~0xa7) 

*LCD line 4 display address: 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_and_that(that);

}

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_and_that(*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 turns the display off 

 delayms(5);

 LCD_en_command(0x01); //0x01 clear screen clear screen command

 delayms(5);

 LCD_en_command(0x06); //0x06 Cursor mode setting Enter the mode setting command and write data to move the cursor right

 delayms(5);

 LCD_en_command(0x0c); //0x0c displays the cursor, 0x0c=not displayed, 0x0d=displayed flashing

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

}


 

//This is the main decoding program 


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

 GPS decoding display program,

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

#include

#include "1602.h"

//#include"math.h"

//#include

sbit GPS_SPD=P2^1; //Receive baud rate setting

sbit KEY1=P2^0; //Display content split screen switching, (the second function of T0, T1 pin is counter.)

char code TIME_AREA = 8; //time zone

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

       Here are some of the changes made

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

unsigned long maxspeed,b;

unsigned int count=0;

unsigned int a[5];

unsigned char hspeed[5];

unsigned int dot_count; //decimal point counter

//unsigned char x;

//GPS data storage array

unsigned char JD[10]; //longitude

unsigned char JD_a; //longitude direction

unsigned char WD[9]; //latitude

unsigned char WD_a; //latitude direction

unsigned char date[6]; //date

unsigned char time[6]; //time

unsigned char speed[5]={'0','0','0','.','0'}; //Speed

unsigned char high[6]; // Altitude

unsigned char angle[5]={'0','0','0','0','0'}; //azimuth

unsigned char use_sat[2]; //Number of satellites used

unsigned char total_sat[2]; //Total number of satellites in the sky

unsigned char lock; //positioning status

//Variables required for serial port interrupt

unsigned char seg_count; //comma counter

unsigned char byte_count; //digit counter

unsigned char cmd_number; //command type

unsigned char mode; //0: end mode, 1: command mode, 2: data mode

unsigned char buf_full; //1: The whole sentence is received and the corresponding data is valid. 0: The cached data is invalid.

unsigned char cmd[5]; //command type storage array

// Display the required variables

unsigned int dsp_count; //Refresh count counter

//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) //No GPS signal

  {

   dsp_count++;

   if(dsp_count>=65000){

    LCD_cls(); //Clear screen

    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{ //When there is GPS signal

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

 Maximum speed processing

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

                     dot_count=0;

       b=0;

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

       {

           if(speed!='.')

           dot_count++;

        else

           break ;

       }

       switch(dot_count)

       {

          

       case 1:

            b=((speed[0]-'0')*10+(speed[2]-'0'))*1.852;

         break;

       case 2:

            b=((speed[0]-'0')*100+(speed[1]-'0')*10+(speed[4]-'0'))*1.852;

         break;

       case 3:

            b=((speed[0]-'0')*1000+(speed[1]-'0')*100+(speed[2]-'0')*10+(speed[4]-'0'))*1.852;

         break;

      

        }

                      if(b>maxspeed)

       {

         maxspeed=b;

          }


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

 Maximum speed processing

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

 

            

   if(chk_key()){ //Key switch display detected

    page=!page;

    LCD_cls();

   }

   if(!page){ //Page 1


                      

    if(buf_full|0x01){ //GGA statement

     if(lock==0){ //If not positioned

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

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

     }else{ //If located

 

         LCD_write_char(0,0,JD_a); //Display longitude

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

      {

        LCD_write_char(i+1,0,JD);

        }

                        LCD_write_char(4,0,'.');

                        for(i=3;i<10;i++)

      {

        LCD_write_char(i+2,0,JD);

        }

      LCD_write_char(0,1,WD_a); //Display latitude

      LCD_write_char(1,1,' ');

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

      {

       LCD_write_char(i+2,1,WD);

      }

      LCD_write_char(4,1,'.');

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

      {

       LCD_write_char(i+3,1,WD);

      }

            

      }

     LCD_write_char(14,1,use_sat[0]); //Display the number of received satellites

     LCD_write_char(15,1,use_sat[1]);

     buf_full&=~0x01;

     dsp_count=0;

   }

    if(buf_full|0x02){ //GSV statement

     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){ //If not positioned

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

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

     }else{ //If located

 

           LCD_write_char(0,0,JD_a); //Display longitude

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

     {

       LCD_write_char(i+1,0,JD);

       }

                    LCD_write_char(4,0,'.');

                    for(i=3;i<10;i++)

     {

       LCD_write_char(i+2,0,JD);

       }

     LCD_write_char(0,1,WD_a); //Display latitude

    

     LCD_write_char(1,1,' ');

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

     {

      LCD_write_char(i+2,1,WD);

     }

     LCD_write_char(4,1,'.');

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

     {

      LCD_write_char(i+3,1,WD);

     }

         }

     LCD_write_char(14,0,use_sat[0]); //Display the number of received satellites

     LCD_write_char(15,0,use_sat[1]);

     buf_full&=~0x04;

     dsp_count=0;

    }

   }

   else{ //Page 2

    if(buf_full|0x01){ //GGA statement

     buf_full&=~0x01;

     dsp_count=0;

    }

    if(buf_full|0x02){

     buf_full&=~0x02;

     dsp_count=0;

    }

    if(buf_full|0x04){ //RMC statement

     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'){ //If not positioned

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

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

     }else{ // Already located, changes made here.

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


        

       

                           if(count<10)

         { 

                            

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

       {   

       LCD_write_char(i,0,speed);//knot显示

       }

       count++;

        }

        else

        {

          if(count>15)

          {  

          count=0;

       }

                           hspeed[0]=maxspeed/1000+0x30; //Convert the decimal into a character array

         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/h A"); 

                            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]); //Maximum speed display */

      }

                         

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

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

        LCD_write_char(11+i,0,angle);

      }

     }

     buf_full&=~0x04;

     dsp_count=0;

    }

   }

  }

 }

}

bit chk_key(void)

{

 if(!KEY1){

  delayms(10);

  if(!KEY1){

   while(!KEY1);

   delayms(10);

   return(1);

  }

 }

    LCD_cls(); //Clear screen

 return(0);

}

//system initialization

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 9600 baud @ 11.059MHz */

 }else{

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

 }

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

 LCD_init(8); //Initialize 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; //Open general interrupt and serial port interrupt

}

//Serial port receive interrupt

void uart(void) interrupt 4

{

 unsigned char tmp;

 if(RI){

  tmp=SBUF;

  switch(tmp){

   case '$':

    cmd_number=0; // command type clear

    mode=1; //receive command mode

    byte_count=0; //The number of received digits is cleared

    break;

   case ',':

    seg_count++; //Comma count plus 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){

     // Command type determination

     cmd[byte_count]=tmp; //Receive characters and put them into type buffer

     if(byte_count>=4){ //If the type data is received, determine the type

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

     //Receive data processing

     switch (cmd_number){

      case 1: //Type 1 data reception. GPGGA

       switch(seg_count){

        case 2: // latitude processing

         if(byte_count<9){

          WD[byte_count]=tmp;

         }

         break;

        case 3: // latitude direction processing

         if(byte_count<1){

          WD_a=tmp;

         }

         break;

        case 4: //Longitude processing

         if(byte_count<10){

          JD[byte_count]=tmp;

         }

         break;

        case 5: //Longitude direction processing

         if(byte_count<1){

          JD_a=tmp;

         }

         break;

        case 6: //Location judgment

         if(byte_count<1){

          lock=tmp;

         }

         break;

        case 7: //Number of satellites used for positioning

         if(byte_count<2){

          use_sat[byte_count]=tmp;

         }

         break;

        case 9: //Height processing

         if(byte_count<6){

          high[byte_count]=tmp;

         }

         break;

       }

       break;

      case 2: //Type 2 data reception. GPGSV

       switch(seg_count){

        case 3: //Total number of satellites in the sky

         if(byte_count<2){

          total_sat[byte_count]=tmp;

         }

         break;

       }

       break;

      case 3: //Type 3 data reception. GPRMC

       switch(seg_count){

        case 1: //time processing

         if(byte_count<6){    

          time[byte_count]=tmp; 

         }

         break;

        case 2: //Positioning judgment      

         if(byte_count<1){

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

           else{

             lock=0;}

         }

         break;

        case 3: // latitude processing      

         if(byte_count<9){

          WD[byte_count]=tmp;

         }

         break;

        case 4: // latitude direction processing      

         if(byte_count<1){

          WD_a=tmp;

         }

         break;

        case 5: //Longitude processing      

         if(byte_count<10){

          JD[byte_count]=tmp;

         }

         break;

        case 6: //Longitude direction processing      

         if(byte_count<1){

          JD_a=tmp;

         }

         break;

        case 7: //speed processing      

         if(byte_count<5){

          speed[byte_count]=tmp;

         }

                               

         break;

        case 8: //Azimuth processing      

         if(byte_count<5){

          angle[byte_count]=tmp;

         }

         break;

        case 9: //Azimuth processing      

         if(byte_count<6){

          date[byte_count]=tmp;

         }

         break;

       }

       break;

     }

    }

    byte_count++; //Received digit plus 1

    break;

  }

 }

 RI=0;

}


Reference address:51 MCU decoding GPS 1602 display

Previous article:Computer control console lamp (c# hook, display room temperature, network correction time)
Next article:51 single chip microcomputer controls the servo

Latest Microcontroller Articles
  • Download from the Internet--ARM Getting Started Notes
    A brief introduction: From today on, the ARM notebook of the rookie is open, and it can be regarded as a place to store these notes. Why publish it? Maybe you are interested in it. In fact, the reason for these notes is ...
  • Learn ARM development(22)
    Turning off and on interrupts Interrupts are an efficient dialogue mechanism, but sometimes you don't want to interrupt the program while it is running. For example, when you are printing something, the program suddenly interrupts and another ...
  • Learn ARM development(21)
    First, declare the task pointer, because it will be used later. Task pointer volatile TASK_TCB* volatile g_pCurrentTask = NULL;volatile TASK_TCB* vol ...
  • Learn ARM development(20)
    With the previous Tick interrupt, the basic task switching conditions are ready. However, this "easterly" is also difficult to understand. Only through continuous practice can we understand it. ...
  • Learn ARM development(19)
    After many days of hard work, I finally got the interrupt working. But in order to allow RTOS to use timer interrupts, what kind of interrupts can be implemented in S3C44B0? There are two methods in S3C44B0. ...
  • Learn ARM development(14)
  • Learn ARM development(15)
  • Learn ARM development(16)
  • Learn ARM development(17)
Change More Related Popular Components

EEWorld
subscription
account

EEWorld
service
account

Automotive
development
circle

About Us Customer Service Contact Information Datasheet Sitemap LatestNews


Room 1530, 15th Floor, Building B, No.18 Zhongguancun Street, Haidian District, Beijing, Postal Code: 100190 China Telephone: 008610 8235 0740

Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号