您的位置:首页 > 编程语言 > C语言/C++

C语言编程实现GPS定位信息的接受和显示

2014-09-06 12:22 447 查看
前面主要是在PC上操作串口,接受GPS天线传来的原始数字,下面是编程在用户层对接受到的信息进行处理和解析,有了前面的编写GPRS收发短信的经历,这次编写C程序接受和显示程序接容易多了。当然也参考和学习了网上别人的程序;

以下是实现的具体代码:

/*********************************************************************************

* Copyright: (C) 2014 liucehngdeng<1037398771@qq.com>

* All rights reserved.

*

* Filename: gps_test.c

* Description: This file

*

* Version: 0.0.0(09/04/2014~)

* Author: liu chengdeng <1037398771@qq.com>

* ChangeLog: 1, Release initial version on "09/04/2014 11:05:23 AM"

*

********************************************************************************/

#include<stdio.h>

#include<stdlib.h>

#include<string.h>

#include<sys/types.h>

#include<sys/stat.h>

#include<fcntl.h>

#include<unistd.h>

#include<termios.h>

#include<string.h>

#define BUF_SIZE 1024

typedef struct{

int year;

int month;

int day;

int hour;

int minute;

int second;

}date_time;

typedef struct{

date_time D;

char status;

double latitude;

double longitude;

char NS;

char EW;

double speed;

double high;

}GPS_INFO;

int open_dev(char *dev)

{

int fd = open( dev, O_RDWR| O_NDELAY ); //| O_NOCTTY | O_NDELAY

if (-1 == fd)

{

perror("Can't Open Serial Port !");

return -1;

}

else

return fd;

}

int init_serial(int fd,int nSpeed, int nBits, char nEvent, int nStop)

{

struct termios newtio,oldtio;

if(tcgetattr( fd,&oldtio) != 0) {

perror("SetupSerial 1");

return -1;

}

bzero( &newtio, sizeof( newtio ) );

newtio.c_cflag |= CLOCAL | CREAD;

newtio.c_cflag &= ~CSIZE;

switch( nBits )

{

case 7:

newtio.c_cflag |= CS7;

break;

case 8:

newtio.c_cflag |= CS8;

break;

}

switch( nEvent )

{

case 'O':

newtio.c_cflag |= PARENB;

newtio.c_cflag |= PARODD;

newtio.c_iflag |= (INPCK | ISTRIP);

break;

case 'E':

newtio.c_iflag |= (INPCK | ISTRIP);

newtio.c_cflag |= PARENB;

newtio.c_cflag &= ~PARODD;

break;

case 'N':

newtio.c_cflag &= ~PARENB;

break;

}

switch( nSpeed )

{

case 2400:

cfsetispeed(&newtio, B2400);

cfsetospeed(&newtio, B2400);

break;

case 4800:

cfsetispeed(&newtio, B4800);

cfsetospeed(&newtio, B4800);

break;

case 9600:

cfsetispeed(&newtio, B9600);

cfsetospeed(&newtio, B9600);

break;

case 115200:

cfsetispeed(&newtio, B115200);

cfsetospeed(&newtio, B115200);

break;

case 460800:

cfsetispeed(&newtio, B460800);

cfsetospeed(&newtio, B460800);

break;

default:

cfsetispeed(&newtio, B9600);

cfsetospeed(&newtio, B9600);

break;

}

if( nStop == 1 )

newtio.c_cflag &= ~CSTOPB;

else if ( nStop == 2 )

newtio.c_cflag |= CSTOPB;

newtio.c_cc[VTIME] = 0;//閲嶈

newtio.c_cc[VMIN] = 100;//杩斿洖鐨勬渶灏忓€? 閲嶈

tcflush(fd,TCIFLUSH);

if((tcsetattr(fd,TCSANOW,&newtio))!=0)

{

perror("com set error");

return -1;

}

return 0;

}

char * get_gprmc (char * buf)

{

char *buff=buf;

char *target="$GPRMC";

char *p=NULL;

if((p=strstr(buff,target))==NULL)

{

printf("No fonud the string GPRMC\n");

return 0;

}

return p;

}

char * get_gpgga (char * buf)

{

char *buff=buf;

char *target="$GPGGA";

char *p=NULL;

if((p=strstr(buff,target))==NULL)

{

printf("No fonud the string GPGGA\n");

return 0;

}

return p;

}

static int getcomma(int num,char *str)

{

int i,j=0;

int len=strlen(str);

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

{

if(str[i]==',')j++;

if(j==num)return i+1;

}

return 0;

}

static double get_double_number(char *s)

{

char buf[BUF_SIZE];

int i;

double rev;

i=getcomma(1,s);

strncpy(buf,s,i);

buf[i]=0;

rev=atof(buf);

return rev;

}

static void UTC2BTC(date_time *GPS)

{

//濡傛灉绉掑彿鍏堝嚭,鍐嶅嚭鏃堕棿鏁版嵁,鍒欏皢鏃堕棿鏁版嵁+1绉?

GPS->second++; //鍔犱竴绉?

if(GPS->second>59){

GPS->second=0;

GPS->minute++;

if(GPS->minute>59){

GPS->minute=0;

GPS->hour++;

}

}

GPS->hour+=8; //鍖椾含鏃堕棿璺烾TC鏃堕棿鐩搁殧8灏忔椂

if(GPS->hour>23)

{

GPS->hour-=24;

GPS->day+=1;

if(GPS->month==2 ||GPS->month==4 ||GPS->month==6 ||GPS->month==9 ||GPS->month==11 ){

if(GPS->day>30){ //涓婅堪鍑犱釜鏈堜唤鏄?0澶╂瘡鏈堬紝2鏈堜唤杩樹笉瓒?0

GPS->day=1;

GPS->month++;

}

}

else{

if(GPS->day>31){ //鍓╀笅鐨勫嚑涓湀浠介兘鏄?1澶╂瘡鏈?

GPS->day=1;

GPS->month++;

}

}

if(GPS->year % 4 == 0 ){

if(GPS->day > 29 && GPS->month ==2){ //闂板勾鐨勪簩鏈堟槸29澶?

GPS->day=1;

GPS->month++;

}

}

else{

if(GPS->day>28 &&GPS->month ==2){ //鍏朵粬鐨勪簩鏈堟槸28澶╂瘡鏈?

GPS->day=1;

GPS->month++;

}

}

if(GPS->month>12){

GPS->month-=12;

GPS->year++;

}

}

}

/*姝ゅ嚱鏁颁紶鍏ヤ袱涓瓧绗︿覆$GPRMC 锛?GPGGA鐨勯鍦板潃*/

void gps_parse(char *line1,char *line2,GPS_INFO *GPS)

{

int i,tmp,start,end;

char* buf=line1;

char* buff=line2;

GPS->D.hour =(buf[ 7]-'0')*10+(buf[ 8]-'0');

GPS->D.minute =(buf[ 9]-'0')*10+(buf[10]-'0');

GPS->D.second =(buf[11]-'0')*10+(buf[12]-'0');

tmp = getcomma(9,buf); //寰楀埌绗?涓€楀彿鐨勪笅涓€瀛楃搴忓彿

GPS->D.day =(buf[tmp+0]-'0')*10+(buf[tmp+1]-'0');

GPS->D.month =(buf[tmp+2]-'0')*10+(buf[tmp+3]-'0');

GPS->D.year =(buf[tmp+4]-'0')*10+(buf[tmp+5]-'0')+2000;

GPS->status =buf[getcomma(2,buf)]; //鐘舵€?

GPS->latitude =get_double_number(&buf[getcomma(3,buf)])/100; //绾害

GPS->NS =buf[getcomma(4,buf)]; //鍗楀寳绾?

GPS->longitude=get_double_number(&buf[getcomma(5,buf)])/100; //缁忓害

GPS->EW =buf[getcomma(6,buf)]; //涓滆タ缁?

UTC2BTC(&GPS->D); //杞寳浜椂闂?

GPS->high = get_double_number(&buff[getcomma(9,buff)]);

}

void show_gps(GPS_INFO *GPS)

{

printf("\n");

printf("DATE : %ld-%02d-%02d \n",GPS->D.year,GPS->D.month,GPS->D.day);

printf("TIME : %02d:%02d:%02d \n",GPS->D.hour,GPS->D.minute,GPS->D.second);

printf("Latitude : %4.4f %c\n",GPS->latitude,GPS->NS);

printf("Longitude: %4.4f %c\n",GPS->longitude,GPS->EW);

printf("high : %4.4f \n",GPS->high);

printf("STATUS : %c\n",GPS->status);

}

int main(void)

{

int fd,nset1,nread;

char buf[BUF_SIZE];

char *buff_gprmc,*buff_gpgga;

GPS_INFO GPS;

fd = open_dev("/dev/ttyS1");//鎵撳紑涓插彛

nset1 = init_serial(fd,4800, 8, 'N', 1);//璁剧疆涓插彛灞炴€?

if (nset1 == -1)

exit(1);

while(1)

{

sleep(2);

memset(buf,0,BUF_SIZE);

nread = read(fd, buf, BUF_SIZE);//璇讳覆鍙?

if (nread > 0)

{

printf("\nGPS DATALen=%d\n",nread);

buf[nread] = '\0';

printf( "GPS information as follow:\n\n%s\n", buf); //杈撳嚭鎵€璇绘暟鎹?

}

buff_gprmc=get_gprmc(buf);

buff_gpgga=get_gpgga(buf);

gps_parse(buff_gprmc,buff_gpgga,&GPS);

show_gps(&GPS) ;

}

close(fd);

return 0;

}

下面是在开发板上运行的结果:

[root@root /]# ./gps_info_test

GPS DATALen=598

GPS information as follow:

$GPGGA,043402.000,3029.6468,N,11423.6176,E,1,09,1.2,88.9,M,-13.7,M,,0000*41

$GPGSA,A,3,30,07,08,04,01,06,17,11,28,,,,2.2,1.2,1.8*3B

$GPRMC,043402.000,A,3029.6468,N,11423.6176,E,0.08,134.87,060914,,,A*63

$GPGGA,043403.000,3029.6468,N,11423.6176,E,1,09,1.2,89.0,M,-13.7,M,,0000*48

$GPGSA,A,3,30,07,08,04,01,06,17,11,28,,,,2.2,1.2,1.8*3B

$GPGSV,3,1,12,04,87,286,29,28,66,339,23,01,55,039,26,30,41,216,46*78

$GPGSV,3,2,12,17,39,298,22,20,38,126,29,11,34,046,30,32,25,076,16*75

$GPGSV,3,3,12,07,20,187,37,08,18,180,40,06,14,224,38,19,03,074,*7D

$GPRMC,043403.000,A,3029.6468,N,11423.6176,E,0.15,

DATE : 2014-09-06

TIME : 12:34:03

Latitude : 30.2965 N

Longitude: 114.2362 E

high : 88.9000

STATUS : A

GPS DATALen=434

GPS information as follow:

135.18,060914,,,A*69

$GPGGA,043404.000,3029.6468,N,11423.6176,E,1,09,1.2,89.1,M,-13.7,M,,0000*4E

$GPGSA,A,3,30,07,08,04,01,06,17,11,28,,,,2.2,1.2,1.8*3B

$GPRMC,043404.000,A,3029.6468,N,11423.6176,E,0.16,149.00,060914,,,A*6F

$GPGGA,043405.000,3029.6468,N,11423.6175,E,1,09,1.2,89.3,M,-13.7,M,,0000*4E

$GPGSA,A,3,30,07,08,04,01,06,17,11,28,,,,2.2,1.2,1.8*3B

$GPRMC,043405.000,A,3029.6468,N,11423.6175,E,0.05,113.40,060914,,,A*64

DATE : 2014-09-06

TIME : 12:34:05

Latitude : 30.2965 N

Longitude: 114.2362 E

high : 89.1000

STATUS : A

GPS DATALen=412

GPS information as follow:

$GPGGA,043406.000,3029.6468,N,11423.6175,E,1,09,1.2,89.3,M,-13.7,M,,0000*4D

$GPGSA,A,3,30,07,08,04,01,06,17,11,28,,,,2.2,1.2,1.8*3B

$GPRMC,043406.000,A,3029.6468,N,11423.6175,E,0.06,154.67,060914,,,A*62

$GPGGA,043407.000,3029.6467,N,11423.6175,E,1,09,1.2,89.5,M,-13.7,M,,0000*45

$GPGSA,A,3,30,07,08,04,01,06,17,11,28,,,,2.2,1.2,1.8*3B

$GPRMC,043407.000,A,3029.6467,N,11423.6175,E,0.12,137.48,060914,,,A*61

DATE : 2014-09-06

TIME : 12:34:07

Latitude : 30.2965 N

Longitude: 114.2362 E

high : 89.3000

STATUS : A
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: