上篇博文已经说好怎么接线,然后将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上收到的数据,将数据发送给服务端,服务端将收到的数据进行解析,后将其打印到显示屏上如图左。