程序主要实现对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'));

}

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

三、官方的解析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等等数据,方便移植到下位机当中

下载地址如下      :

gps串口通信程序c语言,stm32单片机串口接收GPS数据并解析NMEA之GPRMC相关推荐

  1. 基于matlab的串口通信,基于Matlab GUI的单片机串口与PC的通信 附源码

    我也是最近学习单片机和MATLAB的小白平时在看学习的时候 下载了一些有价值的参考文献 概述采用51单片机,atmel的STC89C52RC芯片,主要用到的是七段数码管用来做一个时钟,程序编写软件为k ...

  2. 在Arduino 完成STM32板子的串口通信程序

    文章目录 要求 一.软件安装 二.编译及烧录 三.结果 四.标准库函数与HAL库函数的stm32编程方式差异 五.国人版的MCU集成开发平台 要求 安装 Ardunio IDE 和相关软件支持库,在A ...

  3. java调用c 串口_基于C语言的java串口通信程序

    目录 1.前言 2.windows  串口通信API 3.C/C++封装  动态运行库 4.JAVA-JNI  java程序调用C++程序 一.前言 &ensp ;写这个博客主要是因为自己想用 ...

  4. stm32单片机通过串口通信实现将GY_33颜色传感器的接收到的颜色和RGB值上传给上位机

    目录 硬件连接 实现串口1和串口3相互通信 GY_33的概述 对GY_33的数据分析 GY_33数据处理 GY_33的配套软件使用 代码 主要思路:注:这里我使用串口1和串口3,可以更改串口     ...

  5. STC15F2K60S2单片机的串口通信程序及相关知识

    一.STC15F2K60S2单片机简介 中国深圳宏晶STC系列单片机是2005年推出中国本土的第一款具有全球竞争力的,且与MCS-51兼容的STC系列单片机.它完全兼容51单片机,是新一代增强型单片机 ...

  6. STM32串口通信代码、ASCII码、XU4串口通信,printf只会转换为无符号类型,linux下的串口通信程序

    1.其里面的的通信协议是是自己定的,这里 是检测到数据的结尾是以0x0d.0x0a结尾,则表示接受的数据完成了,这个数据是我想要的,这样子就不会出现一些错乱的数据信息.其中的0x8000.0x4000 ...

  7. qt linux 串口eventdriven,详解 Qt 串口通信程序全程图文 (1)

    Qt 串口通信程序全程图文 是本文介绍的内容,在Qt中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也是使用的该类.我们可以去 http://sourc ...

  8. 详解 Qt 串口通信程序全程图文 (3)

    Qt 串口通信程序全程图文是本文要介绍的内容,下面的程序在第一部分中所写的程序上进行了一些改进.加入打开和关闭串口,发送数据等功能. 1.加入了"打开串口","关闭串口& ...

  9. 详解 Qt 串口通信程序全程图文 (1)

    Qt 串口通信程序全程图文 是本文介绍的内容,在Qt中并没有特定的串口控制类,现在大部分人使用的是第三方写的qextserialport类,我们这里也是使用的该类.我们可以去 http://sourc ...

  10. QT中串口通信程序(转)

    (说明:我们的编程环境是windows xp下,在Qt Creator中进行,如果在Linux下或直接用源码编写,程序稍有不同,请自己改动.) 在Qt中并没有特定的串口控制类,现在大部分人使用的是第三 ...

最新文章

  1. linux下载github中的文件git, wget
  2. 下拉菜单显示 隐藏html,根据在下拉列表中选择的内容隐藏和显示HTML元素
  3. 124. Leetcode 583. 两个字符串的删除操作 (动态规划- 字符串系列)
  4. OpenCV梯度直方图HOG的实例(附完整代码)
  5. vue3 echarts5 graph关系图谱 点击图例节点消失线不消失重复生成问题
  6. (进阶篇)Redis6.2.0 集群 主从复制_故障解决_03
  7. 数据库零碎要点001_数据库的4大特性(原子性_持久性_隔离性_一致性)_数据库的隔离级别(脏读_幻读_不可重复读)_mysql如何设置隔离级别
  8. U3D NGUI改变GameObject Activity闪烁的问题
  9. 已解决:TeamViewer使用的设备数量上限
  10. reflection java_Java Reflection (JAVA反射)
  11. MFC模态对话与非模态对话框(二)
  12. deepin linux字体设置,在deepin系统中如何安装系统字体? - Deepin深度系统用户手册...
  13. 微信小程序与公众号区别PHP,微信小程序和微信公众号的区别是什么?
  14. Web全栈开发1+x(中级)PHPMySQL知识
  15. OpenAI 宣布将对战 DOTA2 世界冠军 OG,最终决战!
  16. 高通导航器软件开发包使用指南(13)
  17. DNF40级冒险团与角色升级经验计算代码
  18. 计算机组成原理STRA检测程序,计算机组成原理实验4-微程序控制器课件.ppt
  19. lu分解 matlab课件,LU分解与部分旋转Matlab
  20. 夜游项目如何讲好文化故事

热门文章

  1. 配合字体图标的搜索框
  2. Java多线程系列--“JUC线程池”03之 线程池原理——线程池源码分析
  3. MTK6580适应小分辨率
  4. win系统连接交换机并设置固定ip地址
  5. git 拉取最新代码
  6. Python Opencv 简单视频裁剪功能的实现
  7. python-生成xlsx表格
  8. cite、q、blockquote之间的区别
  9. 解决microsoft store需要联网 你似乎没有联网
  10. Java程序员面试分类真题(后附答案解析)