使用stm32读取UbloxGPS模块的UBX协议数据

这篇具有很好参考价值的文章主要介绍了使用stm32读取UbloxGPS模块的UBX协议数据。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

使用模块为图中所示的GPS模块,内部集成UBLOX-M10芯片,可以采用NMEA和UBX协议,使用UBX协议可以输出东北天三个方位速度值,符合本项目要求,所以使用UBX协议输出数据。

使用stm32读取UbloxGPS模块的UBX协议数据

模块上位机设置

虽然模块商家提供了输出UBX协议的C语言例程,但是比较繁琐,我们可以使用UBLOX官方上位机软件进行模块设置,从而省去代码中更繁琐的配置指令。

打开u-center软件进行配置

  1. 上位机配置这里网上参考教程比较多,不再浪费时间,提供一篇大家参考:https://blog.csdn.net/u014421313/article/details/126214774

  1. 这里要注意的一点是,我们使用UBX协议时往往只需要输出PVT这一帧数据就可以得到所有的数据,所以在上位机设置时设置为只输出UBX这一帧数据。

使用stm32读取UbloxGPS模块的UBX协议数据

按F9打开Messages,找到图示的NAV。

使用stm32读取UbloxGPS模块的UBX协议数据

找到NAV下方的PVT右击使能,当字体为黑色说明这一条数据开始输出,要注意如果想只输出这一条数据帧,就要确保没有使能其他语句,即保证其他语句都是灰色的。

硬件连接

使用stm32f103zet6,Ublox连接串口二,使用串口一进行串口助手查看数据。

串口部分代码

串口初始化

void uart_init(u32 bound)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2Periph_GPIOA, ENABLE);    //使能USART1,GPIOA时钟

    //USART1_TX   GPIOA.9
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9

    //USART1_RX      GPIOA.10初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10;//PA10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

    //Usart1 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器

    //USART 初始化设置

    USART_InitStructure.USART_BaudRate = bound;//串口波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //收发模式

  USART_Init(USART1, &USART_InitStructure); //初始化串口1
  USART_ITConfig(USART1, USART_IT_RXNE, ENABLE);//开启串口接受中断
  USART_Cmd(USART1, ENABLE);                    //使能串口1 

}
void uart2_init(u32 bound)
{
    //GPIO端口设置
    GPIO_InitTypeDef GPIO_InitStructure;
    USART_InitTypeDef USART_InitStructure;
    NVIC_InitTypeDef NVIC_InitStructure;

    RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);    //使能USART2,GPIOA时钟
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    //USART2_TX   GPIOA.2
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PA.9
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP;    //复用推挽输出
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.9

    //USART2_RX      GPIOA.3初始化
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_3;//PA10
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING;//浮空输入
    GPIO_Init(GPIOA, &GPIO_InitStructure);//初始化GPIOA.10  

    //Usart2 NVIC 配置
    NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;
    NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority=3 ;//抢占优先级3
    NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;        //子优先级3
    NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;            //IRQ通道使能
    NVIC_Init(&NVIC_InitStructure);    //根据指定的参数初始化VIC寄存器

    //USART 初始化设置

    USART_InitStructure.USART_BaudRate = bound;//串口波特率
    USART_InitStructure.USART_WordLength = USART_WordLength_8b;//字长为8位数据格式
    USART_InitStructure.USART_StopBits = USART_StopBits_1;//一个停止位
    USART_InitStructure.USART_Parity = USART_Parity_No;//无奇偶校验位
    USART_InitStructure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;//无硬件数据流控制
    USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;    //收发模式

  USART_Init(USART2, &USART_InitStructure); //初始化串口2
  USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);//开启串口接受中断
  USART_Cmd(USART2, ENABLE);                    //使能串口2

}

串口2中断接收部分

void USART2_IRQHandler(void)                    //串口2中断服务程序
{
    static uint8_t datacnt=0,state=0; //计数器,状态标志位
    u8 Res;
#if SYSTEM_SUPPORT_OS         //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
    OSIntEnter();    
#endif
    if(USART_GetITStatus(USART2, USART_IT_RXNE) != RESET)  //接收中断()
        {
            Res =USART_ReceiveData(USART2);    //读取接收到的数据
//            databuf[datacnt++]=Res;
            if(state==0) //验证帧头0xb5
            {
                if(Res==0xb5)
                {
                    databuf[datacnt++]=Res;
                    state=1;
                }
                else
                {
                    datacnt=0;
                    state=0;
                }
            }
            
            else if(state==1)  //验证帧头0x62
            {
                if(Res==0x62)
                {
                    databuf[datacnt++]=Res;
                    state=2;
                }
                else
                {
                    datacnt=0;
                    state=0;
                }                
            }

            else if(state==2) //验证class 0x01
            {
                if(Res==0x01)
                {
                    databuf[datacnt++]=Res;
                    state=3;
                }
                else
                {
                    datacnt=0;
                    state=0;
                }                
            }
            else if(state==3)  //验证ID 0x07
            {
                if(Res==0x07)
                {
                    databuf[datacnt++]=Res;
                    state=4;
                }
                else
                {
                    datacnt=0;
                    state=0;
                }                
            }
            else if(state==4) 
            {
                databuf[datacnt++]=Res;
                if(datacnt>=100)
                {
                    if((databuf[98]==checksum(databuf,96)>>8)&&(databuf[99]==(checksum(databuf,96)&0XFF)))
                    {
                        USART2_RX_STA=1;
                        datacnt=0;
                        state=0;
                    }
                 
                }
                                        
            }

    }     
#if SYSTEM_SUPPORT_OS     //如果SYSTEM_SUPPORT_OS为真,则需要支持OS.
    OSIntExit();                                               
#endif
} 

在串口2接收中断中对数据进行判断,PVT语句有0xb5和0x62两个帧头,0x01为Class,0x07为id,加上数据一共100个字节。需预先定义一个状态标志位state,当判断到0xb5时,state为1,然后下一次接收判断0x62,以此类推。

此外UBX协议还有两个校验位,位于最后两位。手册中这两位的定义为:

使用stm32读取UbloxGPS模块的UBX协议数据

所以需要我们编写一个判断校验位的函数

uint16_t checksum(uint8_t*data,uint8_t len)
{
    uint8_t* p=data+2;
    uint8_t j;
    uint32_t CK_a=0,CK_b=0,CK_A=0,CK_B=0;
    uint16_t sum;
    for(j=0;j<len;j++)
    {
        CK_a+=*p++;
        CK_b+=CK_a;
    }
    CK_A=CK_a&0xff;
    CK_B=CK_b&0xff;
    sum=CK_A<<8|CK_B;
    return sum;
}

这个函数把所得两个8位校验位合并为一个16位,在使用时进行移位运算即可得到两个校验位。通过判断校验位两个值使串口二标志位USART2_RX_STA=1,说明数据接收完成。

最后在主函数中写一下串口一把串口二接收的数据通过串口助手显示在屏幕上:

 int main(void)
 {        
     u16 t;  
    delay_init();             //延时函数初始化      
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2); //设置NVIC中断分组2:2位抢占优先级,2位响应优先级
    uart_init(115200);     //串口初始化为115200
    uart2_init(115200);
     LED_Init();                 //LED端口初始化
    KEY_Init();          //初始化与按键连接的硬件接口
     while(1)
    {
        LED1=0;
        if(USART2_RX_STA==1)
        {
            LED0=0;
            
            for(t=0;t<100;t++)
            {
                
                USART_SendData(USART1,databuf[t]);
                while(USART_GetFlagStatus(USART1,USART_FLAG_TC)!=SET);//等待发送结束
            }
//            delay_ms(1000);
        }    

    }     
 }

如果需要提取数据中的经纬度、速度等信息,可以通过手册中对PVT语句的解析,使用相应的字节进行转换,这里要注意数据为小端形式。

接收的数据如下:

使用stm32读取UbloxGPS模块的UBX协议数据

有需要解答的大家可以留言一下,第一次发博客,不太熟练。文章来源地址https://www.toymoban.com/news/detail-477291.html

到了这里,关于使用stm32读取UbloxGPS模块的UBX协议数据的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • STM32 第19讲 IIC(协议简介/读取驱动AT24C02/实验)

    IIC: Inter Integrated Circuit,集成电路总线,是一种 同步 串行 半双工通信协议 ①总线由数据线 SDA 和时钟线 SCL 构成的串行总线,数据线用来传输数据,时钟线用来同步数据收发。 ②总线上每一个器件都有一个唯一的地址识别,所以我们只需要知道器件的地址,根据时序就可以

    2024年02月03日
    浏览(29)
  • 【STM32L496】使用HAL库实现I2C写入/读取数据(M24C32)

    IIC原理超详细讲解—值得一看 【嵌入式硬件芯片开发笔记】EEPROM芯片M24C32配置流程 STM32硬件I2C与软件模拟I2C超详解 实现通信功能的芯片为M24C32,对此,芯片手册上第一页就有对其概括描述。 Automotive 32-Kbit serial I²C bus EEPROM with 1 MHz clock 启动/停止条件 :当串行时钟(SCL)位于

    2024年02月03日
    浏览(53)
  • STM32 串口 DMA 数据读取(详细代码)

    最近重新开始学32,搞到串口 DMA 的时候, 数据读取卡了很长一段时间,最终,功夫不负有心人终于搞出来了。在此以记录一下,方便以后查询使用。 在调试的过程中也遇到了很多bug,有些简直就是低级问题,但是还是卡了很久,在此写出来给自己加深印象,同时已给后来者

    2024年02月16日
    浏览(31)
  • STM32读取GPS数据-ATGM336H

    全球四大卫星定位系统     GPS 系统(美国)     BDS 系统(中国北斗)     GLONASS 系统(俄罗斯)     伽利略卫星导航系统(欧盟)     ATGM336H-5N 系列模块是 9.7X10.1 尺寸的高性能 BDS/GNSS 全星座定位导航模块系列的总称。该系列模块产品都是基于中科

    2024年01月25日
    浏览(33)
  • STM32F407VET6使用SPI访问Flash数据返回0xff(先写入数据,再读取数据,却返回0xff,但是通过debug却可以正常输出)

    STM32F407VET6使用SPI访问Flash数据返回0xff(先写入数据,再读取数据,却返回0xff,但是通过debug却可以正常输出) 看了野火的STM32F103VET6板子的SPI操作Flash的视频,用了自己的STM32F407VET6板子试了一下,出现了点问题,在网上看了很久也没有找出原因,现在问题解决了,就写一篇,

    2024年02月15日
    浏览(33)
  • STM32系列(HAL库)——F103C8T6通过MFRC522、RFID射频卡、门禁卡模块读取卡片ID

    (1)编程平台:Keil5 (2)CubeMX (3)XCOM(串口调试助手) (1)MFRC-522模块 (2)F1的板子,本例使用经典F103C8T6 (3)ST-link 下载器 (4)USB-TTL模块 (5)杜邦线若干 (1)模块简介:         MFRC522-AN模块采用 Philips MFRC522芯片设计读卡电路,使用方便,成本低廉,适用于设备开发、读卡器开发等高级应用

    2024年02月02日
    浏览(30)
  • STM32读取HX711压力传感器芯片数据

    目录 一、HX711压力传感器芯片介绍 1.1 HX711芯片介绍 1.2 芯片管脚与描述 1.3 芯片特点 二、测量原理 2.1 芯片原理图 2.2 压力传感器输出电压值 2.3 芯片原理概述 2.4 数据输出,输入通道和增益选择时序图 2.5 程序计算原理 2.5.1 如何计算传感器供电电压?  2.5.2 如何将 AD 值反向转

    2024年04月16日
    浏览(29)
  • STM32配置读取BMP280气压传感器数据

    BMP280是在BMP180基础上增强的绝对气压传感器,在飞控领域的高度识别方面应用也比较多。 BMP280和BMP180的区别: 市面上也有一些模块: 这里介绍STM32芯片和BMP280的连接和数据读取。 BMP280和STM32的供电范围一致,可以在1.8V, 2.5V和3.3V多个供电电压点直接连接。 BMP280和STM32可以通

    2024年02月13日
    浏览(28)
  • STM32:使用蓝牙模块

            蓝牙是一种常见的无线通信协议,通常用于短距离通信。蓝牙分为经典蓝牙和低功耗蓝牙(BLE)。经典蓝牙通常用于需要持续传输数据的设备,比如蓝牙耳机等。低功耗蓝牙通常用于只需要间歇性传输数据的设备,比如运动手环。         蓝牙通信通常分为主机和从

    2024年02月06日
    浏览(30)
  • 【STM32】STM32G系列使用CORDIC模块加速计算

    STM32G431系列产品内置了CORDIC运算单元,可以用来加速数学计算,如三角函数、取模、开方等。适合大量数据进行相同的运算操作。配合DMA可以大大节省CPU计算开销。 使用CORDIC模块无需配置参数,若采用DMA方式则只需配置DMA读写通道,配置如下 在代码中对cordic模块进行初始化

    2024年02月12日
    浏览(28)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包