stm32单片机串口接收GPS数据并解析NMEA之GPRMC

发布者:等放假的Lwj最新更新时间:2018-10-06 来源: eefocus关键字:stm32  单片机  串口接收 手机看文章 扫描二维码
随时随地手机看文章

程序主要实现对GPRMC数据的全解析,解析包括时间解析,位置解析,航向,组合,定位状态等等的解析

直接利用stm32系列单片机对GPS板卡接收到的数据进行处理得到相对应的信息

一.  gps.h文件:


#ifndef __GPS_H

#define __GPS_H

#include "delay.h"

#include "sys.h"

#include "usart.h"

extern u8 gps_buf[120]; //用来接收串口数据

extern u8 gps_i ;

enum gps_rece_state //串口数据的枚举类型

{

f_start, //帧开始

f_segment, //字段接收完

f_end,

f_out

};

extern enum gps_rece_state gps_state;

void send_gps(void);

void send_route(void);

void send_speed(void);

#endif

二. gps.c文件如下:

#include "gps.h"

#include "stm32f10x_usart.h"

#include "lcd.h"

#include "global.h"

#include "config.h"

#include "led.h"

#include "myfun.h"

#include "include.h"


//采集串口数据,并且读取得到GPS数据


u8 gps_buf[120] = {0}; //用来接收串口数据

u8 gps_i = 0;

u8 comma = 0;

u8 check_count = 0;

enum gps_rece_state gps_state;  //串口接收gps的状态

void get_gps(void);

//{

// f_start, //帧开始

// f_segment, //字段接收完

// f_end,

// f_out

//}


void USART3_IRQHandler(void)                 //串口1中断服务程序

{

u8 rec = 0,i;

if(USART_GetITStatus(USART3, USART_IT_RXNE) != RESET)

{

rec =USART_ReceiveData(USART3);

if(rec == '$') //如果是美元符,为起始

{

gps_state = f_start;

gps_i = 0;

comma = 0;

check_count = 0;

for(i=0;i<120;i++)

gps_buf[i] = 0;

}

else if(gps_state == f_start)  //开始接收

{

gps_buf[gps_i] = rec;

gps_i++;

if(rec == ',')

comma++;

if(comma == 12)

gps_state = f_segment;//还剩下四个字节校验值

}

else if(gps_state == f_segment)  //开始接收

{

gps_buf[gps_i] = rec;

gps_i++;   //此时的数组这个位置刚好没写

check_count++;

if(check_count == 4)

gps_state = f_end;

}

else if(gps_state == f_end)  //接收完成

{

#ifdef SHOW_GPS

LCD_Fill(0,0,239,50,WHITE);

LCD_ShowString(0,0,gps_buf);

#endif 

get_gps();


}



}

//从串口中得到GPS的数据和显示数据

//使用数组存逗号位置

u8 pos[13] = {0};

void get_gps(void)

{

u8 i,j = 0;

if((gps_buf[0]=='G')&&(gps_buf[1]=='P')&&(gps_buf[2]=='R')\

&&(gps_buf[3]=='M')&&(gps_buf[4]=='C'))

{

for(i = 5;i < gps_i;i++)

{

if(gps_buf[i] == ',')

pos[++j] = i;//第j个逗号在第i个位置

}

ori_data.status = gps_buf[pos[2]+1];

screen.status = gps_buf[pos[2]+1]; 

if(ori_data.status == 'A')

{

LED0 = 0;

for(i = pos[3]+1;i < pos[4];i++) //纬度

{

screen.lat[i-pos[3]-1] = gps_buf[i];

//

}

ori_data.lat = asc2f(screen.lat)/100;

screen.ns = gps_buf[pos[4]+1];

ori_data.ns = gps_buf[pos[4]+1];


for(i = pos[5]+1;i < pos[6];i++) //经度

screen.lon[i-pos[5]-1] = gps_buf[i];

ori_data.lon = asc2f(screen.lon)/100;

screen.ew = gps_buf[pos[6]+1];

ori_data.ew = gps_buf[pos[6]+1];


for(i = pos[7]+1;i < pos[8];i++) //地面速度

screen.speed[i-pos[7]-1] = gps_buf[i];

ori_data.speed = 0.5144 * asc2f(screen.speed);



for(i = pos[8]+1;i < pos[9];i++) //地面航向

screen.azimuth[i-pos[8]-1] = gps_buf[i];

ori_data.azimuth = asc2f(screen.azimuth);


for(i = pos[10]+1;i < pos[11];i++) //磁偏角 磁偏角方向

screen.declination[i-pos[10]-1] = gps_buf[i];

ori_data.declination = asc2f(screen.declination);


// for(i = pos[11]+1;i < pos[12];i++) //

if((pos[12] - pos[11]-1)!=0)

screen.dir_declination = gps_buf[pos[11]+1];

ori_data.dir_declination = screen.dir_declination;

}

else

{

LED0 = 1;

}

}

}


//发送GPS数据原始帧格式

void send_gps(void)

{

uint64_t time_now_us = time_nowUs();

float time_s = time_now_us* (1.0f/1e6f);


while(SCI_SendChar('I'));

SCISendInt(speed_east*100);


while(SCI_SendChar('|'));

SCISendInt(speed_north*100);

while(SCI_SendChar('|'));

SCISendInt(speed_hor*100);

while(SCI_SendChar('|'));

SCISendInt(0);


while(SCI_SendChar('|'));

SCISendInt(time_s*10);


while(SCI_SendChar('|'));

SCISendInt(0);


while(SCI_SendChar('\r'));

while(SCI_SendChar('\n'));


}


//发送数据,经纬度,速度等等


void send_speed(void)

{

uint64_t time_now_us = time_nowUs();

float time_s = time_now_us* (1.0f/1e6f);


u8 i;

while(SCI_SendChar('I'));

// double2asc(g_lat);

double2asc(ori_data.speed);

for(i = 1;asc_d[i]!=0;i++) //GPS

USART_SendChar(USART1,asc_d[i]);

while(SCI_SendChar('|'));

// double2asc(g_lon);

double2asc(speed_imu);

for(i = 1;asc_d[i]!=0;i++) //IMU

USART_SendChar(USART1,asc_d[i]);

while(SCI_SendChar('|'));

float2asc(speed_hor);

for(i = 1;((asc_f[i]!=0)&&(i<6));i++) //组合

USART_SendChar(USART1,asc_f[i]);


while(SCI_SendChar('|'));

float2asc(yaw_north);

for(i = 1;((asc_f[i]!=0)&&(i<6));i++) //航向

USART_SendChar(USART1,asc_f[i]);


while(SCI_SendChar('|'));

SCISendInt(time_s*10);

while(SCI_SendChar('|')); //定位状态

//if(ori_data.status == 'A')

if(pos_mode == 3)

USART_SendChar(USART1,'1');

else

USART_SendChar(USART1,'0');

while(SCI_SendChar('\r'));

while(SCI_SendChar('\n'));


}

//发送数据,经纬度,速度等等


void send_route(void)

{

uint64_t time_now_us = time_nowUs();

int time_s = (int)time_now_us* (1.0f/1e6f);


u8 i;

while(SCI_SendChar('I'));

double2asc(g_lat);

for(i = 1;asc_d[i]!=0;i++) //纬度

USART_SendChar(USART1,asc_d[i]);

while(SCI_SendChar('|'));

double2asc(g_lon);

for(i = 1;asc_d[i]!=0;i++) //经度

USART_SendChar(USART1,asc_d[i]);

while(SCI_SendChar('|'));

float2asc(speed_hor);

for(i = 1;((asc_f[i]!=0)&&(i<6));i++) //速度

USART_SendChar(USART1,asc_f[i]);


while(SCI_SendChar('|'));

float2asc(course);

for(i = 1;((asc_f[i]!=0)&&(i<6));i++) //航向

USART_SendChar(USART1,asc_f[i]);


while(SCI_SendChar('|'));

SCISendInt(time_s*10);

while(SCI_SendChar('|')); //定位状态

if(pos_mode == 3)

USART_SendChar(USART1,'1');

else

USART_SendChar(USART1,'0');

// if(ori_data.status == 'A')

// USART_SendChar(USART1,'1');

// else

// USART_SendChar(USART1,'0');

while(SCI_SendChar('\r'));

while(SCI_SendChar('\n'));

}

由于部分代码显示不全面,,可参考源代码下载地址:

链接:https://pan.baidu.com/s/1y7xDSfy2Ftv4p9PJRxCmSA 密码:1v7g

三、官方的解析NMEA数据的标准库文件的详细目录如下:

--------------------------------------------------------------

│  1.txt

│  CHANGELOG.TXT

│  LICENSE.TXT

│  Makefile

│  nmea.ico

│  nmea.sln

│  README.TXT

│  

├─build

├─doc

│      makefile

│      nmea.doxygen

│      

├─include

│  └─nmea

│          config.h

│          context.h

│          generate.h

│          generator.h

│          gmath.h

│          info.h

│          nmea.h

│          parse.h

│          parser.h

│          sentence.h

│          time.h

│          tok.h

│          units.h

│          

├─lib

├─samples

│  ├─generate

│  │      generate.vcproj

│  │      main.c

│  │      

│  ├─generator

│  │      generator.vcproj

│  │      main.c

│  │      

│  ├─math

│  │      main.c

│  │      math.vcproj

│  │      

│  ├─parse

│  │      main.c

│  │      parse.vcproj

│  │      

│  └─parse_file

│          gpslog.txt

│          main.c

│          parse_file.vcproj

│          

└─src

        context.c

        generate.c

        generator.c

        gmath.c

        info.c

        nmea.vcproj

        parse.c

        parser.c

        sentence.c

        time.c

        tok.c

--------------------------------------------------------------

主要提供各种GPS,数据的解析,使用C语言编写,可以解析GPGGA,GPRMC,GPZDA等等数据,方便移植到下位机当中

下载地址如下      :

链接:https://pan.baidu.com/s/1KM5y30wge4Im-2jfI7Ihfw密码:c0p2


关键字:stm32  单片机  串口接收 引用地址:stm32单片机串口接收GPS数据并解析NMEA之GPRMC

上一篇:关于stm32HardFault_Handler异常(死机)的处理
下一篇:STM32_在线调试查看硬件程序运行时间的两种方法

推荐阅读最新更新时间:2024-03-16 16:15

51单片机的内存映射(一)
本文主要讲述51单片机RAM部分的内存映射,其内存空间如下图所示: 51单片机内部有256个字节的RAM空间,低128个字节为工作寄存器组区(0x00H-0x1FH)、位寻址区(0x02H-0x2FH)、通用RAM区(0x30H-0x70H),SFR寄存区(0x80-0xFF)这段空间定义51单片机所有的控制寄存器和状态寄存器。下面我们就以上图中自底向上的顺序逐一介绍一下各区的功能以及访问方法。 工作寄存器区 工作寄存器区为R0-R7,它们各为1个字节,但51单片机一共有4组工作寄存器,单片机在工作过程中只能有一组工作寄存器工作。各个工作寄存器的地址以及工作寄存器组的选择如下图所示: 工作寄存器的功
[单片机]
51<font color='red'>单片机</font>的内存映射(一)
MCS-51系列单片机实现PWM输出功能的方法解析
MCS-51系列单片机无PWM输出功能,可以采用定时器配合软件的方法实现,对精度要求不高的场合是非常实用的。采用高速光隔6N137输出,并将PWM的信号倒相。 一、 工作原理 二、PWM输出 1. 固定脉宽PWM输出 用T0定时器完成PWM输出,脉宽固定为65536us。T0定时器设置成16位定时器,PWM波形如图2所示。 程序清单:(12MHz) PwmData0;T0定时t1的初值(字) PwmData1;T0定时t2的初值(字) PwmF ;PWM输出标志 ;*************************** setb tr0;启动T0 …… ;T0中断服务程序 T0Int:JB,PwmF,PWMOUT ;PWM
[单片机]
自学习循路的移动机器人模型设计与实现
    随着科学技术的不断发展,机器人技术在航天、海洋、军事、建筑、交通、工业及服务业等领域已取得广泛的应用和发展。而在一些特别场合(如航天、深海作业及核工业等领域),以无人探察车、无人排险车及无人运输车等为代表的机器人技术越来越受到关注。为此,笔者设计了一种具备道路记忆功能、使用灵活方便、应用范围较广的轮式移动机器人模型。 该机器人模型以微控制器MCU为核心,先由人对机器人模型按照所要行走的路线进行训练,即让机器人模型记忆该路线(将路线数据存储在存储器中)。以后机器人模型就可沿此路线重复行走。其记忆路线的方式灵活方便,可根据不同的需要和需要对其进行不同的路线训练以完成不同的任务。 该模型能够应用于一些人类不宜活动或较难控
[工业控制]
STM32中断与嵌套NVIC快速入门
简介:STM32 中断与嵌套NVIC 快速入门 //==================================================== // STM32 中断与嵌套NVIC 快速入门 // netjob 2008-8-1 //==================================================== STM32中断与嵌套NVIC快速入门 我也是靠看这本书才弄懂的: Cortex-M3 权威指南 Joseph Yiu 著 宋岩 译 其实很简单。 //CM3 有 最多240个中断(通常外部中断写作IRQs),就是 软件上说的 IRQ CHA
[单片机]
SimpleLinkTM 低功耗 Bluetooth® 无线 MCU支持阿里云Link物联网平台
在创新技术的推动下,智能锁、可穿戴设备等物联网应用已经成为时下、甚至是引领未来几年物联网快速发展的主流。 当您在进行这些物联网应用的开发时,是否也很头疼需要花费大量的时间在云端及低功耗蓝牙设备端的开发上? 是否想在节省时间的同时,便捷地获取更加强大的功能、稳定性和多重云端安全保障?德州仪器(TI)的 CC2640R2F 解决方案支持阿里云Link物联网平台,结合阿里云Link物联网平台旗下阿里智能APP SDK,帮助开发人员快速而安全的开发出产品,并保证产品的稳定性。 TI基于 CC2640R2F 的SDK提供一套例程来支持阿里云Link物联网平台。在这套方案里面,你可以使用阿里的profile, 它包含一系列的安全功
[物联网]
SimpleLinkTM 低功耗 Bluetooth® 无线 <font color='red'>MCU</font>支持阿里云Link物联网平台
基于单片机的等效采样示波器设计
  在数字示波器技术中,常用的采样方法有两种:实时采样和等效采样。实时采样通常是等时间间隔的,它的最高采样频率是奈奎斯特极限频率。等效采样(Equivalent Sampling)是指对多个信号周期连续样来复现一个信号波形,采样系统能以扩展的方式复现频率大大超过奈奎斯特极限频率的信号波形。   1 总体设计   由于所设计的示波器输入频率范围较宽,   本系统采用了等效和实时两种采样方式。若输入频率小于1.25MHz,选用实时采样;反之,选用等效采样。根据输入频率确定时钟芯片的输出及分频数。当输入频率高于1kHz时,利用可编程频率合成芯片SY89429V产生基准时钟;当输入频率小于1kHz时,由单片机提供40kHz的基准时
[测试测量]
基于<font color='red'>单片机</font>的等效采样示波器设计
单片机播放音乐的基本知识
用单片机播放音乐,或者弹奏电子琴,实际上是按照特定的频率,输出一连串的方波。为了输出合适的方波,首先应该知道音符与频率的关系。 1.音名 从常见的电子琴的键盘谈起。 在下表中,可以看到一列黑白相间的琴键(示意)。主要分成低音、中音和高音三个区域,每个区域都有12个琴键。其中的白键,简谱音符标为1、2、3、4、5、6、7,大家一般都读成哆、来、咪、发、嗦、拉、西。 2.频率 注意看一下几个6(拉)的频率,它们是整数,容易看出规律――是成2倍的关系。其它的音符,也有同样的规律。这些频率,如220、440等,它们在琴键上的位置是世界统一的,无论是钢琴、手风琴,还是电子琴,都是一样的。 包括黑键和白键在内的全部音符的频率数值,是成 等比数列
[单片机]
<font color='red'>单片机</font>播放音乐的基本知识
8051单片机供水系统水位控制的硬件电路设计
供水系统水位控制原理 下图是水塔水位控制原理图。图中虚线表示允许水位变化的上下限。在正常情况下,应保持水位在虚线范围之内,为此,在水塔的不同高度安装固定不动的三根金属棒,以感知水位变化情况。其中A棒处于下限水位以下,C棒处于上限水位,B棒在下限水位处。A棒接+5V电源,B棒、C棒各通过一个电阻与模拟地相连。 水塔由电机带动水泵供水,单片机控制电机转动以达到对水位控制的目的。供水时,水位上升,当达到上限时,由于水的导电作用,B棒、C棒连通+5V电源,因此,b、c两端均为高电平“1”状态。这时,应停止电机和水泵的工作,不再给水塔供水。 当水位降到下限时,B棒、C棒都不能与A棒导通,因此,b、c两端均为“0”状态。这时,应启动电机,
[单片机]
8051<font color='red'>单片机</font>供水系统水位控制的硬件电路设计
小广播
添点儿料...
无论热点新闻、行业分析、技术干货……
设计资源 培训 开发板 精华推荐

最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

换一换 更多 相关热搜器件
随便看看
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2024 EEWORLD.com.cn, Inc. All rights reserved