diff --git a/IMX6ULL/doc_pic/09_UART/05_Linux串口应用编程.md b/IMX6ULL/doc_pic/09_UART/05_Linux串口应用编程.md index 4816052..e215879 100644 --- a/IMX6ULL/doc_pic/09_UART/05_Linux串口应用编程.md +++ b/IMX6ULL/doc_pic/09_UART/05_Linux串口应用编程.md @@ -2,11 +2,26 @@ 参考资料 -* [解密TTY](https://www.cnblogs.com/liqiuhao/p/9031803.html) * [Serial Programming Guide for POSIX Operating Systems](https://digilander.libero.it/robang/rubrica/serial.htm) + * [Linux串口编程](https://www.cnblogs.com/feisky/archive/2010/05/21/1740893.html):有参考代码 + * [Linux串口—struct termios结构体](https://blog.csdn.net/yemingzhu163/article/details/5897156) + * 这个是转载,排版更好看: https://www.cnblogs.com/sky-heaven/p/9675253.html + +* 本节课程源码在GIT仓库里 + + ```shell + doc_and_source_for_drivers\IMX6ULL\source\09_UART + 01_app_send_recv + 02_gps + doc_and_source_for_drivers\STM32MP157\source\A7\09_UART + 01_app_send_recv + 02_gps + ``` + + ### 1. 串口API @@ -16,6 +31,14 @@ 对于UART,又在ioctl之上封装了很多函数,主要是用来设置行规程。 +所以对于UART,编程的套路就是: + +* open +* 设置行规程,比如波特率、数据位、停止位、检验位、RAW模式、一有数据就返回 +* read/write + + + 怎么设置行规程?行规程的参数用结构体termios来表示,可以参考[Linux串口—struct termios结构体](https://blog.csdn.net/yemingzhu163/article/details/5897156) ![image-20210716152256884](pic/09_UART/12_termios.png) @@ -23,7 +46,7 @@ 这些函数在名称上有一些惯例: * tc:terminal contorl -* +* cf: control flag 下面列出一些函数: @@ -40,9 +63,63 @@ -### 2. GPS模块 -#### 2.1 GPS简介 + +### 2. 串口收发实验 + +本实验用过把串口的发送、接收引脚短接,实现自发自收:使用write函数发出字符,使用read函数读取字符。 + +#### 2.1 接线 + +##### 2.1.1 IMX6ULL + +![image-20210717090635504](pic/09_UART/16_extend_board_on_imx6ull.png) + +##### 2.1.2 STM32MP157 + +![image-20210717090517819](pic/09_UART/17_extend_board_on_stm32mp157.png) + + + +#### 2.2 编程 + +#### 2.3 上机实验 + +##### 2.3.1 IMX6ULL + +先设置工具链: + +```shell +export ARCH=arm +export CROSS_COMPILE=arm-buildroot-linux-gnueabihf- +export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin +``` + + + +编译、执行程序 + + + +##### 2.3.2 STM32MP157 + +先设置工具链: + +```shell +export ARCH=arm +export CROSS_COMPILE=arm-buildroot-linux-gnueabihf- +export PATH=$PATH:/home/book/100ask_stm32mp157_pro-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin +``` + + + +编译、执行程序 + + + +### 3. GPS模块实验 + +#### 3.1 GPS简介 全球定位系统(Global Positioning System,GPS)是一种以空中卫星为基础的高精度无线电导航的定位系统,它在全球任何地方以及近地空间都能够提供准确的地理位置、车行速度及精确的时间信息。GPS主要由三大组成部分:空间部分、地面监控部分和用户设备部分。GPS系统具有高精度、全天候、用广泛等特点。 @@ -54,7 +131,7 @@ -#### 2.2 GPS模块硬件 +#### 3.2 GPS模块硬件 GPS模块与外部控制器的通讯接口有多种方式,这里我们使用串口进行通讯,波特率为9600bps,1bit停止位,无校验位,无流控,默认每秒输出一次标准格式数据。 @@ -62,7 +139,7 @@ GPS模块外观如下图所示,通过排线与控制器进行供电和通讯 ![](pic/09_UART/13_gps.png) -#### 2.3 GPS模块数据格式 +#### 3.3 GPS模块数据格式 GPS使用多种标准数据格式,目前最通用的GNSS格式是NMEA0183格式。NMEA0183是最终定位格式,即将二进制定位格式转为统一标准定位格式,与卫星类型无关。这是一套定义接收机输出的标准信息,有几种不同的格式,每种都是独立相关的ASCII格式,逗点隔开数据流,数据流长度从30-100字符不等,通常以每秒间隔持续输出。 @@ -76,7 +153,12 @@ NVMEA0183格式主要针对民用定位导航,与专业RTCM2.3/3.0和CMR+的GN $GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*hh  -$GPGGA语句各字段的含义和取值范围各字段的含义和取值范围见下表所示。 +$XXGGA语句各字段的含义和取值范围各字段的含义和取值范围见下表所示,XX取值有: + +* GPGGA:单GPS +* BDGGA:单北斗 +* GLGGA:单GLONASS +* GNGGA:多星联合定位 | 字段 | 含义 | 取值范围 | | ---- | -------------------------------------------- | ------------------------------------------------------------ | @@ -99,27 +181,25 @@ $GPGGA语句各字段的含义和取值范围各字段的含义和取值范围 -### 3. 编程 +#### 3.4 编程 -### 4. 上机实验 +#### 3.5 接线 -#### 4.1 接线 - -##### 4.1.1 IMX6ULL +##### 3.5.1 IMX6ULL ![image-20210716155143140](pic/09_UART/15_gps_to_imx6ull.png) -##### 4.1.2 STM32MP157 +##### 3.5.2 STM32MP157 +![image-20210717091116795](pic/09_UART/18_gps_to_stm32mp157.png) +#### 3.6 上机实验 -#### 4.2 编译、执行 - -##### 4.2.1 IMX6ULL +##### 3.6.1 IMX6ULL 先设置工具链: @@ -135,7 +215,7 @@ export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gn -##### 4.2.2 STM32MP157 +##### 3.6.2 STM32MP157 先设置工具链: diff --git a/IMX6ULL/doc_pic/09_UART/pic/09_UART/16_extend_board_on_imx6ull.png b/IMX6ULL/doc_pic/09_UART/pic/09_UART/16_extend_board_on_imx6ull.png new file mode 100644 index 0000000..7a67229 Binary files /dev/null and b/IMX6ULL/doc_pic/09_UART/pic/09_UART/16_extend_board_on_imx6ull.png differ diff --git a/IMX6ULL/doc_pic/09_UART/pic/09_UART/17_extend_board_on_stm32mp157.png b/IMX6ULL/doc_pic/09_UART/pic/09_UART/17_extend_board_on_stm32mp157.png new file mode 100644 index 0000000..a365f53 Binary files /dev/null and b/IMX6ULL/doc_pic/09_UART/pic/09_UART/17_extend_board_on_stm32mp157.png differ diff --git a/IMX6ULL/doc_pic/09_UART/pic/09_UART/18_gps_to_stm32mp157.png b/IMX6ULL/doc_pic/09_UART/pic/09_UART/18_gps_to_stm32mp157.png new file mode 100644 index 0000000..eda73b2 Binary files /dev/null and b/IMX6ULL/doc_pic/09_UART/pic/09_UART/18_gps_to_stm32mp157.png differ diff --git a/STM32MP157/doc_pic/09_UART/05_Linux串口应用编程.md b/STM32MP157/doc_pic/09_UART/05_Linux串口应用编程.md index 4816052..e215879 100644 --- a/STM32MP157/doc_pic/09_UART/05_Linux串口应用编程.md +++ b/STM32MP157/doc_pic/09_UART/05_Linux串口应用编程.md @@ -2,11 +2,26 @@ 参考资料 -* [解密TTY](https://www.cnblogs.com/liqiuhao/p/9031803.html) * [Serial Programming Guide for POSIX Operating Systems](https://digilander.libero.it/robang/rubrica/serial.htm) + * [Linux串口编程](https://www.cnblogs.com/feisky/archive/2010/05/21/1740893.html):有参考代码 + * [Linux串口—struct termios结构体](https://blog.csdn.net/yemingzhu163/article/details/5897156) + * 这个是转载,排版更好看: https://www.cnblogs.com/sky-heaven/p/9675253.html + +* 本节课程源码在GIT仓库里 + + ```shell + doc_and_source_for_drivers\IMX6ULL\source\09_UART + 01_app_send_recv + 02_gps + doc_and_source_for_drivers\STM32MP157\source\A7\09_UART + 01_app_send_recv + 02_gps + ``` + + ### 1. 串口API @@ -16,6 +31,14 @@ 对于UART,又在ioctl之上封装了很多函数,主要是用来设置行规程。 +所以对于UART,编程的套路就是: + +* open +* 设置行规程,比如波特率、数据位、停止位、检验位、RAW模式、一有数据就返回 +* read/write + + + 怎么设置行规程?行规程的参数用结构体termios来表示,可以参考[Linux串口—struct termios结构体](https://blog.csdn.net/yemingzhu163/article/details/5897156) ![image-20210716152256884](pic/09_UART/12_termios.png) @@ -23,7 +46,7 @@ 这些函数在名称上有一些惯例: * tc:terminal contorl -* +* cf: control flag 下面列出一些函数: @@ -40,9 +63,63 @@ -### 2. GPS模块 -#### 2.1 GPS简介 + +### 2. 串口收发实验 + +本实验用过把串口的发送、接收引脚短接,实现自发自收:使用write函数发出字符,使用read函数读取字符。 + +#### 2.1 接线 + +##### 2.1.1 IMX6ULL + +![image-20210717090635504](pic/09_UART/16_extend_board_on_imx6ull.png) + +##### 2.1.2 STM32MP157 + +![image-20210717090517819](pic/09_UART/17_extend_board_on_stm32mp157.png) + + + +#### 2.2 编程 + +#### 2.3 上机实验 + +##### 2.3.1 IMX6ULL + +先设置工具链: + +```shell +export ARCH=arm +export CROSS_COMPILE=arm-buildroot-linux-gnueabihf- +export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin +``` + + + +编译、执行程序 + + + +##### 2.3.2 STM32MP157 + +先设置工具链: + +```shell +export ARCH=arm +export CROSS_COMPILE=arm-buildroot-linux-gnueabihf- +export PATH=$PATH:/home/book/100ask_stm32mp157_pro-sdk/ToolChain/arm-buildroot-linux-gnueabihf_sdk-buildroot/bin +``` + + + +编译、执行程序 + + + +### 3. GPS模块实验 + +#### 3.1 GPS简介 全球定位系统(Global Positioning System,GPS)是一种以空中卫星为基础的高精度无线电导航的定位系统,它在全球任何地方以及近地空间都能够提供准确的地理位置、车行速度及精确的时间信息。GPS主要由三大组成部分:空间部分、地面监控部分和用户设备部分。GPS系统具有高精度、全天候、用广泛等特点。 @@ -54,7 +131,7 @@ -#### 2.2 GPS模块硬件 +#### 3.2 GPS模块硬件 GPS模块与外部控制器的通讯接口有多种方式,这里我们使用串口进行通讯,波特率为9600bps,1bit停止位,无校验位,无流控,默认每秒输出一次标准格式数据。 @@ -62,7 +139,7 @@ GPS模块外观如下图所示,通过排线与控制器进行供电和通讯 ![](pic/09_UART/13_gps.png) -#### 2.3 GPS模块数据格式 +#### 3.3 GPS模块数据格式 GPS使用多种标准数据格式,目前最通用的GNSS格式是NMEA0183格式。NMEA0183是最终定位格式,即将二进制定位格式转为统一标准定位格式,与卫星类型无关。这是一套定义接收机输出的标准信息,有几种不同的格式,每种都是独立相关的ASCII格式,逗点隔开数据流,数据流长度从30-100字符不等,通常以每秒间隔持续输出。 @@ -76,7 +153,12 @@ NVMEA0183格式主要针对民用定位导航,与专业RTCM2.3/3.0和CMR+的GN $GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*hh  -$GPGGA语句各字段的含义和取值范围各字段的含义和取值范围见下表所示。 +$XXGGA语句各字段的含义和取值范围各字段的含义和取值范围见下表所示,XX取值有: + +* GPGGA:单GPS +* BDGGA:单北斗 +* GLGGA:单GLONASS +* GNGGA:多星联合定位 | 字段 | 含义 | 取值范围 | | ---- | -------------------------------------------- | ------------------------------------------------------------ | @@ -99,27 +181,25 @@ $GPGGA语句各字段的含义和取值范围各字段的含义和取值范围 -### 3. 编程 +#### 3.4 编程 -### 4. 上机实验 +#### 3.5 接线 -#### 4.1 接线 - -##### 4.1.1 IMX6ULL +##### 3.5.1 IMX6ULL ![image-20210716155143140](pic/09_UART/15_gps_to_imx6ull.png) -##### 4.1.2 STM32MP157 +##### 3.5.2 STM32MP157 +![image-20210717091116795](pic/09_UART/18_gps_to_stm32mp157.png) +#### 3.6 上机实验 -#### 4.2 编译、执行 - -##### 4.2.1 IMX6ULL +##### 3.6.1 IMX6ULL 先设置工具链: @@ -135,7 +215,7 @@ export PATH=$PATH:/home/book/100ask_imx6ull-sdk/ToolChain/arm-buildroot-linux-gn -##### 4.2.2 STM32MP157 +##### 3.6.2 STM32MP157 先设置工具链: diff --git a/STM32MP157/doc_pic/09_UART/pic/09_UART/16_extend_board_on_imx6ull.png b/STM32MP157/doc_pic/09_UART/pic/09_UART/16_extend_board_on_imx6ull.png new file mode 100644 index 0000000..7a67229 Binary files /dev/null and b/STM32MP157/doc_pic/09_UART/pic/09_UART/16_extend_board_on_imx6ull.png differ diff --git a/STM32MP157/doc_pic/09_UART/pic/09_UART/17_extend_board_on_stm32mp157.png b/STM32MP157/doc_pic/09_UART/pic/09_UART/17_extend_board_on_stm32mp157.png new file mode 100644 index 0000000..a365f53 Binary files /dev/null and b/STM32MP157/doc_pic/09_UART/pic/09_UART/17_extend_board_on_stm32mp157.png differ diff --git a/STM32MP157/doc_pic/09_UART/pic/09_UART/18_gps_to_stm32mp157.png b/STM32MP157/doc_pic/09_UART/pic/09_UART/18_gps_to_stm32mp157.png new file mode 100644 index 0000000..eda73b2 Binary files /dev/null and b/STM32MP157/doc_pic/09_UART/pic/09_UART/18_gps_to_stm32mp157.png differ diff --git a/STM32MP157/source/A7/09_UART/01_app_send_recv/serial_send_recv.c b/STM32MP157/source/A7/09_UART/01_app_send_recv/serial_send_recv.c new file mode 100644 index 0000000..0e9bd29 --- /dev/null +++ b/STM32MP157/source/A7/09_UART/01_app_send_recv/serial_send_recv.c @@ -0,0 +1,177 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* set_opt(fd,115200,8,'N',1) */ +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; + + newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/ + newtio.c_oflag &= ~OPOST; /*Output*/ + + 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; + 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[VMIN] = 1; /* 读数据时的最小字节数: 没读到这些数据我就不返回! */ + newtio.c_cc[VTIME] = 0; /* 等待第1个数据的时间: + * 比如VMIN设为10表示至少读到10个数据才返回, + * 但是没有数据总不能一直等吧? 可以设置VTIME(单位是10秒) + * 假设VTIME=1,表示: + * 10秒内一个数据都没有的话就返回 + * 如果10秒内至少读到了1个字节,那就继续等待,完全读到VMIN个数据再返回 + */ + + tcflush(fd,TCIFLUSH); + + if((tcsetattr(fd,TCSANOW,&newtio))!=0) + { + perror("com set error"); + return -1; + } + //printf("set done!\n"); + return 0; +} + +int open_port(char *com) +{ + int fd; + //fd = open(com, O_RDWR|O_NOCTTY|O_NDELAY); + fd = open(com, O_RDWR|O_NOCTTY); + if (-1 == fd){ + return(-1); + } + + if(fcntl(fd, F_SETFL, 0)<0) /* 设置串口为阻塞状态*/ + { + printf("fcntl failed!\n"); + return -1; + } + + return fd; +} + + +/* + * ./serial_send_recv + */ +int main(int argc, char **argv) +{ + int fd; + int iRet; + char c; + + /* 1. open */ + + /* 2. setup + * 115200,8N1 + * RAW mode + * return data immediately + */ + + /* 3. write and read */ + + if (argc != 2) + { + printf("Usage: \n"); + printf("%s \n", argv[0]); + return -1; + } + + fd = open_port(argv[1]); + if (fd < 0) + { + printf("open %s err!\n", argv[1]); + return -1; + } + + iRet = set_opt(fd, 115200, 8, 'N', 1); + if (iRet) + { + printf("set port err!\n"); + return -1; + } + + printf("Enter a char: "); + while (1) + { + scanf("%c", &c); + iRet = write(fd, &c, 1); + iRet = read(fd, &c, 1); + if (iRet == 1) + printf("get: %02x %c\n", c, c); + else + printf("can not get data\n"); + } + + return 0; +} + diff --git a/STM32MP157/source/A7/09_UART/02_gps/gps_read.c b/STM32MP157/source/A7/09_UART/02_gps/gps_read.c new file mode 100644 index 0000000..c8a0989 --- /dev/null +++ b/STM32MP157/source/A7/09_UART/02_gps/gps_read.c @@ -0,0 +1,238 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* set_opt(fd,115200,8,'N',1) */ +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; + + newtio.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/ + newtio.c_oflag &= ~OPOST; /*Output*/ + + 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; + 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[VMIN] = 1; /* 读数据时的最小字节数: 没读到这些数据我就不返回! */ + newtio.c_cc[VTIME] = 0; /* 等待第1个数据的时间: + * 比如VMIN设为10表示至少读到10个数据才返回, + * 但是没有数据总不能一直等吧? 可以设置VTIME(单位是10秒) + * 假设VTIME=1,表示: + * 10秒内一个数据都没有的话就返回 + * 如果10秒内至少读到了1个字节,那就继续等待,完全读到VMIN个数据再返回 + */ + + tcflush(fd,TCIFLUSH); + + if((tcsetattr(fd,TCSANOW,&newtio))!=0) + { + perror("com set error"); + return -1; + } + //printf("set done!\n"); + return 0; +} + +int open_port(char *com) +{ + int fd; + //fd = open(com, O_RDWR|O_NOCTTY|O_NDELAY); + fd = open(com, O_RDWR|O_NOCTTY); + if (-1 == fd){ + return(-1); + } + + if(fcntl(fd, F_SETFL, 0)<0) /* 设置串口为阻塞状态*/ + { + printf("fcntl failed!\n"); + return -1; + } + + return fd; +} + + +int read_gps_raw_data(int fd, char *buf) +{ + int i = 0; + int iRet; + char c; + int start = 0; + + while (1) + { + iRet = read(fd, &c, 1); + if (iRet == 1) + { + if (c == '$') + start = 1; + if (start) + { + buf[i++] = c; + } + if (c == '\n' || c == '\r') + return 0; + } + else + { + return -1; + } + } +} + +/* eg. $GPGGA,082559.00,4005.22599,N,11632.58234,E,1,04,3.08,14.6,M,-5.6,M,,*76" */ +int parse_gps_raw_data(char *buf, char *time, char *lat, char *ns, char *lng, char *ew) +{ + char tmp[10]; + + if (buf[0] != '$') + return -1; + else if (strncmp(buf+3, "GGA", 3) != 0) + return -1; + else { + sscanf(buf, "%s,%s,%s,%s,%s,%s", tmp, time, lat, ns, lng, ew); + return 0; + } +} + + +/* + * ./serial_send_recv + */ +int main(int argc, char **argv) +{ + int fd; + int iRet; + char c; + char buf[1000]; + char time[100]; + char Lat[100]; + char ns[100]; + char Lng[100]; + char ew[100]; + + /* 1. open */ + + /* 2. setup + * 115200,8N1 + * RAW mode + * return data immediately + */ + + /* 3. write and read */ + + if (argc != 2) + { + printf("Usage: \n"); + printf("%s \n", argv[0]); + return -1; + } + + fd = open_port(argv[1]); + if (fd < 0) + { + printf("open %s err!\n", argv[1]); + return -1; + } + + iRet = set_opt(fd, 9600, 8, 'N', 1); + if (iRet) + { + printf("set port err!\n"); + return -1; + } + + while (1) + { + /* eg. $GPGGA,082559.00,4005.22599,N,11632.58234,E,1,04,3.08,14.6,M,-5.6,M,,*76"*/ + /* read line */ + iRet = read_gps_raw_data(fd, buf); + + /* parse line */ + if (iRet == 0) + { + iRet = parse_gps_raw_data(buf, time, Lat, ns, Lng, ew); + } + + /* printf */ + if (iRet == 0) + { + printf("Time : %s\n", time); + printf("ns : %s\n", ns); + printf("ew : %s\n", ew); + printf("Lat : %s\n", Lat); + printf("Lng : %s\n", Lng); + } + } + + return 0; +} +