这一篇博客延续的是上一篇博客。
上一篇讲述该设计的设计思路,这一篇讲述如何具体实施。
对于该设计的实施,可以大致分为两个part:(1)51单片机编程部分(2)手机导航APP部分
其中对于51单片机部分的编程不算很难,但是确实不是特别好写。这部分比较重要的也就是:(1)串口初始化配置程序(2)中断接收位置信息以及储存位置信息(3)解析位置信息【因为这个格式不是地图中可以直接使用的格式,需要进行坐标换算】
①51单片机接收并处理GPS位置信息的核心代码
一,下面是main.c的代码。里面的一些变量就不展示声明了。有问题的话可以留言,会及时解答的。

#include "main.h"
#include "uart.h"#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>#define uchar unsigned char  //无符号字符型 宏定义    变量范围0~255
#define uint  unsigned int   //无符号整型 宏定义    变量范围0~65535
//定义变量
//****************************************************
//主函数
//****************************************************
void main()
{unsigned char i = 0;Uart_Init();Delay_ms(10);clrStruct(); //清空缓存数组while(1){   parseGpsBuffer();printGpsBuffer();}
}int String_integer(char s[],int head,int end)
{int i;int num = 0;for (i = head; s[i] >= '0' && s[i] <= '9'&&i<=end; i++){num = 10 * num +(s[i] - '0');}return num;
}
void jingweidu_jiexi(char a[])
{char str[20];int flag=0,i,dian_num,num_a,jzheng,num_b;double jxiaoshu,jingdu;for(i=0; i<strlen(a); i++)if(a[i]=='.'){flag=i;break;}dian_num=strlen(a)-flag-1;num_a=String_integer(a,0,flag-1);jzheng=num_a/100;num_b=String_integer(a,flag+1,strlen(a)-1);jxiaoshu=num_a%100+(double)num_b/pow(10,dian_num);jingdu=jzheng+jxiaoshu/60.0;//printf("%d %d %d\n",num_a,num_b,jzheng);//printf("dian_num===%d %lf\n",dian_num,jxiaoshu);//sprintf(str,"%lf\r\n",jingdu);sprintf(str,"%d.%.6lf\r\n",jzheng,jxiaoshu/60*10);UartPrintf(str);
}
void errorLog(int num)
{while (1){UartPrintf("ERROR");UartPrintASCII(num+0x30);UartPrintf("\r\n");}
}void parseGpsBuffer()
{char *subString;char *subStringNext;char i = 0;if (Save_Data.isGetData){Save_Data.isGetData = false;for (i = 0 ; i <= 6 ; i++){if (i == 0){if ((subString = strstr(Save_Data.GPS_Buffer, ",")) == NULL)errorLog(1);    //解析错误}else{subString++;if ((subStringNext = strstr(subString, ",")) != NULL){char usefullBuffer[2];switch(i){case 1:memcpy(Save_Data.UTCTime, subString, subStringNext - subString);break;   //获取UTC时间case 2:memcpy(usefullBuffer, subString, subStringNext - subString);break;  //获取UTC时间case 3:memcpy(Save_Data.latitude, subString, subStringNext - subString);break; //获取纬度信息case 4:memcpy(Save_Data.N_S, subString, subStringNext - subString);break;   //获取N/Scase 5:memcpy(Save_Data.longitude, subString, subStringNext - subString);break;  //获取经度信息case 6:memcpy(Save_Data.E_W, subString, subStringNext - subString);break;   //获取E/Wdefault:break;}subString = subStringNext;Save_Data.isParseData = true;if(usefullBuffer[0] == 'A')Save_Data.isUsefull = true;else if(usefullBuffer[0] == 'V')Save_Data.isUsefull = false;}else{errorLog(2);   //解析错误}}}}
}void printGpsBuffer()
{if (Save_Data.isParseData){Save_Data.isParseData = false;if(Save_Data.isUsefull){jingweidu_jiexi(Save_Data.latitude);jingweidu_jiexi(Save_Data.longitude);}else{UartPrintf("GPS DATA is not usefull!\r\n");}}
}//****************************************************
//MS延时函数
//****************************************************
void Delay_ms(unsigned int n)
{unsigned int  i,j;for(i=0; i<n; i++)for(j=0; j<123; j++);
}

二,uart.c的代码。

#include "uart.h"
char idata gpsRxBuffer[gpsRxBufferLength];
unsigned char RX_Count = 0;
_SaveData Save_Data;void Uart_Init()
{SCON = 0X50;  //UART方式1;8位UARTREN  = 1;     //允许串行口接收数据PCON = 0x00;  //SMOD=0;波特率不加倍TMOD = 0x20;  //T1方式2,用于产生波特率TH1  = 0xFD;  //装初值TL1  = 0xFD;TR1  = 1;     //启动定时器1EA   = 1;     //打开全局中断控制ES   = 1;     //打开串行口中断
}void UartPrintf(unsigned char *p)              //发送字符串
{ES=0;while(*p){SBUF=*(p++);while(TI==0){};TI=0;}ES=1;
}void UartPrintASCII(unsigned char c)               //发送一个字符
{ES=0;TI=0;SBUF=c;while(TI==0);TI=0;ES=1;
}void RECEIVE_DATA(void) interrupt 4 using 3
{if(RI==1){unsigned char temp = 0;char i = 0;//ES=0;RI = 0;temp = SBUF;if(temp == '$'){RX_Count = 0;}if(RX_Count <= 5){gpsRxBuffer[RX_Count++] = temp;}else if(gpsRxBuffer[0] == '$' &&gpsRxBuffer[4] == 'M' && gpsRxBuffer[5] == 'C')           //确定是否收到"GPRMC/GNRMC"这一帧数据{gpsRxBuffer[RX_Count++] = temp;if(temp == '\n'){memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length);      //清空memcpy(Save_Data.GPS_Buffer, gpsRxBuffer, RX_Count);   //保存数据Save_Data.isGetData = true;RX_Count = 0;memset(gpsRxBuffer, 0, gpsRxBufferLength);      //清空}if(RX_Count >= 75){RX_Count = 75;gpsRxBuffer[RX_Count] = '\0';//添加结束符//RXbit=1;}}}//ES=1;
}void clrStruct()
{Save_Data.isGetData = false;Save_Data.isParseData = false;Save_Data.isUsefull = false;memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length);      //清空memset(Save_Data.UTCTime, 0, UTCTime_Length);memset(Save_Data.latitude, 0, latitude_Length);memset(Save_Data.N_S, 0, N_S_Length);memset(Save_Data.longitude, 0, longitude_Length);memset(Save_Data.E_W, 0, E_W_Length);
}

这两个.c文件是51单片机部分的所有代码(除了.h里面的变量以及函数的声明)。
②下面讲解手机APP程序部分。
大家可以自行下载E4A最新版。
链接:https://pan.baidu.com/s/1BRGgxj0HgcnK8FKM9DB6gQ 提取码:49rf
在此部分之前,对HC-05的配置要了解,一般只需要用到名字,配对码,其他几乎都默认即可,猪从模式选择从模式,波特率选择9600(这两个都是默认的,无须配置),那么如何配置呢,用串口调试助手,大家可以自行下载,网上有很多,配置注意:(1)发送配置命令要换行(2)使用USB-TTL模块对蓝牙模块进行配置,直接连接即可,txd和rxd交叉相连,很简单的。无须代码,有电就可以进行配置,后面就可以直接实现透传的功能啦。那么为什么不使用单片机进行配置呢?由于单片机里面会保存有上次烧录进去的代码而且无法清除,必然会影响蓝牙模块的配置。
配置以及查询主要命令有:

接着,要将手机设置里面的蓝牙打开,与刚刚配置好的蓝牙模块相配对(找到蓝牙模块的名字并且输入配对码,一般默认配对码为1234,这个1234的默认配对码仅仅对于HC-05来说,例如BT-05默认配对码为123456),配对码可以自行配置,不过不需要修改,以免忘记。手机蓝牙与蓝牙模块配对图所示:

接下来才可进行手机APP与蓝牙模块的通信模式。这就需要APP部分的程序了。
软件界面如图所示:

这部分是最简单的,因为这个软件上面会自带很多例程比如蓝牙例程以及地图导航,只需要修改一部分即可。不过需要注意的是,使用新版蓝牙这个蓝牙例程。其他的蓝牙例程并不适用(对于该设计来说)。


事件 主窗口.创建完毕()高德地图1.显示比例尺(真)高德地图1.显示缩放按钮(真)高德地图1.显示指南针(真)高德地图1.显示定位按钮(真)高德导航1.初始化() '初始化高德导航,注意:高德导航必须与高德地图配合使用,否则无效。
结束 事件
事件 按钮1.被单击()新版蓝牙1.开启蓝牙()
结束 事件
事件 按钮2.被单击()新版蓝牙1.关闭蓝牙()
结束 事件
事件 按钮3.被单击()高级列表框1.清空项目()新版蓝牙1.搜索设备()
结束 事件
事件 按钮4.被单击()新版蓝牙1.停止搜索()
结束 事件
事件 新版蓝牙1.发现设备(名称 为 文本型,地址 为 文本型,是否已配对 为 逻辑型)如果 是否已配对 则高级列表框1.添加项目("",名称 & "(已配对)",地址,"","")否则高级列表框1.添加项目("",名称,地址,"","")结束 如果
结束 事件
事件 高级列表框1.表项被单击(项目索引 为 整数型)变量 地址 为 文本型地址=高级列表框1.取项目信息(项目索引)弹出提示(地址)新版蓝牙1.停止搜索()新版蓝牙1.连接设备(地址)
结束 事件
事件 新版蓝牙1.连接成功()弹出提示("连接成功")主窗口.标题="Q蓝牙已经连接"
结束 事件事件 新版蓝牙1.连接失败()弹出提示("连接失败")主窗口.标题="Q蓝牙未连接"
结束 事件
事件 新版蓝牙1.丢失连接()弹出提示("丢失连接")
结束 事件
事件 按钮5.被单击()新版蓝牙1.断开连接()
结束 事件
事件 新版蓝牙1.搜索完毕()弹出提示("搜索完毕")
结束 事件
事件 按钮7.被单击()如果 新版蓝牙1.是否已开启蓝牙() 则弹出提示("已开启蓝牙")否则弹出提示("未开启蓝牙")结束 如果
结束 事件
事件 按钮8.被单击()变量 已配对设备 为 文本型(,)'已配对设备(n,0)=名称   已配对设备(n,1)=地址   n >= 0 < 取数组下标(已配对设备,1)变量 i 为 整数型高级列表框1.清空项目()已配对设备=新版蓝牙1.取已配对设备()i=0判断循环首 i<取数组下标(已配对设备,1)高级列表框1.添加项目("",已配对设备(i,0) & "(已配对)",已配对设备(i,1),"","")i=i+1判断循环尾
结束 事件
事件 新版蓝牙1.收到数据(数据 为 字节型())变量 文本数据 为 文本型文本数据 = 字节到文本(数据,"GBK")编辑框4.加入文本(文本数据)编辑框4.置光标位置(取文本长度(编辑框4.内容))
结束 事件
事件 按钮100.被单击()高德地图1.坐标查询地址(32.968324,112.549652)
结束 事件
事件 高德地图1.坐标查询地址完毕(查询结果 为 逻辑型,地址 为 文本型)如果 查询结果 = 真 则编辑框1.内容=地址否则弹出提示("查询地址失败")结束 如果
结束 事件事件 按钮15.被单击()高德地图1.开始搜索路线2(编辑框1.内容,编辑框2.内容,1,编辑框3.内容)
结束 事件事件 高德地图1.搜索路线完毕(搜索结果 为 逻辑型,起点纬度 为 双精度小数型,起点经度 为 双精度小数型,终点纬度 为 双精度小数型,终点经度 为 双精度小数型)如果 搜索结果 = 真 则弹出提示("搜索路线成功,开始规划导航路线……")'高德导航1.规划步行导航路线(起点纬度,起点经度,终点纬度,终点经度)高德导航1.规划驾车导航路线(起点纬度,起点经度,终点纬度,终点经度)否则 弹出提示("搜索路线失败")结束 如果
结束 事件事件 高德导航1.规划导航路线完毕(规划结果 为 逻辑型)如果 规划结果 = 真 则按钮17.可用 = 真按钮18.可用 = 真弹出提示("导航路线规划成功,可以开始导航")否则 弹出提示("导航路线规划失败")结束 如果
结束 事件事件 按钮17.被单击()'高德导航1.开始步行模拟导航()高德导航1.开始驾车模拟导航()
结束 事件事件 按钮18.被单击()'高德导航1.开始步行实时导航()高德导航1.开始驾车实时导航()
结束 事件事件 主窗口.按下某键(键代码 为 整数型,传址 屏蔽 为 逻辑型)如果 键代码 = 返回键 则高德导航1.释放资源()结束程序()结束 如果
结束 事件

下面是APP蓝牙接收数据界面图。

下面的数字是经纬度,一共有两行。不断实时地接收位置信息。上面的代码中只用了取已配对设备,由于界面有限。不过功能是一样的。
下面是路线规划图:

点击开始搜索路线,会进行起点与终点的选择(与地图上面地点要一致)搜索界面如上图。点击开始驾车实时导航会进入导航界面,如下图:

说到这里基本已经结束了,下面附上我实验时候的总图,即实物图:

那么具体连线方式是什么呢?
对于GPS模块来说:
GPS模块 单片机
VCC 5V(单片机)
GND GND
TXD RXD(P3.0)
对于蓝牙模块来说:
蓝牙模块 单片机
VCC 5V(单片机)
GND GND
RXD TXD(P3.1)
一共六根线即可。
大家有什么问题可以留言,我可以及时作答,毕竟刚答辩结束。

基于51单片机GPS的导航系统设计(2)---具体实施相关推荐

  1. 步进电机的计算机控制系统设计,基于.51单片机的步进电机控制系统设计.doc

    基于51单片机的步进电机控制系统设计 中文摘要 步进电机是一种受,并且能将相应的或者的电动机.由于步进电机具有步距误差不积累.运行可靠.结构简单.惯性小.成本低等优点,因此,被广泛使用于计算机外围电路 ...

  2. 基于51单片机GPS定位公交车自动报站系统(程序+原理图+PCB+论文+全套资料)

    功能介绍: 1.电路设计合理. 2.熟练地使用STC89C52单片机.GPR模块,掌握其原理. 3.可设置播报声音的大小.上行或下行.显示时间等内容 4.采用LCD12864显示时间,位置等信息. 5 ...

  3. 基于51单片机的智能晾衣架系统设计

    1.功能介绍 设计基于51单片机的智能晾衣架.主要功能如下: (1)控制晾衣架的升降. (2)具有限位开关功能. (3)具有无线遥控功能. (4)能够指示运行状态. (5)具有智能模式,可以根据环境光 ...

  4. 基于51单片机的语音采集系统设计(录音笔选择方案)

    功能: 基于51单片机的语音实时采集系统 系统由STC89C52单片机+ISD4004录音芯片+LM386功放模块+小喇叭+LCD1602+按键+指示灯+电源构成 具体实现功能: (1)可通过按键随时 ...

  5. 3、基于51单片机语音识别控制三路开关系统设计

    毕设帮助.开题指导.技术解答(有偿)见文末. 目录 摘要 一.硬件方案 二.设计功能 三.实物图 四.原理图 五.PCB图 六.Proteus仿真 七.程序源码 八.资料包括 摘要 语音识别是解决机器 ...

  6. 单片机c语言 王东锋,基于51单片机的输液报警系统设计

    高扬 摘 要:本设计是以AT89C51单片机为核心,利用光电传感器来检测设备液体的流动情况.当吊瓶内有点滴落下时,可通过红外检测装 1前言 随着信息技术和计算机技术的发展,信息革命在工业.医疗和控制领 ...

  7. 28、基于51单片机空气智能加湿器系统设计

    摘要 湿度的测量应用范围是很广的,对湿度测量系统的研究也具有深远意义,本课题针对国内外对湿度测量系统的研究与发展状况,分析了目前湿度测量系统存在的主要问题,设计了一种基于单片机的湿度测量系统,对某些有 ...

  8. 基于51单片机模拟乒乓球游戏机系统设计

    毕设帮助.开题指导.技术解答(有偿)见文末. 目录 摘要 一.硬件方案 二.设计功能 三.实物图 四.原理图 五.PCB图 六.Proteus仿真 七.程序源码 八.资料包括 摘要 乒乓球游戏电路是一 ...

  9. 58、基于51单片机ADXL345计步器 卡路里系统设计

    毕设帮助.开题指导.技术解答(有偿)见文末. 目录 摘要 一.硬件方案 二.设计功能 三.实物图 四.原理图 五.PCB图 六.keil4开发软件-程序 七.资料包括 摘要 计步器是一种颇受欢迎的日常 ...

最新文章

  1. THINKPHP 分页类
  2. C# WPF MVVM模式Prism框架从零搭建(经典)
  3. SRAM和SDRAM的区别
  4. 从底层分析c和类c语言
  5. Eclipse-JAVA版本
  6. 1年经验却拿总监薪资?看到他做的数据可视化报表,我彻底服了
  7. VS2008中文版MSDN订阅下载问题
  8. go restful 安全_Go语言构建 RESTful Web 服务
  9. python进阶12 Redis
  10. easypr4android,车牌识别系统EasyPR的批量识别功能测试界面
  11. 计算机累论文的数据字典怎么写,毕业论文中数据字典应该这样写
  12. go---token解析与构造
  13. 有关学习方面的资料如何进行打印
  14. IBM服务器无法启动怎么恢复
  15. GraphQL基金会宣布与联合开发基金会合作推动开源和开放标准
  16. 【c语言】判断一个数n能否同时被3和5整除
  17. 加速磁盘碎片整理的六大技巧
  18. 【董天一】IPFS的竞争对手们(一)
  19. 天津达内可靠么 老员工揭秘真实的达内教育
  20. 读书笔记:软件工程(7) - 软件过程模型:螺旋模型、迭代开发

热门文章

  1. Windows11下安装Docker
  2. 软件工程之面向对象分析与设计
  3. go和python解码msgpack不一致
  4. dubbo直连、只订阅、只注册
  5. NodeMCU文档中文翻译 5 上传代码
  6. 雅思作文模板.html,雅思作文模板使用分析
  7. 腾讯敏感词汇大全_有创意的饰品店名,独一无二的饰品店名大全
  8. seque Pro 每次打开都会提示错误
  9. 64位字长的高性能微型计算机,地址总线字长内存容量寻址范围之间的计算
  10. HMS Core Drive SDK构建使用华为云空间服务应用程序