FL2440--基于安信可A7模块实现GPS定位功能(接收数据,数据上报给服务端)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_38022615/article/details/81535869

上篇博文已经说好怎么接线,然后将USB 转串口接到FL2440的板子上,其串口为”ttyUSB0”,今天我们讲的是GPS定位功能数据上报解析,所以先不讲GPRS下的各种AT命令。今天只用到AT的两个指令。
AT+GPS=1 打开GPS
AT+GPS=0 关闭GPS
打开GPS后默认NEMA信息从GPS_TXD管脚以9600的波特率输出,若要让其数据从AT口输出,可用命令AT+GPSRD。
AT+GPSRD=0 关闭NEMA信息从AT口输出。
AT+GPSRD=n NEMA信息n秒从AT口输出一次。

FL2440上运行的程序

这个模块所需要的文件如图所示
这里写图片描述

串口模块就如前面博文所示 comport.c 和comport.h,
GPS_test是由makefile编译后产生的可执行文件,主要看的是socket_cilent.c文件
以下为socket_cilent.c的源码

/*********************************************************************************
 *      Copyright:  (C) 2018 NULL
 *                  All rights reserved.
 *
 *       Filename:  socket_server.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(2018年08月04日)
 *         Author:  DingHuanhuan <[email protected]>
 *      ChangeLog:  1, Release initial version on "2018年08月04日 19时18分17秒"
 *                 
 ********************************************************************************/


#include <string.h>
#include <stdlib.h>
#include <stdio.h>
/*  sockaddr_in{} and other Internet define */ 
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/*   strerror(),perror(), errno head file   */
#include <errno.h>


#include "comport.h"

#define  BUF_SIZE   1024
#define  Serv_IP    "192.168.0.5"
#define  port        12345
int main(int argc, char **argv)
{
    int                 sockfd  = -1;           //创建一个套接字
    struct sockaddr_in  serv_addr;//定义网络通信通用兼容的IPV4/IPV6结构体
    char                rec_buf[buf_size];
    char                send_buf[buf_size];
    char                *devname = "/dev/ttyUSB0";
    unsigned long       baudrate = 115200;
    COM_PORT            *comport;
    FILE *              fp;

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

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

    }

    printf("OPEN THE DEVICE\n");

    sockfd  =  socket(AF_INET,SOCK_STREAM,0);//创建一个套接字,IPV4面向TCP连接

    if(sockfd < 0)         //若创建套接字出错
    {
        printf("creat socket failure:%s\n",strerror(errno));
        goto finish;
    }

    printf("socket create fd is %d \n",sockfd); //打印套接字的文件描述符

    /* 连接服务器的准备,设置要连接的服务器的IP地址和端口号 */
    memset(&serv_addr,0,sizeof(serv_addr));//清空处理网络通信的地址的结构体
    serv_addr.sin_family = AF_INET;        //设置为IPV4地址
    serv_addr.sin_port   = htons(port);    //端口号,主机字节序转网络字节序
    //inet_aton(Serv_IP,&serv_addr.sin_addr);//把字符串IP地址转换为一个32位网络序列IP地址
    //printf ("设置 IP地址端口号成功\n");

    if(inet_pton(AF_INET, Serv_IP, &serv_addr.sin_addr) <=0)
    {
        printf("inet_pton error for %s\n",strerror(errno));
        goto finish;
    }
    printf("inet_pton : %s\n",Serv_IP); 
    /* 连接服务端 */
    if(connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr))<0)
    {
        printf("connect to the server failure:%s\n",strerror(errno));
        goto finish;
    }

    /*使能GPS接收数据功能并用AT口输出*/
    memset(send_buf,0,sizeof(send_buf));
    strcpy(send_buf,"AT+GPS=1\r\n");
    if(write(comport->fd,send_buf,strlen(send_buf))<0)
    {   
        printf("write error:%s\n",strerror(errno));
        goto finish;
    }   
    sleep(1);
    printf("send_buf: %s\n",send_buf);
    memset(send_buf,0,sizeof(send_buf));
    strcpy(send_buf,"AT+GPSRD=2\r\n");
    if(write(comport->fd,send_buf,strlen(send_buf))<0)
    {   
        printf("write error:%s\n",strerror(errno));
        goto finish;
    }   
    sleep(1);
    printf("send_buf: %s\n",send_buf);
    fp  =  fdopen(comport->fd,"r+");
    while(1)
    {

        memset(rec_buf,0,sizeof(rec_buf));
        if(NULL == fp)
        {
            printf("fdopen failed!:%s\n",strerror(errno));
            goto finish;
        }
        while(NULL !=  fgets(rec_buf,sizeof(rec_buf),fp))
        {
            printf("%s",rec_buf);
            usleep(20000);
            if(send(sockfd,rec_buf,strlen(rec_buf),0)<0)
            {
                printf ("socket send failure :%s\n",strerror(errno));
                goto finish;
            }
        }
    }





finish:
    close(sockfd);
    close(comport->fd);
    free(comport);
    return 0;
}

其中这段代码的意思是:通过串口向安信可A7发送:”AT+GPS=1\r\n” 打开GPS,延时1s,再次向串口发送“AT+GPSRD=2”将GPS信息每隔2s从AT口输出一次。

    memset(send_buf,0,sizeof(send_buf));
    strcpy(send_buf,"AT+GPS=1\r\n");
    if(write(comport->fd,send_buf,strlen(send_buf))<0)
    {   
        printf("write error:%s\n",strerror(errno));
        goto finish;
    }   
    sleep(1);
    printf("send_buf: %s\n",send_buf);
    memset(send_buf,0,sizeof(send_buf));
    strcpy(send_buf,"AT+GPSRD=2\r\n");
    if(write(comport->fd,send_buf,strlen(send_buf))<0)
    {   
        printf("write error:%s\n",strerror(errno));
        goto finish;
    }   
    sleep(1);
    printf("send_buf: %s\n",send_buf);

编译源码

#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 = GPS_test

CROSS_COMPILE=/opt/xtools/arm920t/bin/arm-linux-
export CC=${CROSS_COMPILE}gcc -Wall
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

在Centos上打make命令编译生成GPS_test的可执行文件。可以敲命令file看下GPS_test文件类型

[dinghuanhuan@centos6 GPS]$>make
/opt/xtools/arm920t/bin/arm-linux-gcc -Wall    -c -o comport.o comport.c
/opt/xtools/arm920t/bin/arm-linux-gcc -Wall    -c -o socket_cilent.o socket_cilent.c
[dinghuanhuan@centos6 GPS]$>file GPS_test 
GPS_test: ELF 32-bit LSB executable, ARM, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.16, not stripped

将可执行文件GPS_test发送至windows下,打开tftpd32.exe,后登录FL2440上,通过命令tftp -gr GPS_test 192.168.0.192,即可得到GPS_test文件,而后执行命令chmod a+x GPS_test,给文件执行的权限。

服务器运行的程序

文件如图所示
这里写图片描述
gps.c 和gps.h文件在前面博文已经介绍了,可以看前面的博文
这边的socket_server.c文件如下

/*********************************************************************************
 *      Copyright:  (C) 2018 NULL
 *                  All rights reserved.
 *
 *       Filename:  socket_server.c
 *    Description:  This file 
 *                 
 *        Version:  1.0.0(2018年08月05日)
 *         Author:  DingHuanhuan <[email protected]>
 *      ChangeLog:  1, Release initial version on "2018年08月05日 19时30分27秒"
 *                 
 ********************************************************************************/


#include "gps.h"


#include <string.h>
#include <stdlib.h>
#include <stdio.h>

/*   sockaddr_in{} and other Internet define */ 
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
/*    strerror(),perror(), errno head file   */
#include <errno.h>  

#define  BUF_SIZE    1024
#define  port        12345

int main(int argc, char **argv)
{
    int        listen_fd,accept_fd;    //创建两个套接字,一个开启连接,一个通信
    struct     sockaddr_in    server_addr;//服务器端地址,是一个结构体,等下要填充ipV4或者ipV6的结构
    char       buf[BUF_SIZE];
    GPRMC      gprmc_data;
    listen_fd = socket(AF_INET,SOCK_STREAM,0);
    if(listen_fd < 0)
    {
        printf("Creat socket failure:%s\n",strerror(errno));
        return -1;
    }
    printf("Socket creat fd is %d\n",listen_fd);

    /*服务器设置,设置server地址和端口号,用于接受任何client端*/
    memset(&server_addr,0,sizeof(server_addr));       //清空再设置ipV4地址
    server_addr.sin_family = AF_INET;                //设置为ipV4地址
    server_addr.sin_port = htons(port);             //端口号,主机字节序转网络字节序,short是16位
    server_addr.sin_addr.s_addr = htonl(INADDR_ANY); //设置host主机地址
    if(bind(listen_fd,(struct sockaddr *)&server_addr,sizeof(server_addr))<0)
    {
        printf("Bind socket failure %s\n",strerror(errno));
        return -2;
    }
    printf("socket bind ok\n");

    listen(listen_fd,15);//等待连接,最大连接数设为15
    printf("socket listen ok\n");
    printf("Start accept %d\n",listen_fd);
    accept_fd = accept(listen_fd,NULL,NULL);
    //accept接受的参数必须经过listen和bing处理过,返回一个新的socket码
    //新的socket传送数据,旧的socket还能继续用accept接受请
    //后面两个参数设置为NULL,那么会在系统连接时自动根据客户端信息填入

    if(accept_fd <0)
    {
        printf("Listen socket failure: %s\n", strerror(errno));  //如果监听失败,打印错误信息
        return -3;
    }
    printf("socked accept fd is %d\n",accept_fd);


    while(1)
    {
        sleep(2);
        memset(buf,0,BUF_SIZE);
        if(recv(accept_fd,buf, BUF_SIZE,0)<0)
        {
           printf("recv failure:%s\n",strerror(errno));
           return -4;
        }
         //printf("gps_buff: %s\n",buf);
         memset(&gprmc_data,0,sizeof(gprmc_data));

         Analyse_GPRMC(buf,&gprmc_data);
         Print_GPRMC(&gprmc_data);


    }
    close(accept_fd);
    close(listen_fd);


    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 = server

export CC=gcc

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

生成可执行文件server,运行其程序

实物连接图

这里写图片描述

现象图

这里写图片描述
图右为FL2440上收到的数据,将数据发送给服务端,服务端将收到的数据进行解析,后将其打印到显示屏上如图左。

猜你喜欢

转载自blog.csdn.net/m0_38022615/article/details/81535869