收藏 分销(赏)

基于某单片机GPS定位信息显示系统设计.doc

上传人:鼓*** 文档编号:9737859 上传时间:2025-04-05 格式:DOC 页数:35 大小:920.20KB 下载积分:8 金币
下载 相关 举报
基于某单片机GPS定位信息显示系统设计.doc_第1页
第1页 / 共35页
基于某单片机GPS定位信息显示系统设计.doc_第2页
第2页 / 共35页


点击查看更多>>
资源描述
实用标准文案 目录 一、系统整体概述 2 (一)主要内容 2 (二)系统方案的总体设计 2 二、硬件设计 3 (一)硬件总体结构框图 3 (二)单片机的介绍 4 1. STC89C52的简介 4 2. STC89C52引脚图 4 (三)GPS(UBLOX NEO 6M)模块介绍 4 1. UBLOX NEO 6M简介 4 2. UBLOX NEO 6M性能和管脚定义 5 (四)LCD(12864)模块介绍 6 1. LCD(12864)简介 6 2. LCD(12864)引脚介绍 6 3. LCD(12864)操作时序 6 (五)硬件电路PCB板的绘制 7 1. 原理图的绘制 7 2. PCB板的绘制 7 3. 实际硬件电路 8 三、软件设计 9 (一)软件设计思路 9 (二)模块化软件设计 9 1. GPS接收模块设计 9 2. 单片机模块设计 11 3. 显示模块设计 11 四、系统调试与结果 13 (一)硬件调试 13 (二)软件调试 13 (三)设计结果 14 五、总 结 16 参考文献 17 附录 18 一、系统整体概述 (一)主要内容 在学习C51系列单片机和GPS定位原理以及GPS相关知识的理论知识基础上,我们需要在种类繁多的单片机和GPS类型中选择合适的单片机和GPS模块,GPS模块的作用是用来接收卫星信号然后提取相应的信息,单片机作为本次设计系统的控制核心,对GPS模块接收到的信息进行处理,然后用液晶显示屏实时显示预设的数据信息。 系统的具体实现主要由软硬件设计结合完成。硬件设计核心是单片机最小系统的设计,然后在最小系统的基础上设计本次设计所需的外围电路,借助成品GPS模块,完成硬件电路的焊接,该设计硬件电路设计并不复杂,而且体积小便于携带。软件设计的核心内容是实现GPS模块与单片机的通信进而完成系统设计的要求,因为模块化设计具有功能清晰、调试方便等优点,而且在不同平台上移植方便,所以这次设计的思路是采用模块化设计,整个软件开发环境用Keil软件,采用C语言编程,硬件则为使用Altium Designer。 (二)系统方案的总体设计 本次设计的目标是要在单片机的基础上完成GPS定位信息显示系统设计。根据设计预设的要求,我们设计是以单片机为控制核心,控制GPS接收模块,最后利用液晶显示设备就可以实现系统设计目标。 市场上单片机种类很多,C51系列单片机,STM系列单片机等等。通过考虑单片机的普适性、所具备的功能、具体I/0口的性能以及价格是否经济实用等因素,本次设计采用C51系列单片机。系统整体是由硬件设计和软件设计两部分设计而成,采用C51系列单片机、GPS定位模块、LCD液晶显示模块设计而成。硬件设计主要由单片机(STC89C52)、GPS模块(UBLOX NEO 6M)、LCD12864液晶显示模块等组成;接收GPS模块传送的数据信息是软件设计的重点,进而获得当前所处位置的经纬度、航向和海拔等信息。 二、硬件设计 (一)硬件总体结构框图 硬件总体结构框图如图2-1所示。 液晶显示电路 STC89C52 GPS接收模块 GPS信号 电源 图2-1 硬件总体结构框图 本次设计系统的硬件电路主要由下面几部分构成: 第一,接收模块电路。GPS模块负责锁定卫星,然后把信息传送给单片机。 第二,控制模块电路。以STC89C52单片机为控制核心,读取GPS模块传送的数据,然后把读取的数据送到液晶显示屏即实现了单片机的控制作用。 第三,液晶显示电路。51单片机控制液晶显示电路,在液晶显示屏进而可以显示GPS模块读取的数据信息。 第四,电源部分电路。整个系统的正常工作需要电源部分为其提供电源。 此外,硬件电路中还会涉及一些使单片机正常工作的外围电路,以保证单片机正常工作。 (二)单片机的介绍 1. STC89C52的简介 STC89C52是STC公司生产的一种控制器。MCS-51内核是该单片机的经典内核,而且在STC89C52上做了很多的创新,使其不仅具有传统51单片机所具有的功能,而且引进了很多创新的功能,使STC89C52的应用范围更加广泛。STC89C52具体的使用标准可以查阅相关书籍和芯片技术手册,更多资料不再说明。 2. STC89C52引脚图 图2-2 STC89C52引脚图 (三)GPS(UBLOX NEO 6M)模块介绍 1. UBLOX NEO 6M简介 本次课程设计使用的GPS(UBLOX NEO 6M)模块是一个完整的成品接收模块,具有高性能、低功耗的优点,能满足我们本次设计定位的要求。GPS模块实物图如图2-2所示。 图2-3 GPS模块实物 2. UBLOX NEO 6M性能和管脚定义 (1) 定位时间(TTFF):精准的定位时间和当前环境有关。 (2)灵敏度 Min Lyp Max 单位 跟踪 -160 dBm 捕获 -147 dBm 表2-4 GPS灵敏度 (3)精度 2D平面:2.5m[平均] 漂移:<0.02m/s 2D平面:2m[平均],有WAAS辅助 授时精度:1us (4)UBLOX NEO 6M管脚定义见表2-5所示。 序号 名称 I/O 描述 特性 1 VCC 1 模块主电源,直流输入 DC3.0V-5.2V 2 GND 0 接地 3 TX 0 UART接口 OH>=2.1375V,OL<=0.7125V 4 RX 1 UART接口 3.15V>=OH>=1.995V -0.3V<=OL<=0.855V 5 PPS 0 模块定位脉冲 OH>=2.1375V,OL<=0.7125V 表2-5 GPS管脚定义 (更加详细资料可参考UBLOX NEO 6M数据手册) (四)LCD(12864)模块介绍 1. LCD(12864)简介 LCD(12864)液晶显示模块类型属于汉字图形类型的液晶模块,可在显示屏上显示数字、符号和汉字等字符。可与CPU直接连接,设有串行和并行这两种控制方式。具有多种功能可供使用,具体使用哪种功能可查阅芯片资料。 2. LCD(12864)引脚介绍 D0~D7是数据口,RS(CS)是数据/命令选择端(串片选),R/W(SID)端口是读/写选择端(串数据口),E(SCLK)是使能信号(串同步时钟信号),PSB端口是串/并选择端口,RST是我们熟悉而且常用的复位端口(低电平有效),BLA与BLK则是并不常用的背光电源正极端和负极端。LCD(12864)的引脚如图2-6所示。 图2-6 LCD12864引脚 3. LCD(12864)操作时序 12864控制可使用两种时序,分别为并行操作时序和串行操作时序。(具体内容太多,可参考12864数据手册。) (五)硬件电路PCB板的绘制 大二时由于自学过Altium Designer,又参加飞思卡尔智能车竞赛绘制电路板,加上平时经常绘制一些较为复杂的PCB,所以此系统所有硬件由Altium Designer设计完成。 1. 原理图的绘制 根据系统要求绘制的硬件原理图如图2-6所示。其中包括了单片机最小系统电路(复位、震荡、程序下载接口等电路)、电源电路、12864显示屏接口电路和led指示灯电路。 图2-7 硬件电路原理图 2. PCB板的绘制 根据系统要求及原理图绘制的PCB图如图2-8所示。 图2-8 硬件电路PCB图 3. 实际硬件电路 由于资金原因,设计好的PCB并没有送某宝卖家打印,实际电路板由洞洞板焊接而成,如图2-9所示。 图2-9 实际硬件图 三、软件设计 (一)软件设计思路 实现GPS接收模块与单片机的通信是软件设计的核心模块,然后可以实现在液晶显示屏上实时显示当前的数据信息。整个编程是用keil软件,采用C语言编程。 功能清晰、调试方便等特点是软件模块化设计所具有的优点,所以采用模块化设计,GPS数据接收模块、单片机模块、LCD模块和实时显示模块是软件程序设计的四个组成部分。 程序的设计思路是GPS模块接收信息,然后向单片机发送固定格式的数据,单片机通过串口接收数据,并对数据进行解析,最终实现在LCD显示屏上显示时间、经纬度和高度等信息。详细源代码见附录。 (二) 模块化软件设计 1. GPS接收模块设计 首先在搜索卫星时显示“华水课程设计”、“江涛201412712”和“GPS显示项目”,然后进行识别判断GPS模块收到的信息是否完成发送给单片机的操作,若有信息发送给单片机,但接收到的信息我们并不是全部需要,所以需要进行识别判断相应语句的操作,然后把需要的信息存入到GPRMC语句中。GPS接收模块程序流程图如图3-1所示。 结 束 开 始 显示界面初始化 GPRMC判断 有效性分析 纬度、经度、速度、海拔、航向、高度、时间、日期提取 数据存储和处理 图3-1GPS接收模块流程图 2. 单片机模块设计 GPS模块接收到数据信息后,需要把信息传送到单片机,单片机经过分析以及对数据信息进行筛选处理,然后送到液晶显示屏实时显示相应的位置信息,具体主要通过两个界面显示。单片机模块程序设计流程图如图3-2所示。 开 始 接收GPS模块数据 单片机模块设置初始化 数据处理 数据写入STC89C52 进行显示 结 束 图3-2 单片机模块流程图 3. 显示模块设计 GPS模块接收信息后,把信息传送给单片机,单片机首先对数据进行筛选和处理等操作,然后就可以把信息送到液晶显示模块,就实现了在液晶显示屏实时显示当前位置我们所需的信息。液晶显示屏主要分为两个界面显示,界面一实时显示当前的日期、时间和经纬度信息,界面二实时显示当前所处位置的速度、航向、高度和海拔。显示模块程序设计流程图如图3-3所示。 界面一显示设置 界面二显示设置 开 始 初始化设置 分页显示 结 束 图3-3 显示模块流程图 四、系统调试与结果 (一)硬件调试 检测电路设计和工艺设计等方面的故障是硬件调试的主要任务。 1. 检查电路设计中所有元件的焊接以及引脚是否有故障。 首先用万用表逐个检查焊点,目的是检测是否出现短路和断路故障。然后接入电源,观察电源指示灯的工作状态,硬件电路加入电源指示灯可以方便的检测硬件电路焊接是否正常。 2. 进行仿真操作。 用单片机控制仿真操作,目的是用来检查系统所涉及的接口是否达到设计的要求。 把程序下载到单片机上。 利用Keil软件,将已经完成的程序进行选择生成头文件的操作,然后把文件下载到STC89C52单片机。 4. 检查单个模块。 通过下载51单片机自带的程序到单片机,然后查看液晶显示屏(LCD12864)的显示情况判断单个模块是否工作正常。 (二)软件调试 软件调试时我们是使用Keil软件进行仿真和调试,可以检查程序是否出错,而且同时可以纠正程序的错误,若硬件设计有问题,就可以检查出硬件的故障然后我们就可以进行修改。因为程序设计是模块化的,所以在调试时可以逐个模块进行调试,若模块调试结果正常,就可以进行整个程序的调试。尤其注意查看各个模块的语法正确而参数设计不正确的情况。 1. 检查已经编译完成的LCD(12864)液晶显示模块程序,查看液晶显示屏能否正常显示。 2. 检查已经编译完成的GPS模块程序,查看液晶显示屏显示的信息和预设结果的差距进而修改GPS接收模块程序。 3. 运行整个程序,观察液晶显示屏的结果是否实时显示当前位置我们所设想的信息,通过显示效果进行相应的软硬件修改。 (三)设计结果 软件调试初各个模块工作正常,但一旦运行整个程序,液晶显示屏在GPS搜索卫星界面后出现乱码,通过多次的调试和检测,原来是晶振不符合要求,更换晶振后,再次进行调试和检测,最终液晶显示屏显示了预想的结果,即实现了实时显示当前位置的日期、时间、纬度、经度等信息。调试结果初始化界面如图4-1所示。 图4-1 初始化界面 把当前位置液晶显示屏显示的信息与谷歌地图显示的位置信息进行对比,日期、时间非常精确,但经度与纬度出现了误差。究其原因:一是由于本次设计所采用的GPS接收模块精度并不高,不能进行精确定位接收;二是在实验中不可避免会受障碍物、天气等因素的干扰,试验环境并不理想;三是在谷歌地图中我们手动点选的位置没有和GPS测量位置达到同步。但是误差是在误差范围内,我们是可以接受的。所以本次设计是有意义的,可靠的。即实现了实时显示当前位置的数据信息。界面一和二显示结果如图5-2,5-3所示。 图4-2 界面一显示结果 图4-3 界面二显示结果 五、总 结 本次课程设计以单片机为控制核心,控制GPS接收模块,GPS模块把接收到的信息传送给单片机,单片机把数据信息送到液晶显示屏显示,实现实时显示当前位置的数据信息。 通过完成本次的课程设计,做到了单片机的理论知识和实践相结合。我们在初学习单片机时,曾把精力主要放在学习单片机的内部结构上。可想而知,学起来非常痛苦。实践证明,这不是正确的方法,我们应该把精力放在单片机的应用上,在掌握应用过程中我们发现也逐步掌握了单片机的内部结构,也学会了充分地利用了单片机的资源。通过学习单片机知识,进而了解了计算机的原理和结构。计算机的功能主要体现在控制功能上,比如现在流行的智能家居领域也是单片机控制功能的体现。 经过本次的单片机课程设计,不仅学习了GPS接收模块的知识、单片机和液晶显示模块相关知识,也提高了自己的焊接能力,使自己明确了拿到一个课题自己应该从哪着手去做,使自己有明确的系统设计思路,也懂得了当实验结果不理想时,该如何去纠错,如何去寻找问题,解决问题。 参考文献 [1]数字电子技术基础/岩石主编;清华大学电子学教研组编.-5版.-北京:高等教育出版社,2006.5 [2]模拟电子技术基础/童诗白,华成英主编;清华大学电子学教研组编.-4版.-北京:高等教育出版社,2006.5 [3]潘谈.基于STC89C58芯片的小型GPS船舶航迹仪的设计[J].舰船科学技术,2014,(12):124-127. [4]杜俊,董松.基于单片机的GPS定位系统的设计与实现[J].甘肃科技,2016,(19):25-27. [5]张亮红,刘文怡,王红亮.基于单片机的GPS定位系统的设计与实现[J].电子器件,2015,(5):1187-1191. [6]谭昕.基于单片机的GPS导航装置分析[J].中国新通信,2015,(18):115. [7]刘颖.基于单片机的GPS导航装置的设计研究[J].科技展望,2015,(18):157. [8]高芳.单片机在GPS系统中的应用[J].电子制作,2013,(19):57. [9]Guang Li Long.Design of GPS based on Single Chip Microcomputer[J].Trans Tech期刊,2012:2192-2195. 附录 系统设计部分代码: Main.c //====================================================================== // 工程名称: 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 uchar code inf[] = {" 华水江涛 "}; 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 (1) //如果接收完一行 { 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; } } } } } //定时器0服务函数 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; led1 = ~led1; 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; } =============================================================================== GPS.c #include "GPS.h" #include "LCD.h" #include <string.h> uchar code init1[] = {" 华水课程设计 "}; uchar code init2[] = {" 江涛 201412712 "}; uchar code init3[] = {" GPS显示项目 "}; uchar code init4[] = {"搜索定位卫星...."}; static uchar GetComma(uchar num,char* str); static double Get_Double_Number(char *s); static float Get_Float_Number(char *s); static void UTC2BTC(DATE_TIME *GPS); void GPS_Init(void) { Lcd_DispLine(0, 0, init1); Lcd_DispLine(1, 0, init2); Lcd_DispLine(2, 0, init3); Lcd_DispLine(3, 0, init4); } int GPS_RMC_Parse(char *line,GPS_INFO *GPS) { uchar ch, status, tmp; float lati_cent_tmp, lati_second_tmp; float long_cent_tmp, long_second_tmp; float speed_tmp; char *buf = line; ch = buf[5]; status = buf[GetComma(2, buf)]; if (1) //如果第五个字符是C,($GPRMC) { if (status == 'A') //如果数据有效,则分析 { GPS -> NS = buf[GetComma(4, buf)]; GPS -> EW = buf[GetComma(6, buf)]; GPS->latitude = Get_Double_Number(&buf[GetComma(3, buf)]); GPS->longitude = Get_Double_Number(&buf[GetComma( 5, buf)]); GPS->latitude_Degree = (int)GPS->latitude / 100; //分离纬度 lati_cent_tmp = (GPS->latitude - GPS->latitude_Degree * 100); GPS->latitude_Cent = (int)lati_cent_tmp; lati_second_tmp = (lati_cent_tmp - GPS->latitude_Cent) * 60; GPS->latitude_Second = (int)lati_second_tmp; GPS->longitude_Degree = (int)GPS->longitude / 100; //分离经度 long_cent_tmp = (GPS->longitude - GPS->longitude_Degree * 100); GPS->longitude_Cent = (int)long_cent_tmp; long_second_tmp = (long_cent_tmp - GPS->longitude_Cent) * 60; GPS->longitude_Second = (int)long_second_tmp; speed_tmp = Get_Float_Number(&buf[GetComma(7, buf)]); //速度(单位:海里/时) GPS->speed = speed_tmp * 1.85; //1海里=1.85公里 GPS->direction = Get_Float_Number(&buf[GetComma(8, buf)]); //角度 GPS->D.hour = (buf[7] - '0') * 10 + (buf[8] - '0'); //时间 GPS->D.minute = (buf[9] - '0') * 10 + (buf[10] - '0'); GPS->D.second = (buf[11] - '0') * 10 + (buf[12] - '0'); tmp = GetComma(9, buf); GPS->D.day = (buf[tmp + 0] - '0') * 10 + (buf[tmp + 1] - '0'); //日期 GPS->D.month = (buf[tmp + 2] - '0') * 10 + (buf[tmp + 3] - '0'); GPS->D.year = (buf[tmp + 4] - '0') * 10 + (buf[tmp + 5] - '0')+2000; UTC2BTC(&GPS->D); return 1; } } return 0; } int GPS_GGA_Parse(char *line,GPS_INFO *GPS) { uchar ch, status; char *buf = line; ch = buf[4]; status = buf[GetComma(2, buf)]; if (ch == 'G') //$GPGGA { if (status != ',') { GPS->height_sea = Get_Float_Number(&buf[GetComma(9, buf)]); GPS->height_ground = Get_Float_Number(&buf[GetComma(11, buf)]); return 1; } } return 0; } static float Str_To_Float(char *buf) { float rev = 0; float dat; int integer = 1; char *str = buf; int i; while(*str != '\0') { switch(*str) { case '0': dat = 0; break; case '1': dat = 1; break; case '2': dat = 2; break; case '3': dat = 3; break; case '4': dat = 4; break; case '5': dat = 5; break; case '6': dat = 6; break; case '7': dat = 7; break; case '8': dat = 8; break; case '9': dat = 9; break; case '.': dat = '.'; break; } if(dat == '.') { integer = 0; i = 1; str ++; continue; } if( integer == 1 ) { rev = rev * 10 + dat; } else { rev = rev + dat / (10 * i); i = i * 10 ; } str ++; } return rev; } static float Get_Float_Number(char *s) { char buf[10]; uchar i; float rev; i=GetComma(1, s); i = i - 1; strncpy(buf, s, i); buf[i] = 0; rev=Str_To_Float(buf); return rev; } static double Str_To_Double(char *buf) { double rev = 0; double dat; int integer = 1; char *str = buf; int i; while(*str != '\0') { switch(*str) { case '0': dat = 0; break; case '1': dat = 1; break; case '2': dat = 2; break; case '3': dat = 3; break; case '4': dat = 4; break; case '5': dat = 5; break; case '6': dat = 6; break; case '7': dat = 7; break; case '8': dat = 8;
展开阅读全文

开通  VIP会员、SVIP会员  优惠大
下载10份以上建议开通VIP会员
下载20份以上建议开通SVIP会员


开通VIP      成为共赢上传

当前位置:首页 > 学术论文 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        抽奖活动

©2010-2026 宁波自信网络信息技术有限公司  版权所有

客服电话:0574-28810668  投诉电话:18658249818

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :微信公众号    抖音    微博    LOFTER 

客服