mirror of
https://e.coding.net/weidongshan/linux/doc_and_source_for_drivers.git
synced 2025-12-03 05:11:14 +08:00
tmp
This commit is contained in:
@@ -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)
|
* [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串口编程](https://www.cnblogs.com/feisky/archive/2010/05/21/1740893.html):有参考代码
|
||||||
|
|
||||||
* [Linux串口—struct termios结构体](https://blog.csdn.net/yemingzhu163/article/details/5897156)
|
* [Linux串口—struct termios结构体](https://blog.csdn.net/yemingzhu163/article/details/5897156)
|
||||||
|
|
||||||
* 这个是转载,排版更好看: https://www.cnblogs.com/sky-heaven/p/9675253.html
|
* 这个是转载,排版更好看: 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
|
### 1. 串口API
|
||||||
|
|
||||||
@@ -16,6 +31,14 @@
|
|||||||
|
|
||||||
对于UART,又在ioctl之上封装了很多函数,主要是用来设置行规程。
|
对于UART,又在ioctl之上封装了很多函数,主要是用来设置行规程。
|
||||||
|
|
||||||
|
所以对于UART,编程的套路就是:
|
||||||
|
|
||||||
|
* open
|
||||||
|
* 设置行规程,比如波特率、数据位、停止位、检验位、RAW模式、一有数据就返回
|
||||||
|
* read/write
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
怎么设置行规程?行规程的参数用结构体termios来表示,可以参考[Linux串口—struct termios结构体](https://blog.csdn.net/yemingzhu163/article/details/5897156)
|
怎么设置行规程?行规程的参数用结构体termios来表示,可以参考[Linux串口—struct termios结构体](https://blog.csdn.net/yemingzhu163/article/details/5897156)
|
||||||
|
|
||||||

|

|
||||||
@@ -23,7 +46,7 @@
|
|||||||
这些函数在名称上有一些惯例:
|
这些函数在名称上有一些惯例:
|
||||||
|
|
||||||
* tc:terminal contorl
|
* tc:terminal contorl
|
||||||
*
|
* cf: control flag
|
||||||
|
|
||||||
下面列出一些函数:
|
下面列出一些函数:
|
||||||
|
|
||||||
@@ -40,9 +63,63 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 2. GPS模块
|
|
||||||
|
|
||||||
#### 2.1 GPS简介
|
|
||||||
|
### 2. 串口收发实验
|
||||||
|
|
||||||
|
本实验用过把串口的发送、接收引脚短接,实现自发自收:使用write函数发出字符,使用read函数读取字符。
|
||||||
|
|
||||||
|
#### 2.1 接线
|
||||||
|
|
||||||
|
##### 2.1.1 IMX6ULL
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
##### 2.1.2 STM32MP157
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 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系统具有高精度、全天候、用广泛等特点。
|
全球定位系统(Global Positioning System,GPS)是一种以空中卫星为基础的高精度无线电导航的定位系统,它在全球任何地方以及近地空间都能够提供准确的地理位置、车行速度及精确的时间信息。GPS主要由三大组成部分:空间部分、地面监控部分和用户设备部分。GPS系统具有高精度、全天候、用广泛等特点。
|
||||||
|
|
||||||
@@ -54,7 +131,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### 2.2 GPS模块硬件
|
#### 3.2 GPS模块硬件
|
||||||
|
|
||||||
GPS模块与外部控制器的通讯接口有多种方式,这里我们使用串口进行通讯,波特率为9600bps,1bit停止位,无校验位,无流控,默认每秒输出一次标准格式数据。
|
GPS模块与外部控制器的通讯接口有多种方式,这里我们使用串口进行通讯,波特率为9600bps,1bit停止位,无校验位,无流控,默认每秒输出一次标准格式数据。
|
||||||
|
|
||||||
@@ -62,7 +139,7 @@ GPS模块外观如下图所示,通过排线与控制器进行供电和通讯
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### 2.3 GPS模块数据格式
|
#### 3.3 GPS模块数据格式
|
||||||
|
|
||||||
GPS使用多种标准数据格式,目前最通用的GNSS格式是NMEA0183格式。NMEA0183是最终定位格式,即将二进制定位格式转为统一标准定位格式,与卫星类型无关。这是一套定义接收机输出的标准信息,有几种不同的格式,每种都是独立相关的ASCII格式,逗点隔开数据流,数据流长度从30-100字符不等,通常以每秒间隔持续输出。
|
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<CR><LF>
|
$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*hh<CR><LF>
|
||||||
|
|
||||||
$GPGGA语句各字段的含义和取值范围各字段的含义和取值范围见下表所示。
|
$XXGGA语句各字段的含义和取值范围各字段的含义和取值范围见下表所示,XX取值有:
|
||||||
|
|
||||||
|
* GPGGA:单GPS
|
||||||
|
* BDGGA:单北斗
|
||||||
|
* GLGGA:单GLONASS
|
||||||
|
* GNGGA:多星联合定位
|
||||||
|
|
||||||
| 字段 | 含义 | 取值范围 |
|
| 字段 | 含义 | 取值范围 |
|
||||||
| ---- | -------------------------------------------- | ------------------------------------------------------------ |
|
| ---- | -------------------------------------------- | ------------------------------------------------------------ |
|
||||||
@@ -99,27 +181,25 @@ $GPGGA语句各字段的含义和取值范围各字段的含义和取值范围
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 3. 编程
|
#### 3.4 编程
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 4. 上机实验
|
#### 3.5 接线
|
||||||
|
|
||||||
#### 4.1 接线
|
##### 3.5.1 IMX6ULL
|
||||||
|
|
||||||
##### 4.1.1 IMX6ULL
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##### 4.1.2 STM32MP157
|
##### 3.5.2 STM32MP157
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### 3.6 上机实验
|
||||||
|
|
||||||
#### 4.2 编译、执行
|
##### 3.6.1 IMX6ULL
|
||||||
|
|
||||||
##### 4.2.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
|
||||||
|
|
||||||
先设置工具链:
|
先设置工具链:
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
BIN
IMX6ULL/doc_pic/09_UART/pic/09_UART/18_gps_to_stm32mp157.png
Normal file
BIN
IMX6ULL/doc_pic/09_UART/pic/09_UART/18_gps_to_stm32mp157.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
@@ -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)
|
* [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串口编程](https://www.cnblogs.com/feisky/archive/2010/05/21/1740893.html):有参考代码
|
||||||
|
|
||||||
* [Linux串口—struct termios结构体](https://blog.csdn.net/yemingzhu163/article/details/5897156)
|
* [Linux串口—struct termios结构体](https://blog.csdn.net/yemingzhu163/article/details/5897156)
|
||||||
|
|
||||||
* 这个是转载,排版更好看: https://www.cnblogs.com/sky-heaven/p/9675253.html
|
* 这个是转载,排版更好看: 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
|
### 1. 串口API
|
||||||
|
|
||||||
@@ -16,6 +31,14 @@
|
|||||||
|
|
||||||
对于UART,又在ioctl之上封装了很多函数,主要是用来设置行规程。
|
对于UART,又在ioctl之上封装了很多函数,主要是用来设置行规程。
|
||||||
|
|
||||||
|
所以对于UART,编程的套路就是:
|
||||||
|
|
||||||
|
* open
|
||||||
|
* 设置行规程,比如波特率、数据位、停止位、检验位、RAW模式、一有数据就返回
|
||||||
|
* read/write
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
怎么设置行规程?行规程的参数用结构体termios来表示,可以参考[Linux串口—struct termios结构体](https://blog.csdn.net/yemingzhu163/article/details/5897156)
|
怎么设置行规程?行规程的参数用结构体termios来表示,可以参考[Linux串口—struct termios结构体](https://blog.csdn.net/yemingzhu163/article/details/5897156)
|
||||||
|
|
||||||

|

|
||||||
@@ -23,7 +46,7 @@
|
|||||||
这些函数在名称上有一些惯例:
|
这些函数在名称上有一些惯例:
|
||||||
|
|
||||||
* tc:terminal contorl
|
* tc:terminal contorl
|
||||||
*
|
* cf: control flag
|
||||||
|
|
||||||
下面列出一些函数:
|
下面列出一些函数:
|
||||||
|
|
||||||
@@ -40,9 +63,63 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 2. GPS模块
|
|
||||||
|
|
||||||
#### 2.1 GPS简介
|
|
||||||
|
### 2. 串口收发实验
|
||||||
|
|
||||||
|
本实验用过把串口的发送、接收引脚短接,实现自发自收:使用write函数发出字符,使用read函数读取字符。
|
||||||
|
|
||||||
|
#### 2.1 接线
|
||||||
|
|
||||||
|
##### 2.1.1 IMX6ULL
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
##### 2.1.2 STM32MP157
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#### 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系统具有高精度、全天候、用广泛等特点。
|
全球定位系统(Global Positioning System,GPS)是一种以空中卫星为基础的高精度无线电导航的定位系统,它在全球任何地方以及近地空间都能够提供准确的地理位置、车行速度及精确的时间信息。GPS主要由三大组成部分:空间部分、地面监控部分和用户设备部分。GPS系统具有高精度、全天候、用广泛等特点。
|
||||||
|
|
||||||
@@ -54,7 +131,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
#### 2.2 GPS模块硬件
|
#### 3.2 GPS模块硬件
|
||||||
|
|
||||||
GPS模块与外部控制器的通讯接口有多种方式,这里我们使用串口进行通讯,波特率为9600bps,1bit停止位,无校验位,无流控,默认每秒输出一次标准格式数据。
|
GPS模块与外部控制器的通讯接口有多种方式,这里我们使用串口进行通讯,波特率为9600bps,1bit停止位,无校验位,无流控,默认每秒输出一次标准格式数据。
|
||||||
|
|
||||||
@@ -62,7 +139,7 @@ GPS模块外观如下图所示,通过排线与控制器进行供电和通讯
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### 2.3 GPS模块数据格式
|
#### 3.3 GPS模块数据格式
|
||||||
|
|
||||||
GPS使用多种标准数据格式,目前最通用的GNSS格式是NMEA0183格式。NMEA0183是最终定位格式,即将二进制定位格式转为统一标准定位格式,与卫星类型无关。这是一套定义接收机输出的标准信息,有几种不同的格式,每种都是独立相关的ASCII格式,逗点隔开数据流,数据流长度从30-100字符不等,通常以每秒间隔持续输出。
|
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<CR><LF>
|
$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*hh<CR><LF>
|
||||||
|
|
||||||
$GPGGA语句各字段的含义和取值范围各字段的含义和取值范围见下表所示。
|
$XXGGA语句各字段的含义和取值范围各字段的含义和取值范围见下表所示,XX取值有:
|
||||||
|
|
||||||
|
* GPGGA:单GPS
|
||||||
|
* BDGGA:单北斗
|
||||||
|
* GLGGA:单GLONASS
|
||||||
|
* GNGGA:多星联合定位
|
||||||
|
|
||||||
| 字段 | 含义 | 取值范围 |
|
| 字段 | 含义 | 取值范围 |
|
||||||
| ---- | -------------------------------------------- | ------------------------------------------------------------ |
|
| ---- | -------------------------------------------- | ------------------------------------------------------------ |
|
||||||
@@ -99,27 +181,25 @@ $GPGGA语句各字段的含义和取值范围各字段的含义和取值范围
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 3. 编程
|
#### 3.4 编程
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### 4. 上机实验
|
#### 3.5 接线
|
||||||
|
|
||||||
#### 4.1 接线
|
##### 3.5.1 IMX6ULL
|
||||||
|
|
||||||
##### 4.1.1 IMX6ULL
|
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
##### 4.1.2 STM32MP157
|
##### 3.5.2 STM32MP157
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
#### 3.6 上机实验
|
||||||
|
|
||||||
#### 4.2 编译、执行
|
##### 3.6.1 IMX6ULL
|
||||||
|
|
||||||
##### 4.2.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
|
||||||
|
|
||||||
先设置工具链:
|
先设置工具链:
|
||||||
|
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.0 MiB |
Binary file not shown.
|
After Width: | Height: | Size: 1.5 MiB |
BIN
STM32MP157/doc_pic/09_UART/pic/09_UART/18_gps_to_stm32mp157.png
Normal file
BIN
STM32MP157/doc_pic/09_UART/pic/09_UART/18_gps_to_stm32mp157.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
177
STM32MP157/source/A7/09_UART/01_app_send_recv/serial_send_recv.c
Normal file
177
STM32MP157/source/A7/09_UART/01_app_send_recv/serial_send_recv.c
Normal file
@@ -0,0 +1,177 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* 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 <dev>
|
||||||
|
*/
|
||||||
|
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 </dev/ttySAC1 or other>\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;
|
||||||
|
}
|
||||||
|
|
||||||
238
STM32MP157/source/A7/09_UART/02_gps/gps_read.c
Normal file
238
STM32MP157/source/A7/09_UART/02_gps/gps_read.c
Normal file
@@ -0,0 +1,238 @@
|
|||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <termios.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
/* 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"<CR><LF> */
|
||||||
|
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 <dev>
|
||||||
|
*/
|
||||||
|
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 </dev/ttySAC1 or other>\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"<CR><LF>*/
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user