打印
[应用相关]

STM32F429+NEO -7N(GPS模块)输出地理位置信息(转载)

[复制链接]
937|8
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
利用GPS定位在生活中并不少见,下面就记录一下自己使用GPS获取地理位置的过程。


目录


实验前准备
NEO-7N GPS模块简介
USB转TTL调试模块
STM32获取GPS数据
GPS数据解析


实验前准备

STM32F429开发板
USB转TTL模块
NEO-7N GPS模块
串口调试助手


使用特权

评论回复
沙发
guanjiaer|  楼主 | 2019-7-5 09:10 | 只看该作者
NEO-7N简介

NEO-7N GPS 模块,具有高灵敏度、低功耗、小型化、极高追踪灵敏度等特点,大大扩大了其定位的覆盖面,在普通GPS 接收模块不能定位的地方,如狭窄都市天 空下 、 密集的丛林环境, NEO-7N 都能高精度定位。模块的高灵敏度、小静态漂移、 低功耗及轻巧的体积,适用于车 载 、手持设备如 PDA,车辆监控、手 机、摄像机及其他移动定位系统的应用。




使用特权

评论回复
板凳
guanjiaer|  楼主 | 2019-7-5 09:10 | 只看该作者
USB转TTL调试模块

从上图可以看到,GPS模块是通过串口传输数据的,因此可以直接接USB转TTL模块调试,接线如下:
GPS---->USB-TTL
VCC ----> VCC
GND----> GND
TXD ----> RXD
RXD----> TXD

使用特权

评论回复
地板
guanjiaer|  楼主 | 2019-7-5 09:11 | 只看该作者
这里还要注意的是:GPS的波特率要选取9600







GPS模块稍微需要点时间工作,通常10分钟内获取到原始数据,还要注意的是:要把该模块放置在室外,不然接收不到GPS信号,建议外接天线,3米那种。 上图就是获取到的原始GPS数据,我们只需要关注以$GPRMC开头的这一组数据。

使用特权

评论回复
5
guanjiaer|  楼主 | 2019-7-5 09:12 | 只看该作者
STM32获取GPS数据


既然GPS的数据输出是通过串口实现的,那么就可以通过配置STM32的串口来读取GPS数据。但是串口获得的原始数据这么多,要怎么才能得到我们想要的数据呢?上文所提到的关注的那一组数据,就是我们需要的数据。我们可以从串口开始数据解析,当串口识别到$GPRMC标识符的几个标识符号就能认为这是我们需要的数据,把该数据保存下来数组才能做后面的进一步处理。这里我使用了32上的串口3函数实现如下:


void USART3_IRQHandler(void)
{
        u8 Res;             
        if(__HAL_UART_GET_FLAG(&UART3_Handler,UART_FLAG_RXNE)!=RESET)//接收到数据
        {         
                HAL_UART_Receive(&UART3_Handler,&Res,1,1000);//读取到接收数据
        if(Res=='$')//读取到的值为'$'
        {
            point1=0;//指定位置为第0个字节
        }

        USART3_RX_BUF[point1++]=Res;
        if(USART3_RX_BUF[0] == '$' && USART3_RX_BUF[4] == 'M' && USART3_RX_BUF[5] == 'C')                        //确定是否收到"GPRMC/GNRMC"这一帧数据
        {
                if(Res == '\n')                                                                          
                {
                        memset(Save_Data.GPS_Buffer, 0, GPS_Buffer_Length);      //清空
                        memcpy(Save_Data.GPS_Buffer, USART3_RX_BUF, point1);         //保存数据
                        Save_Data.isGetData = true;
                        point1 = 0;
                        memset(USART3_RX_BUF, 0, USART3_MAX_RECV_LEN);      //清空                               
                }       
                               
        }
       
        if(point1 >= USART3_MAX_RECV_LEN)
        {
                point1 = USART3_MAX_RECV_LEN;
        }
        }                                                                                                                            
}


使用特权

评论回复
6
guanjiaer|  楼主 | 2019-7-5 09:51 | 只看该作者
当保存了我们需要的数据后,就开始试着输出该组数据,观察$GPRMC这一组数据,都是通过“,”分隔符来区别下一个数据的,因此可以通过判断“,”的位置来确定数据。

void parseGpsBuffer()
{
        char *subString;
        char *subStringNext;
        char i = 0;
        if (Save_Data.isGetData)
        {
                Save_Data.isGetData = false;
                printf("**************\r\n");
                printf("%s",Save_Data.GPS_Buffer);

               
                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/S
                                                case 5:memcpy(Save_Data.longitude, subString, subStringNext - subString);break;        //获取经度信息
                                                case 6:memcpy(Save_Data.E_W, subString, subStringNext - subString);break;        //获取E/W

                                                default: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);        //解析错误
                                }
                        }


                }
        }
}


使用特权

评论回复
7
guanjiaer|  楼主 | 2019-7-5 09:52 | 只看该作者
为了让数据好看些,方便辨认,再通过一个函数让这些数据“排队输出”:

void printGpsBuffer()
{  
        if (Save_Data.isParseData)
        {
                Save_Data.isParseData = false;
               
                printf("Save_Data.UTCTime = %s\r\n",Save_Data.UTCTime);

                if(Save_Data.isUsefull)
                {         
                        Save_Data.isUsefull = false;
                        printf("Save_Data.latitude = %s\r\n",Save_Data.latitude);
                        printf("Save_Data.N_S = %s\r\n",Save_Data.N_S);

                        printf("Save_Data.longitude = %s\r\n",Save_Data.longitude);
                        printf("Save_Data.E_W = %s\r\n",Save_Data.E_W);

            printf("the result longtitude is %s\r\n",longitudeToOnenetFormat(Save_Data.longitude));
            printf("the result latitude is %s\r\n",latitudeToOnenetFormat(Save_Data.latitude));
            //trans_result(Save_Data.longitude,Save_Data.latitude);
                }
                else
                {
                        printf("GPS DATA is not usefull!\r\n");
                }
               
        }
}


使用特权

评论回复
8
guanjiaer|  楼主 | 2019-7-5 09:52 | 只看该作者

上图长的一串数据就是提取的GPRMC数据,该行后面输出的就是分类后的数据。把获取到的经纬度值在地图输入,可以看到具体的位置了,还挺准确的。

使用特权

评论回复
9
guanjiaer|  楼主 | 2019-7-5 09:52 | 只看该作者

GPS数据解析

当然,上面输出的经纬度不是常见的GBS84地图值,因此还可以把数据再进行转换,得到我们想要的数据,这里不贴代码,提供一个思路:就是把GPRMC的值的整数部分和小数部分拆开,储存在数组里面再换算。


使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

77

主题

4116

帖子

2

粉丝