打印
[应用相关]

GPS数据解析(NEO-6M)

[复制链接]
1382|5
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
guanjiaer|  楼主 | 2019-7-5 08:59 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
使用NEO-6M的GPS模块,要知道NMEA协议,这是一种数据传送格式。
其中包括7种数据格式:这七种格式都大同小异,这里就不一一去赘述了,想要了解直接下载相关的datasheet就好了,值得一提的是:这几种格式有些输出的部分信息是一样的,具体要用什么信息,根据自己的项目去选择吧;初始条件下(刚拿到这个模块、刚将芯片焊接完成),GPS模块是将这七条数据全部都输出的;当然,你有时候并不会想要全部的七条数据,这时,可以用u_blox公司的上位机软件u_center对模块进行相关更改,包括改数据输出、改通信波特率、改数据传输速度,这个在正点原子的教程->GPS实验里有很清楚的描述,我就不丢人现眼了;设置好通信波特率,数据传送速率,输出哪种数据后,就可以开始使用模块了。


使用特权

评论回复
沙发
guanjiaer|  楼主 | 2019-7-5 08:59 | 只看该作者
软件部分:GPS模块使用的是串口通讯、所以,在程序中我们要先对连接模块的串口进行相关的初始化:TXD复用推挽输出、RXD浮空输入,波特率设置成和模块的波特率一致等;初始化完成,我们就要开启串口中断来接收数据,串口进入一次中断接收一次数据,一次接收一个字节(即8位),GPS传送出来的数据是字符型的,即串口每接收一次数据就接收一个字符;这些数据在被接收后,可以定义一个数组去缓存;当接收完一帧之后,我们就要处理得到的数据了,注意:这时候得到的是原始数据,也就是一些字符,我们想要用到这些数据,往往要将其转换为其他类型的数据,比如:整形、实型etc…在我的程序中,我只要$GPRMC这种数据格式传出来的纬度和经度信息,想要在程序中运用这些信息,当然不能用字符的形式、那么就要想点办法了,我想要将经纬度信息转化成float型的数据,那怎么办呢?我们都知道数字的字符是ASCII码,字符‘0’的ASCII码是48,假如我得到的数据是字符‘6’,我想要将这个字符6转化为数字6,那怎么办呢?很简单,我的处理方式如下:int k; char b=’6’; k=b-‘0’; 没错,用字符6对应的ASCII码减去字符0的ASCII码,就得到数字的6了;然后你看你读到的这个字符实在数据的个位、十位还是百位上,乘以一个相应的倍数(如百位:k*=100,千位:k*=1000);然后再将这些数据加起来就是了。 还有值得一提的是,想要找到你对应的数据并不用去数逗号,那样反而麻烦了,NMEA传出来的数据格式都是固定的,你只要找到你想要的数据在你存数据的数组的哪一位上,就可以对这个数据进行处理了。Talk is cheap,Show you my code(代码运行在STM32F103ZET6):

使用特权

评论回复
板凳
guanjiaer|  楼主 | 2019-7-5 08:59 | 只看该作者
#define LEN 200
u8 usart_buf[LEN];   //定义一个200字节的数据缓存空间
u8 flag=0;

unsigned short databit=0;
static short k;  /**读坐标函数的变量**/
static float t;
static u8 i;
static float res;
static char da=0;

void gps_open(){

    USART_Cmd(USART2,ENABLE);
}

使用特权

评论回复
地板
guanjiaer|  楼主 | 2019-7-5 09:00 | 只看该作者
void gps_close(){

    USART_Cmd(USART2,DISABLE);
}

使用特权

评论回复
5
guanjiaer|  楼主 | 2019-7-5 09:00 | 只看该作者
void USART2_IRQHandler(){

    u8 data=0;
    if(USART_GetITStatus(USART2,USART_IT_RXNE)==SET)
    {
        data=USART_ReceiveData(USART2);
        usart_buf[databit]=data;
        if( '*' == usart_buf[databit] )    //一帧数据结束了
        {
            gps_close();
            databit = 0;
            flag = 1;
        }
        else
            databit++;
    }
}

使用特权

评论回复
6
guanjiaer|  楼主 | 2019-7-5 09:00 | 只看该作者
//读取当前坐标函数,调用一次读取一次,读完一次自动关闭串口
//传入一个纬度变量和一个经度变量的地址,往这两个地址的储存空间写数
//如果是有效定位,返回1;如果是无效定位,返回0
//纬度ddmm.mmmmm(度分)  经度dddmm.mmmmm(度分)
u8 read_coor(float *latitude,float *longitude){

    gps_open();              //开启GPS
    while(!flag);             //等待一帧数据接收完成  
    flag=0;                   //清空完成标志
    /***********解析一帧数据*************/
    if(usart_buf[17]=='A')  //A说明是有效定位
    {
        for(i=19;i<23;i++)
        {
            da=usart_buf[i];
            k=da-48;
            switch(i)
            {
                case 19:
                    k *= 1000;break;
                case 20:
                    k *= 100;break;
                case 21:
                    k *= 10;break;
                case 22:
                    k *= 1;break;
                default :
                    k = 0;break;
            }
            res+=k;
        }

        for(i=24;i<29;i++)
        {
            da=usart_buf[i];
            t= da - 48;
            switch(i)
            {
                case 24:
                    t *= 0.1;break;
                case 25:
                    t *= 0.01;break;
                case 26:
                    t *= 0.001;break;
                case 27:
                    t *= 0.0001;break;
                case 28:
                    t *= 0.00001;break;
                default :
                    t=0;break;
            }
            res += t;
        }
        *latitude = res;
        res = 0;                        //解析出纬度

        for(i=32; i<37; i++)
        {
            da=usart_buf[i];
            k = da - 48;
            switch(i)
            {
                case 32:
                    k *= 10000;break;
                case 33:
                    k *= 1000;break;
                case 34:
                    k *= 100;break;
                case 35:
                    k *= 10;break;
                case 36:
                    k *= 1;break;
                default :
                    k=0;break;
            }
            res+=k;
        }

        for(i=38;i<43;i++)
        {
            da=usart_buf[i];
            t=da-48;
            switch(i)
            {
                case 38:
                    t *= 0.1;break;
                case 39:
                    t *= 0.01;break;
                case 40:
                    t *= 0.001;break;
                case 41:
                    t *= 0.0001;break;
                case 42:
                    t *= 0.00001;break;
                default :
                    t=0;break;
            }
            res += t;
        }
        *longitude = res;                        //解析出经度
        res = 0;
        return 1;
    }
    return 0;
}

使用特权

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

本版积分规则

72

主题

3916

帖子

2

粉丝