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;
}
Previous article:Computer control console lamp (c# hook, display room temperature, network correction time)
Next article:51 single chip microcomputer controls the servo
- Popular Resources
- Popular amplifiers
Professor at Beihang University, dedicated to promoting microcontrollers and embedded systems for over 20 years.
- LED chemical incompatibility test to see which chemicals LEDs can be used with
- Application of ARM9 hardware coprocessor on WinCE embedded motherboard
- What are the key points for selecting rotor flowmeter?
- LM317 high power charger circuit
- A brief analysis of Embest's application and development of embedded medical devices
- Single-phase RC protection circuit
- stm32 PVD programmable voltage monitor
- Introduction and measurement of edge trigger and level trigger of 51 single chip microcomputer
- Improved design of Linux system software shell protection technology
- What to do if the ABB robot protection device stops
- Allegro MicroSystems Introduces Advanced Magnetic and Inductive Position Sensing Solutions at Electronica 2024
- Car key in the left hand, liveness detection radar in the right hand, UWB is imperative for cars!
- After a decade of rapid development, domestic CIS has entered the market
- Aegis Dagger Battery + Thor EM-i Super Hybrid, Geely New Energy has thrown out two "king bombs"
- A brief discussion on functional safety - fault, error, and failure
- In the smart car 2.0 cycle, these core industry chains are facing major opportunities!
- The United States and Japan are developing new batteries. CATL faces challenges? How should China's new energy battery industry respond?
- Murata launches high-precision 6-axis inertial sensor for automobiles
- Ford patents pre-charge alarm to help save costs and respond to emergencies
- New real-time microcontroller system from Texas Instruments enables smarter processing in automotive and industrial applications
- (C-Wireless Charging Electric Car) Liaoning Province First Prize_C
- Benefits of Spread Spectrum
- Don’t sell your old phone to buy a new one, learn how to make your own server!
- Can anyone recommend an inexpensive isolation amplifier product, either a chip or a module, with an accuracy of 1% and DC signal sampling?
- Problems with STM32F767 driving Bluetooth module
- Infineon Position2Go Development Kit Review @4. Development
- HFSS Wave Ports and Lumped Ports
- Using the MS-formula library of st 3.1, the scan results do not contain the device name
- What does it mean when the port latch is set to 1? How should I understand this sentence? It would be better if there is a picture to illustrate it.
- Simplifying Equalization Design for USB 3.0 Systems