发新帖我要提问
12
返回列表
打印
[应用相关]

STM32 驱动GPS模块

[复制链接]
楼主: dingbo95
手机看帖
扫描二维码
随时随地手机跟帖
21
dingbo95|  楼主 | 2018-7-25 21:17 | 只看该作者 回帖奖励 |倒序浏览
//分析GPVTG信息
//gpsx:nmea信息结构体
//buf:接收到的GPS数据缓冲区首地址
void NMEA_GPVTG_Analysis(nmea_msg *gpsx,u8 *buf)
{
        u8 *p1,dx;                         
        u8 posx;   
        p1=(u8*)strstr((const char *)buf,"$GPVTG");                                                         
        posx=NMEA_Comma_Pos(p1,7);                                                                //得到地面速率
        if(posx!=0XFF)
        {
                gpsx->speed=NMEA_Str2num(p1+posx,&dx);
                if(dx<3)gpsx->speed*=NMEA_Pow(10,3-dx);                                  //确保扩大1000倍
        }
}  

使用特权

评论回复
22
木木guainv| | 2018-7-26 09:20 | 只看该作者
非常感谢楼主分享啊

使用特权

评论回复
23
dingbo95|  楼主 | 2018-7-26 20:08 | 只看该作者
//提取NMEA-0183信息
//gpsx:nmea信息结构体
//buf:接收到的GPS数据缓冲区首地址
void GPS_Analysis(nmea_msg *gpsx,u8 *buf)
{
        NMEA_GPGSV_Analysis(gpsx,buf);        //GPGSV解析
        NMEA_GPGGA_Analysis(gpsx,buf);        //GPGGA解析        
        NMEA_GPGSA_Analysis(gpsx,buf);        //GPGSA解析
        NMEA_GPRMC_Analysis(gpsx,buf);        //GPRMC解析
        NMEA_GPVTG_Analysis(gpsx,buf);        //GPVTG解析
}

使用特权

评论回复
24
dingbo95|  楼主 | 2018-7-26 20:10 | 只看该作者
//GPS校验和计算
//buf:数据缓存区首地址
//len:数据长度
//cka,ckb:两个校验结果.
void Ublox_CheckSum(u8 *buf,u16 len,u8* cka,u8*ckb)
{
        u16 i;
        *cka=0;*ckb=0;
        for(i=0;i<len;i++)
        {
                *cka=*cka+buf[i];
                *ckb=*ckb+*cka;
        }
}

使用特权

评论回复
25
dingbo95|  楼主 | 2018-7-26 20:13 | 只看该作者
/////////////////////////////////////////UBLOX 配置代码/////////////////////////////////////
//检查CFG配置执行情况
//返回值:0,ACK成功
//       1,接收超时错误
//       2,没有找到同步字符
//       3,接收到NACK应答
u8 Ublox_Cfg_Ack_Check(void)
{                         
        u16 len=0,i;
        u8 rval=0;
        while((USART2_RX_STA&0X8000)==0 && len<100)//等待接收到应答   
        {
                len++;
                delay_ms(5);
        }                 
        if(len<250)           //超时错误.
        {
                len=USART2_RX_STA&0X7FFF;        //此次接收到的数据长度
                for(i=0;i<len;i++)if(USART2_RX_BUF[i]==0XB5)break;//查找同步字符 0XB5
                if(i==len)rval=2;                                                //没有找到同步字符
                else if(USART2_RX_BUF[i+3]==0X00)rval=3;//接收到NACK应答
                else rval=0;                                                           //接收到ACK应答
        }else rval=1;                                                                //接收超时错误
    USART2_RX_STA=0;                                                        //清除接收
        return rval;  
}

使用特权

评论回复
26
dingbo95|  楼主 | 2018-7-26 20:14 | 只看该作者
//配置保存
//将当前配置保存在外部EEPROM里面
//返回值:0,执行成功;1,执行失败.
u8 Ublox_Cfg_Cfg_Save(void)
{
        u8 i;
        _ublox_cfg_cfg *cfg_cfg=(_ublox_cfg_cfg *)USART2_TX_BUF;
        cfg_cfg->header=0X62B5;                //cfg header
        cfg_cfg->id=0X0906;                        //cfg cfg id
        cfg_cfg->dlength=13;                //数据区长度为13个字节.                 
        cfg_cfg->clearmask=0;                //清除掩码为0
        cfg_cfg->savemask=0XFFFF;         //保存掩码为0XFFFF
        cfg_cfg->loadmask=0;                 //加载掩码为0
        cfg_cfg->devicemask=4;                 //保存在EEPROM里面                 
        Ublox_CheckSum((u8*)(&cfg_cfg->id),sizeof(_ublox_cfg_cfg)-4,&cfg_cfg->cka,&cfg_cfg->ckb);
        while(DMA1_Channel7->CNDTR!=0);        //等待通道7传输完成   
        UART_DMA_Enable(DMA1_Channel7,sizeof(_ublox_cfg_cfg));        //通过dma发送出去
        for(i=0;i<6;i++)if(Ublox_Cfg_Ack_Check()==0)break;                //EEPROM写入需要比较久时间,所以连续判断多次
        return i==6?1:0;
}

使用特权

评论回复
27
dingbo95|  楼主 | 2018-7-26 20:15 | 只看该作者
//配置NMEA输出信息格式
//msgid:要操作的NMEA消息条目,具体见下面的参数表
//      00,GPGGA;01,GPGLL;02,GPGSA;
//                03,GPGSV;04,GPRMC;05,GPVTG;
//                06,GPGRS;07,GPGST;08,GPZDA;
//                09,GPGBS;0A,GPDTM;0D,GPGNS;
//uart1set:0,输出关闭;1,输出开启.          
//返回值:0,执行成功;其他,执行失败.
u8 Ublox_Cfg_Msg(u8 msgid,u8 uart1set)
{
        _ublox_cfg_msg *cfg_msg=(_ublox_cfg_msg *)USART2_TX_BUF;
        cfg_msg->header=0X62B5;                //cfg header
        cfg_msg->id=0X0106;                        //cfg msg id
        cfg_msg->dlength=8;                        //数据区长度为8个字节.       
        cfg_msg->msgclass=0XF0;          //NMEA消息
        cfg_msg->msgid=msgid;                 //要操作的NMEA消息条目
        cfg_msg->iicset=1;                         //默认开启
        cfg_msg->uart1set=uart1set; //开关设置
        cfg_msg->uart2set=1;                  //默认开启
        cfg_msg->usbset=1;                         //默认开启
        cfg_msg->spiset=1;                         //默认开启
        cfg_msg->ncset=1;                         //默认开启          
        Ublox_CheckSum((u8*)(&cfg_msg->id),sizeof(_ublox_cfg_msg)-4,&cfg_msg->cka,&cfg_msg->ckb);
        while(DMA1_Channel7->CNDTR!=0);        //等待通道7传输完成   
        UART_DMA_Enable(DMA1_Channel7,sizeof(_ublox_cfg_msg));        //通过dma发送出去
        return Ublox_Cfg_Ack_Check();
}

使用特权

评论回复
28
dingbo95|  楼主 | 2018-7-26 20:16 | 只看该作者
//配置NMEA输出信息格式
//baudrate:波特率,4800/9600/19200/38400/57600/115200/230400          
//返回值:0,执行成功;其他,执行失败(这里不会返回0了)
u8 Ublox_Cfg_Prt(u32 baudrate)
{
        _ublox_cfg_prt *cfg_prt=(_ublox_cfg_prt *)USART2_TX_BUF;
        cfg_prt->header=0X62B5;                //cfg header
        cfg_prt->id=0X0006;                        //cfg prt id
        cfg_prt->dlength=20;                //数据区长度为20个字节.       
        cfg_prt->portid=1;                        //操作串口1
        cfg_prt->reserved=0;                 //保留字节,设置为0
        cfg_prt->txready=0;                         //TX Ready设置为0
        cfg_prt->mode=0X08D0;                 //8位,1个停止位,无校验位
        cfg_prt->baudrate=baudrate; //波特率设置
        cfg_prt->inprotomask=0X0007;//0+1+2
        cfg_prt->outprotomask=0X0007;//0+1+2
        cfg_prt->reserved4=0;                 //保留字节,设置为0
        cfg_prt->reserved5=0;                 //保留字节,设置为0
        Ublox_CheckSum((u8*)(&cfg_prt->id),sizeof(_ublox_cfg_prt)-4,&cfg_prt->cka,&cfg_prt->ckb);
        while(DMA1_Channel7->CNDTR!=0);        //等待通道7传输完成   
        UART_DMA_Enable(DMA1_Channel7,sizeof(_ublox_cfg_prt));        //通过dma发送出去
        delay_ms(200);                                //等待发送完成
        USART2_Init( baudrate);        //重新初始化串口2   
        return Ublox_Cfg_Ack_Check();//这里不会反回0,因为UBLOX发回来的应答在串口重新初始化的时候已经被丢弃了.
}

使用特权

评论回复
29
dingbo95|  楼主 | 2018-7-26 20:16 | 只看该作者
//配置UBLOX NEO-6的时钟脉冲输出
//interval:脉冲间隔(us)
//length:脉冲宽度(us)
//status:脉冲配置:1,高电平有效;0,关闭;-1,低电平有效.
//返回值:0,发送成功;其他,发送失败.
u8 Ublox_Cfg_Tp(u32 interval,u32 length,signed char status)
{
        _ublox_cfg_tp *cfg_tp=(_ublox_cfg_tp *)USART2_TX_BUF;
        cfg_tp->header=0X62B5;                //cfg header
        cfg_tp->id=0X0706;                        //cfg tp id
        cfg_tp->dlength=20;                        //数据区长度为20个字节.
        cfg_tp->interval=interval;        //脉冲间隔,us
        cfg_tp->length=length;                //脉冲宽度,us
        cfg_tp->status=status;                   //时钟脉冲配置
        cfg_tp->timeref=0;                        //参考UTC 时间
        cfg_tp->flags=0;                        //flags为0
        cfg_tp->reserved=0;                         //保留位为0
        cfg_tp->antdelay=820;            //天线延时为820ns
        cfg_tp->rfdelay=0;                    //RF延时为0ns
        cfg_tp->userdelay=0;            //用户延时为0ns
        Ublox_CheckSum((u8*)(&cfg_tp->id),sizeof(_ublox_cfg_tp)-4,&cfg_tp->cka,&cfg_tp->ckb);
        while(DMA1_Channel7->CNDTR!=0);        //等待通道7传输完成   
        UART_DMA_Enable(DMA1_Channel7,sizeof(_ublox_cfg_tp));        //通过dma发送出去
        return Ublox_Cfg_Ack_Check();
}

使用特权

评论回复
30
dingbo95|  楼主 | 2018-7-26 20:22 | 只看该作者
//配置UBLOX NEO-6的更新速率            
//measrate:测量时间间隔,单位为ms,最少不能小于200ms(5Hz)
//reftime:参考时间,0=UTC Time;1=GPS Time(一般设置为1)
//返回值:0,发送成功;其他,发送失败.
u8 Ublox_Cfg_Rate(u16 measrate,u8 reftime)
{
        _ublox_cfg_rate *cfg_rate=(_ublox_cfg_rate *)USART2_TX_BUF;
        if(measrate<200)return 1;        //小于200ms,直接退出
        cfg_rate->header=0X62B5;        //cfg header
        cfg_rate->id=0X0806;                 //cfg rate id
        cfg_rate->dlength=6;                 //数据区长度为6个字节.
        cfg_rate->measrate=measrate;//脉冲间隔,us
        cfg_rate->navrate=1;                //导航速率(周期),固定为1
        cfg_rate->timeref=reftime;         //参考时间为GPS时间
        Ublox_CheckSum((u8*)(&cfg_rate->id),sizeof(_ublox_cfg_rate)-4,&cfg_rate->cka,&cfg_rate->ckb);
        while(DMA1_Channel7->CNDTR!=0);        //等待通道7传输完成   
        UART_DMA_Enable(DMA1_Channel7,sizeof(_ublox_cfg_rate));//通过dma发送出去
        return Ublox_Cfg_Ack_Check();
}

使用特权

评论回复
31
dingbo95|  楼主 | 2018-7-26 21:04 | 只看该作者
木木guainv 发表于 2018-7-26 09:20
非常感谢楼主分享啊

你在做GPS的项目吗?

使用特权

评论回复
32
dingbo95|  楼主 | 2018-7-26 21:05 | 只看该作者
希望可以帮到需要的人

使用特权

评论回复
33
keaibukelian| | 2018-7-27 08:34 | 只看该作者
很好 非常感谢楼主分享

使用特权

评论回复
34
paotangsan| | 2018-7-27 09:22 | 只看该作者
通讯距离能达到多少

使用特权

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

本版积分规则