基于 stm32 的 GPS 数据解析
最编程
2024-04-25 22:12:57
...
目录
1.GPS模块
2.GPS发送的数据格式
3.软件设计
3.1配置好串口
3.2然后写串口中断函数
效果
1.GPS模块
2.GPS发送的数据格式
$GPRMC,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,<10>,<11>,<12>*hh<CR><LF>
<1> UTC 时间,hhmmss(时分秒)格式
<2> 定位状态,A=有效定位,V=无效定位
<3>纬度ddmm.mmmm(度分)格式(前面的0也将被传输)
<4> 纬度半球N(北半球)或S(南半球)
<5>经度dddmm.mmmm(度分)格式(前面的0也将被传输)
<6> 经度半球E(东经)或W(西经)
<7>地面速率(000.0~999.9节,前面的0也将被传输)
<8>地面航向(000.0~359.9度,以真北为参考基准,前面的0也将被传输)
<9> UTC 日期,ddmmyy(日月年)格式
<10>磁偏角(000.0~180.0度,前面的0也将被传输)
<11> 磁偏角方向,E(东)或W(西)
<12>模式指示(仅NMEA01833.00版本输出,A=自主定位,D=差分,E=估算,N=数据无效 <CR><LF>表示回车和换行
3.软件设计
3.1配置好串口
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
}
3.2然后写串口中断函数
当串口接收到数据后,我们用$符号记录每条信息的开始,用K记录逗号的位置,便于解析数据
这里解析的是gprmc中的经纬度速度和gpgga里的高度;
void USART1_IRQHandler(void) //串口1中断服务程序
{
u8 res;
res =USART_ReceiveData(USART1); //读取接收到的数据
if(res=='$'||USART_RX_BUF[0]=='$')
{
if(res=='$')
i=0;
USART_RX_BUF[i]=res;
i++;
}
if(USART_RX_BUF[4]=='M'&&USART_RX_BUF[5]=='C')
{
if(res==',')
k++;
switch(k)
{
case 2:
if(res=='A'&&res!=',')
flag=1;
else
flag=0;
break;
case 3:
if(flag==1&&res!=','&&res!='.')
{ longitude*=10;
longitude+=res-48;}
break;
case 5:
if(flag==1&&res!=','&&res!='.')
{latitude*=10;
latitude+=res-48;}
break;
case 7:
if(flag==1&&res!=','&&res!='.')
{ speed*=10;
speed+=res-48;}
break;
}
}
if(USART_RX_BUF[4]=='G'&&USART_RX_BUF[5]=='A')
{
if(res==',')
p++;
switch(p)
{
case 9:
if(res!=','&&res!='.')
{
high*=10;
high+=res-48;
}
break;
}
if(res==0x0A)
{
memset(USART_RX_BUF,0x00,200);
i=0;
k=0;
a=longitude/10000000;
b=latitude/10000000;
c=speed/10*0.5144;
printf("longitude: %f\r\n",a);
printf("latitude: %f\r\n",b);
printf("speed: %f\r\n",c);
printf("high: %f\r\n",high/100);
longitude=0;
latitude=0;
speed=0;
}
}
}
解析完数据化,打印数据;
效果
推荐阅读
-
照片特定风格转换 Stylar AI;GPT-4V 开放源替代 InternVL;纯 C/C++ 实现的稳定扩散库;基于 AI 的数据爬行
-
Java 基于数据量的进度条百分比简单算法
-
美团点评基于风暴的实时数据处理实践
-
基于电力线载波的数据通信和远程控制
-
基于51单片机的温湿度测量电力载波通信(实物+原理图+PCB+全套资料)--利用51单片机,测量温湿度,通过电力载波协议将数据通过220V供电线路传输到计算机显示,具体功能如下演示视频,全套资料
-
基于深度学习的作物叶病检测系统(UI 界面 + YOLOv5 + 训练数据集)
-
基于 STM32 的记录仪设计(STM32F103+VS1053B)
-
基于 python-flask 技术的社区信息交流平台 [数据库 + 15000 文档] - 简介
-
【论文阅读:基于夏普利值的高效数据估值
-
基于 Python 的零基网络爬虫:抓取 4A 猎头公司数据