FL2440——基于SF2820模块编程实现GPS定位功能

上两篇博文整理学习了有关串口通信、串口编程以及GPS数据格式的一些基本知识。本篇我们要开始编程实现GPS自动定位数据解析。我们将在FL2440开发板上实现该功能。

由于SF2820模块获取到的GPS定位信息是通过串口发送到终端设备,我们在编程实现获取GPS定位信息中自然涉及到串口编程。

串口编程

前面博文已经介绍的很详细,代码也参考前面串口模块。只需要串口模块的头文件与源码。

串口设置其实就相当于串口通信的协议,我们通过程序设置下面的内容(这些值的设置见main函数)
波特率:是为了两者信号流能同步,
数据位:是指又几位数据封装成一帧
结束位:是指以帧传输数据时,协定好结束位,便于提取有效数据
奇偶校验:检验数据的一种手段

编程获取和解析GPS定位信息

头文件(gps.h)

/********************************************************************************
 *      Copyright:  (C) 2018 NULL
 *                  All rights reserved.
 *
 *       Filename:  gps.h
 *    Description:  This head file 
 *
 *        Version:  1.0.0(2018年07月31日)
 *         Author:  DingHuanhuan <[email protected]>
 *      ChangeLog:  1, Release initial version on "2018年07月31日 14时13分55秒"
 *                 
 ********************************************************************************/

#ifndef _GPS_H
#define _GPS_H

#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>



typedef struct _GP_RMC
{
  unsigned int    Time;  /*UTC Time  :hhmmss */
  char            Pos_status;           //定位状态
  float           latitude;             //纬度
  char            lati_hemisphere;      //纬度半球 
  float           longitude;            //经度
  char            longi_hemisphere;     //经度半球
  float           speed;                //移动速度
  float           direction;            //方向
  unsigned int    data;                 //日期
  float           Magnetic_declination; //磁偏角
  char            M_dd;                 //磁偏角方向
  char            mode;                  //模式
}GPRMC; 


int Analyse_GPRMC(char *buff, GPRMC *gprmc_data);
int Print_GPRMC(GPRMC *gprmc_data);


#endif

gps数据分析gps.c
在gps.c文件中有两个函数Analyse_GPRMC 和 Print_GPRMC ,分别实现对gps返回的数据进行分析处理和打印到标准输出。

/*********************************************************************************
 *      Copyright:  (C) 2018 NULL
 *                  All rights reserved.
 *
 *       Filename:  gps.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(2018年07月31日)
 *         Author:  DingHuanhuan <[email protected]>
 *      ChangeLog:  1, Release initial version on "2018年07月31日 14时37分56秒"
 *                 
 ********************************************************************************/

#include "gps.h"

int Analyse_GPRMC(char *buff, GPRMC *gprmc_data)
{
    char *ptr = NULL;
    if(NULL == gprmc_data)
      return -1;

    if(strlen(buff) < 10)
        return -2;

    ptr = strstr(buff,"$GPRMC");

    if(NULL == ptr)
        return -3;

    /* Assign values to structures   */
    sscanf(ptr, "$GPRMC,%d.000,%c,%f,%c,%f,%c,%f,%f,%d,,,%c*",&(gprmc_data->Time),&(gprmc_data->Pos_status),&(gprmc_data->latitude),&(gprmc_data->lati_hemisphere),&(gprmc_data->longitude),&(gprmc_data->longi_hemisphere),&(gprmc_data->speed),&(gprmc_data->direction),&(gprmc_data->data),&(gprmc_data->mode));
  printf("DATA analyse is ok!\n");
  printf("ptr:%s\n",ptr);
  return 0;

}

int Print_GPRMC(GPRMC *gprmc_data)
{
    printf("                                                       \n");
    printf("                                                       \n");
    printf("                                                       \n");
    printf("=======================================================\n");
    printf("=======================================================\n");
    printf("****         Global GPS positioning module         ****\n");
    printf("****            Author:dinghuanhuan                ****\n");
    printf("****            E_mail:[email protected]            ****\n");
    printf("****            GPS model:FIT-GPS-SF2820           ****\n");
    printf("****            MCU model:FL2440                   ****\n");
    printf("=======================================================\n");
    printf("=======================================================\n");
    printf("****      定位状态:%c [A有效定位;V无效定位]         ****\n",gprmc_data->Pos_status);
    printf("****      模式指示: %c [A自主定位;D差分定位]        ****\n",gprmc_data->mode);
    printf("****      UTC日期:  20%02d-%02d-%02d                    ****\n",gprmc_data->data%100,
            (gprmc_data->data%10000)/100,(gprmc_data->data/10000));
    printf("****      UTC时间:  %02d:%02d:%02d                      ****\n", (gprmc_data->Time/10000+8)%24,
            (gprmc_data->Time%10000)/100,(gprmc_data->Time%100));
    printf("****      维度:    %c维 %d度%d分%d秒              ****\n",
            gprmc_data->lati_hemisphere, ((int)gprmc_data->latitude)/100,
            (int)(gprmc_data->latitude - ((int)gprmc_data->latitude / 100 * 100)),
            (int)(((gprmc_data->latitude - ((int)gprmc_data->latitude / 100 * 100)) 
            - ((int)gprmc_data->latitude - ((int)gprmc_data->latitude / 100 * 100)))*60.0));
    printf("****      经度:    %c经 %d度%d分%d秒             ****\n", 
            gprmc_data->longi_hemisphere,((int)gprmc_data->longitude)/100,
            (int)(gprmc_data->longitude - ((int)gprmc_data->longitude / 100 * 100)),
            (int)(((gprmc_data->longitude - ((int)gprmc_data->longitude / 100 * 100)) 
            - ((int)gprmc_data->longitude - ((int)gprmc_data->longitude / 100 * 100)))*60.0));

    printf("****      地面速度:%.5f  m/s                  ****\n",gprmc_data->speed);
    printf("                                                       \n");
    printf("=======================================================\n");
    printf("=======================================================\n");

    return 0;
}

对于字段的分析,在上篇博文已经解读,不过我们要把数据转化一下,方便我们记录和识别。
1. 时间,这个是格林威治时间即世界时间(UTC),把它转换成我们用的北京时间(BTC),在这个时间基础上加8个小时。
2. 经纬度,GPRMC返回的纬度数据位ddmm.mmmm格式即度分格式,我们把它转换成常见的度分秒的格式,计算方法:如接收到的纬度是:3029.60430
3029.60430/100=30.2960430可以直接读出30度, 3029.60430–30*100=29.60430, 可以直接读出29分
(29.60430–29)*60 =0.60430*60=36.258读出36秒, 所以纬度是:30度29分36秒。
3. 南北纬东西经,N:北纬。S:南纬。E:东经。W:西经。
4. 速率,GPRMC返回的速率值是海里/时,单位是节,把它转换成千米/时,换算为:1海里=1.85公里,把得到的速率乘以1.85。
5. 航向,指的是偏离正北的角度
6. 日期,GPRMC的日期格式为:ddmmyy,如:040617表示2017年06月04日,这个日期是准确的,不需要转换。

main函数

/*********************************************************************************
 *      Copyright:  (C) 2018 NULL
 *                  All rights reserved.
 *
 *       Filename:  main.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(2018年07月31日)
 *         Author:  DingHuanhuan <[email protected]>
 *      ChangeLog:  1, Release initial version on "2018年07月31日 14时10分09秒"
 *                 
 ********************************************************************************/
#include "comport.h"
#include "gps.h"

int main(int argc,char **argv)
{
    char             *devname = "/dev/ttyS1";
    unsigned long      baudrate = 4800;
    COM_PORT *comport;
    GPRMC  gprmc_data;
    char buff[buff_size];
    int read_fd = 0;

    comport = Comport_Init(devname, baudrate, "8N1");
    if(NULL == comport)
    {   
        printf("init serial port failure\n");
        return -1;                           
    }   

    Comport_open(comport);
    if(comport->fd <0)
    {
         printf("open error :%s\n",strerror(errno)); 
         exit(1);
    }

    printf("OPEN THE DEVICE\n");
    while(1)
    {
        sleep(3);
        read_fd = read(comport->fd,buff,sizeof(buff));
        if(read_fd < 0)
        {
            printf("read GPRMC data error\n");
            return -2;
        }

        printf("gps_buff: %s\n",buff);
        memset(&gprmc_data,0,sizeof(gprmc_data));

        Analyse_GPRMC(buff,&gprmc_data);

        Print_GPRMC(&gprmc_data);
    }
    close(comport->fd);
    free(comport);
    return 0;
}

接下来用Makefile编译

#This Makefile used to call function to compile all the C source in current folder and links all the objects file into a excutable binary file.  

PWD=$(shell pwd)

prom = comport

CROSS_COMPILE=/opt/xtools/arm920t/bin/arm-linux-
export CC=${CROSS_COMPILE}gcc
export CXX=${CROSS_COMPILE}g++
export AR=${CROSS_COMPILE}ar
export AS=${CROSS_COMPILE}as
export RANLIB=${CROSS_COMPILE}ranlib
export STRIP=${CROSS_COMPILE}strip


VPATH= .
SRCS = $(wildcard ${VPATH}/*.c)
DEPS = $(shell find ${VPATH}/*.h)
OBJS = $(patsubst %.c,%.o,$(SRCS))


$(prom): $(OBJS)
    @$(CC) -o $(prom) $(OBJS)
    @rm -rf *.o
clean:
    @rm -rf *.o

将编译生成的comport下载到开发板,(给其运行权限)运行测试

这里写图片描述

猜你喜欢

转载自blog.csdn.net/m0_38022615/article/details/81386652
今日推荐