1、设计需求及目标
系统由电源电路、晶振电路、复位电路、LCD驱动电路等组成,此系统用以读取GPS模块的数据并处理,最后在LCD液晶显示屏上显示经纬度和时间,用户可以实时通过读取显示的内容了解自己的位置以及当前时间,并可以实现时间自动校准,定位精度为15m。
2、设计思路及方案
系统硬件部分电路大致上可以分成稳压电源、单片机小系统及外围电路和LCD显示屏电路三部分。电路为单片机89C52控制的GPS器件,实现定位系统数据的采集和现实。其中所使用的器件主要是3个,单片机89C52、GPS模块GARMIN GPS25以及LCD显示模块MGLS-12032A。在这里仅列出单片机和LCD接口部分电路的器件名称和相关的主要功能。以单片机为核心将GPS数据发送模块,LCD1602显示模块系统的结合在一起形成一个整体,实现特定功能。电路图:
3、部分代码
// 工程名称: GPS模块测试程序
// 文件名称: main.c
// 功能描述: GPS模块接收定位信息,在LCD上显示
// 组成文件: main.c LCD.c GPS.c display.c
// 头文件: LCD.h GPS.h display.h
// 程序分析: GPS模块通过串口向单片机发送固定格式的数据
// 单片机的串口接收到数据后,进行解析,在LCD上显示
// 定位信息包括:日期时间,经纬度,速度,角度,高度
//======================================================================
#include <reg52.h>
#include <stdio.h>
#include <string.h>
#include "GPS.h"
#include "LCD.h"
#include "display.h"
sbit led1 = P2^3; //接收数据指示灯
sbit led2 = P2^4; //GPRMC数据有效指示灯
sbit led3 = P2^5; //GPGGA数据有效指示灯
#define REV_YES led1 = 0
#define REV_NO led1 = 1
#define RMC_YES led2 = 0
#define RMC_NO led2 = 1
#define GGA_YES led3 = 0
#define GGA_NO led3 = 1
char xdata rev_buf[80]; //接收缓存
uchar xdata rev_start = 0; //接收开始标志
uchar xdata rev_stop = 0; //接收停止标志
uchar xdata gps_flag = 0; //GPS处理标志
uchar xdata change_page = 0; //换页显示标志
uchar xdata num = 0; //
extern GPS_INFO GPS; //在display.c中定义,使用时要加extern
void Uart_Init(void)
{
TMOD = 0x21; //0010 0001
PCON=0X00;
TH0=0x3c;
TL0=0xb0;
TH1=0xfd; //
TL1=0xfd; //
TR1=1; //开启定时器1
REN=1; //允许接收数据
SM0=0;
SM1=1;
TI=0;
RI=0;
EA=1; //开总中断
ES=1; //串口1中断允许
ET0 = 1; //定时器1中断允许
}
/****************************************
主函数
/****************************************/
void main(void)
{
uchar error_num = 0;
Uart_Init(); //初始化串口
Lcd_Init(); //初始化LCD
GPS_Init(); //初始化GPS
rev_stop=0;
REV_NO;
while(1)
{
if (rev_stop) //如果接收完一行
{
TR0 = 1; //开启定时器
REV_YES;
if (change_page % 2 == 1) //换页
{
if (GPS_GGA_Parse(rev_buf, &GPS)) //解析GPGGA
{
GGA_YES;
GPS_DisplayTwo(); //显示第二页信息
error_num = 0;
gps_flag = 0;
rev_stop = 0;
REV_NO;
}
else
{
error_num++;
if (error_num >= 20) //如果数据无效超过20次
{
GGA_NO;
error_num = 20;
GPS_Init(); //返回初始化
}
gps_flag = 0;
rev_stop = 0;
REV_NO;
}
}
else
{
if (GPS_RMC_Parse(rev_buf, &GPS)) //解析GPRMC
{
RMC_YES;
GPS_DisplayOne(); //显示GPS第一页信息
error_num = 0;
gps_flag = 0;
rev_stop = 0;
led1 = 1;
}
else
{
error_num++;
if (error_num >= 20) //如果数据无效超过20次
{
RMC_NO;
error_num = 20;
GPS_Init(); //返回初始化
}
gps_flag = 0;
rev_stop = 0;
REV_NO;
}
}
}
}
}
void timer0(void) interrupt 1
{
static uchar count = 0;
TH0 = 0x3c;
TL0 = 0xb0;
count++;
if (count == 200) //2*5秒钟
{
count = 0;
change_page++; //换页
if (change_page == 10)
change_page = 0;
}
}
void Uart_Receive(void) interrupt 4
{
uchar ch;
ES = 0;
if (RI)
{
ch = SBUF;
if ((ch == '$') && (gps_flag == 0)) //如果收到字符'$',便开始接收
{
rev_start = 1;
rev_stop = 0;
}
if (rev_start == 1) //标志位为1,开始接收
{
rev_buf[num++] = ch; //字符存到数组中
if (ch == '\n') //如果接收到换行
{
rev_buf[num] = '\0';
rev_start = 0;
rev_stop = 1;
gps_flag = 1;
num = 0;
}
}
}
RI = 0; //RI清0,重新接收
ES = 1;
}