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

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

#include "main.h"
#include "uart.h"

#include 
#include 
#include 
#include 

#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

二,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位UART
    REN  = 1;     //允许串行口接收数据
    PCON = 0x00;  //SMOD=0;波特率不加倍
    TMOD = 0x20;  //T1方式2,用于产生波特率
    TH1  = 0xFD;  //装初值
    TL1  = 0xFD;
    TR1  = 1;     //启动定时器1
    EA   = 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交叉相连,很简单的。无须代码,有电就可以进行配置,后面就可以直接实现透传的功能啦。那么为什么不使用单片机进行配置呢?由于单片机里面会保存有上次烧录进去的代码而且无法清除,必然会影响蓝牙模块的配置。
配置以及查询主要命令有:
基于51单片机&GPS的导航系统设计(2)---具体实施_第1张图片
接着,要将手机设置里面的蓝牙打开,与刚刚配置好的蓝牙模块相配对(找到蓝牙模块的名字并且输入配对码,一般默认配对码为1234,这个1234的默认配对码仅仅对于HC-05来说,例如BT-05默认配对码为123456),配对码可以自行配置,不过不需要修改,以免忘记。手机蓝牙与蓝牙模块配对图所示:
基于51单片机&GPS的导航系统设计(2)---具体实施_第2张图片
接下来才可进行手机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蓝牙接收数据界面图。
基于51单片机&GPS的导航系统设计(2)---具体实施_第3张图片
下面的数字是经纬度,一共有两行。不断实时地接收位置信息。上面的代码中只用了取已配对设备,由于界面有限。不过功能是一样的。
下面是路线规划图:
基于51单片机&GPS的导航系统设计(2)---具体实施_第4张图片
点击开始搜索路线,会进行起点与终点的选择(与地图上面地点要一致)搜索界面如上图。点击开始驾车实时导航会进入导航界面,如下图:
基于51单片机&GPS的导航系统设计(2)---具体实施_第5张图片
说到这里基本已经结束了,下面附上我实验时候的总图,即实物图:
基于51单片机&GPS的导航系统设计(2)---具体实施_第6张图片
那么具体连线方式是什么呢?
对于GPS模块来说:
GPS模块 单片机
VCC 5V(单片机)
GND GND
TXD RXD(P3.0)
对于蓝牙模块来说:
蓝牙模块 单片机
VCC 5V(单片机)
GND GND
RXD TXD(P3.1)
一共六根线即可。
大家有什么问题可以留言,我可以及时作答,毕竟刚答辩结束。

你可能感兴趣的:(基于51单片机&GPS的导航系统设计(2)---具体实施)