本章介绍一个额外的扩展模块:GPS定位模块,借助该模块我们可以实现小车的地理位置定位的功能。
使用从淘宝上淘得一个GPS模块,拿来测试一下:
下面直接贴一下关键的代码实现,仅供参考:
get_gps_msg.c:获取GPS数据:
#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>
struct GPS_INFO{
char status;
double latitude;
double longtitude;
}gps;
int set_opt(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] = 0;
tcflush(fd,TCIFLUSH);
if((tcsetattr(fd,TCSANOW,&newtio))!=0)
{
perror("com set error");
return -1;
}
printf("set done!\n\r");
return 0;
}
double get_locate(double temp)
{
int m;
double n;
m=(int)temp/100;
n=(temp-m*100)/60;
n=n+m;
return n;
}
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;
}
double get_double_number(char *s)
{
char buf[128];
int i;
double rev;
i=GetComma(1,s);
strncpy(buf,s,i);
buf[i]=0;
rev=atof(buf);
return rev;
}
void gps_parse(char buf[],int n)
{
int tmp;
char c;
c = buf[5];
if(c=='C')
{
//"GPRMC"
gps.status = buf[GetComma(2,buf)];
gps.latitude = get_locate(get_double_number(&buf[GetComma(3,buf)]));
//gps.NS = buf[GetComma(4,buf)];
gps.longtitude= get_locate(get_double_number(&buf[GetComma(5,buf)]));
//gps.EW = buf[GetComma(6,buf)];
}
}
struct GPS_INFO get_gps(void)
{
int fd,nset1,nread;
char buf[1024];
//int i;
fd = open("/dev/ttyACM0", O_RDWR|O_NONBLOCK);
if (fd == -1)
{
printf("Cannot open gps device\n");
close(fd);
exit(1);
}
nset1 = set_opt(fd,9600, 8, 'N', 1);
if (nset1 == -1)
exit(1);
while (1)
//for(i=0;i<3;i++)
{
memset(buf,0,1024);
nread = read(fd, buf, 1024);
if (nread > 0)
{
buf[nread] = '\0';
gps_parse(buf,1024);
if(gps.status=='A')
{
printf("%f %f\n",gps.latitude,gps.longtitude);
return gps;
}
/* printf("\nDATALen=%d\n",nread);
printf( "GPS %s\n", buf); */
}
sleep(2);
}
close(fd);
//return 0;
}
GPS_modular.c:GPS模块信息
1 /*
2 ============================================================================
3 Name : GPS_modular.c
4 Author : Lou
5 Version :
6 Copyright : copyright reserved
7 Description : Hello World in C, Ansi-style
8 ============================================================================
9 */
10 #include<stdio.h>
11 #include<stdlib.h>
12 #include<string.h>
13 #include<sys/types.h>
14 #include<sys/stat.h>
15 #include<fcntl.h>
16 #include<unistd.h>
17 #include<termios.h>
18
19 struct GPS_INFO{
20 char status;
21 double latitude;
22 double longtitude;
23 }gps;
24 int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
25 {
26 struct termios newtio,oldtio;
27 if ( tcgetattr( fd,&oldtio) != 0) {
28 perror("SetupSerial 1");
29 return -1;
30 }
31 bzero( &newtio, sizeof( newtio ) );
32 newtio.c_cflag |= CLOCAL | CREAD;
33 newtio.c_cflag &= ~CSIZE;
34
35 switch( nBits )
36 {
37 case 7:
38 newtio.c_cflag |= CS7;
39 break;
40 case 8:
41 newtio.c_cflag |= CS8;
42 break;
43 }
44
45 switch( nEvent )
46 {
47 case 'O':
48 newtio.c_cflag |= PARENB;
49 newtio.c_cflag |= PARODD;
50 newtio.c_iflag |= (INPCK | ISTRIP);
51 break;
52 case 'E':
53 newtio.c_iflag |= (INPCK | ISTRIP);
54 newtio.c_cflag |= PARENB;
55 newtio.c_cflag &= ~PARODD;
56 break;
57 case 'N':
58 newtio.c_cflag &= ~PARENB;
59 break;
60 }
61
62 switch( nSpeed )
63 {
64 case 2400:
65 cfsetispeed(&newtio, B2400);
66 cfsetospeed(&newtio, B2400);
67 break;
68 case 4800:
69 cfsetispeed(&newtio, B4800);
70 cfsetospeed(&newtio, B4800);
71 break;
72 case 9600:
73 cfsetispeed(&newtio, B9600);
74 cfsetospeed(&newtio, B9600);
75 break;
76 case 115200:
77 cfsetispeed(&newtio, B115200);
78 cfsetospeed(&newtio, B115200);
79 break;
80 case 460800:
81 cfsetispeed(&newtio, B460800);
82 cfsetospeed(&newtio, B460800);
83 break;
84 default:
85 cfsetispeed(&newtio, B9600);
86 cfsetospeed(&newtio, B9600);
87 break;
88 }
89 if( nStop == 1 )
90 newtio.c_cflag &= ~CSTOPB;
91 else if ( nStop == 2 )
92 newtio.c_cflag |= CSTOPB;
93 newtio.c_cc[VTIME] = 0;
94 newtio.c_cc[VMIN] = 0;
95 tcflush(fd,TCIFLUSH);
96 if((tcsetattr(fd,TCSANOW,&newtio))!=0)
97 {
98 perror("com set error");
99 return -1;
100 }
101 printf("set done!\n\r");
102 return 0;
103 }
104
105
106 double get_locate(double temp)
107 {
108 int m;
109 double n;
110 m=(int)temp/100;
111 n=(temp-m*100)/60;
112 n=n+m;
113 return n;
114 }
115
116
117 int GetComma(int num,char *str)
118 {
119 int i,j=0;
120 int len=strlen(str);
121 for(i=0;i<len;i++)
122 {
123 if(str[i]==',')
124 {
125 j++;
126 }
127
128 if(j==num)
129 return i+1;
130 }
131 return 0;
132 }
133
134 double get_double_number(char *s)
135 {
136 char buf[128];
137 int i;
138 double rev;
139 i=GetComma(1,s);
140 strncpy(buf,s,i);
141 buf[i]=0;
142 rev=atof(buf);
143 return rev;
144 }
145
146 void gps_parse(char buf[],int n)
147 {
148 int tmp;
149 char c;
150 c = buf[5];
151 if(c=='C')
152 {
153 //"GPRMC"
154 gps.status = buf[GetComma(2,buf)];
155 gps.latitude = get_locate(get_double_number(&buf[GetComma(3,buf)]));
156 //gps.NS = buf[GetComma(4,buf)];
157 gps.longtitude= get_locate(get_double_number(&buf[GetComma(5,buf)]));
158 //gps.EW = buf[GetComma(6,buf)];
159 }
160 }
161
162 struct GPS_INFO get_gps(void)
163 {
164 int fd,nset1,nread;
165 char buf[1024];
166 //int i;
167 fd = open("/dev/ttyACM0", O_RDWR|O_NONBLOCK);
168 if (fd == -1)
169 {
170 printf("Cannot open gps device\n");
171 close(fd);
172 exit(1);
173 }
174 nset1 = set_opt(fd,9600, 8, 'N', 1);
175 if (nset1 == -1)
176 exit(1);
177 while (1)
178 //for(i=0;i<3;i++)
179 {
180 memset(buf,0,1024);
181 nread = read(fd, buf, 1024);
182 if (nread > 0)
183 {
184 buf[nread] = '\0';
185 gps_parse(buf,1024);
186 if(gps.status=='A')
187 {
188 printf("%f %f\n",gps.latitude,gps.longtitude);
189 return gps;
190 }
191 /* printf("\nDATALen=%d\n",nread);
192 printf( "GPS %s\n", buf); */
193 }
194 sleep(2);
195 }
196 close(fd);
197 //return 0;
198 }
199
200 int main(void) {
201
202 gps=get_gps();
203 printf("%lf\n,%lf\n",gps.latitude,gps.longtitude);
204 return 0;
205 }
GPS.c:GPS定义
1 #include<stdio.h>
2 #include<stdlib.h>
3 #include<string.h>
4 #include<sys/types.h>
5 #include<sys/stat.h>
6 #include<fcntl.h>
7 #include<unistd.h>
8 #include<termios.h>
9 #include<string.h>
10
11 int set_opt(int fd,int nSpeed, int nBits, char nEvent, int nStop)
12 {
13 struct termios newtio,oldtio;
14 if ( tcgetattr( fd,&oldtio) != 0) {
15 perror("SetupSerial 1");
16 return -1;
17 }
18 bzero( &newtio, sizeof( newtio ) );
19 newtio.c_cflag |= CLOCAL | CREAD;
20 newtio.c_cflag &= ~CSIZE;
21
22 switch( nBits )
23 {
24 case 7:
25 newtio.c_cflag |= CS7;
26 break;
27 case 8:
28 newtio.c_cflag |= CS8;
29 break;
30 }
31
32 switch( nEvent )
33 {
34 case 'O':
35 newtio.c_cflag |= PARENB;
36 newtio.c_cflag |= PARODD;
37 newtio.c_iflag |= (INPCK | ISTRIP);
38 break;
39 case 'E':
40 newtio.c_iflag |= (INPCK | ISTRIP);
41 newtio.c_cflag |= PARENB;
42 newtio.c_cflag &= ~PARODD;
43 break;
44 case 'N':
45 newtio.c_cflag &= ~PARENB;
46 break;
47 }
48
49 switch( nSpeed )
50 {
51 case 2400:
52 cfsetispeed(&newtio, B2400);
53 cfsetospeed(&newtio, B2400);
54 break;
55 case 4800:
56 cfsetispeed(&newtio, B4800);
57 cfsetospeed(&newtio, B4800);
58 break;
59 case 9600:
60 cfsetispeed(&newtio, B9600);
61 cfsetospeed(&newtio, B9600);
62 break;
63 case 115200:
64 cfsetispeed(&newtio, B115200);
65 cfsetospeed(&newtio, B115200);
66 break;
67 case 460800:
68 cfsetispeed(&newtio, B460800);
69 cfsetospeed(&newtio, B460800);
70 break;
71 default:
72 cfsetispeed(&newtio, B9600);
73 cfsetospeed(&newtio, B9600);
74 break;
75 }
76 if( nStop == 1 )
77 newtio.c_cflag &= ~CSTOPB;
78 else if ( nStop == 2 )
79 newtio.c_cflag |= CSTOPB;
80 newtio.c_cc[VTIME] = 0;//重要
81 newtio.c_cc[VMIN] = 100;//返回的最小值 重要
82 tcflush(fd,TCIFLUSH);
83 if((tcsetattr(fd,TCSANOW,&newtio))!=0)
84 {
85 perror("com set error");
86 return -1;
87 }
88 // printf("set done!\n\r");
89 return 0;
90 }
91
92 int main(void)
93 {
94 int fd1,nset1,nread;
95 char buf[1024];
96
97 fd1 = open("/dev/ttyACM0", O_RDWR|O_NONBLOCK);//打开串口
98 if (fd1 == -1)
99 {printf("open error\n");
100 exit(1);}
101
102 nset1 = set_opt(fd1,4800, 8, 'N', 1);//设置串口属性
103 if (nset1 == -1)
104 exit(1);
105
106 while (1)
107
108 {
109 memset(buf,0,1024);
110 nread = read(fd1, buf, 1024);//读串口
111 if (nread > 0){
112 printf("\n GPS DATALen=%d\n",nread);
113 buf[nread] = '\0';
114 printf( "GPS %s\n", buf); //输出所读数据
115 }
116 sleep(2);//睡眠,等待数据多一点
117
118 }
119 close(fd1);
120 return 0;
121 }