Linux上的串口编程

Linux上的串口编程

在这里插入图片描述

Linux串口

Linux下的传统硬件串口命名为ttyS ,其中可以是1,2,3 …等,例如ttyS1,ttyS2,ttyS23 …等等。它们类似于Windows下的COM1,COM2等。
在Linux中,串行端口等硬件组件被视为文件,并在文件系统的/ dev文件夹中组合在一起。如果导航到/ dev文件夹并使用ls命令列出文件,则可以看到与各种硬件对应的文件设备。
在这里插入图片描述
输入命令

dmesg|grep ttyS

如果有

[ 37.531286] serial8250: ttyS0 at I/O 0x3f8 (irq = 4) is a 16550A

则表示ttyS0已连接
现在检查任何USB转串口转换器使用dmesg | grep tty命令。
在这里插入图片描述可以看到FTDI转换器连接到ttyUSB0.
另一个可以看到连接的串行设备的地方是/ dev / serial / by-id文件夹。

配置串口

要在linux下执行串行I/O,需要使用termios API。termios API支持两种访问串口的模式。即
* Cannonical Mode
* NonCannonical Mode
Cannonical 模式是默认的模式,用于访问终端等。我们用后面的一种模式

打开关闭串口

函数
open()打开
close()关闭
open()系统调用需要两个参数,要打开的文件的名称(这里串行端口),并与it.It相关的各种参数返回-1失败和成功的正整数。

int fd;
fd = open( “ / dev /ttyUSB0 ”,O_RDWR | O_NOCTTY ) ;

O_RDWR :打开端口进行读写操作
O_NOCTTY :没有终端控制打开串口的进程
打开串口后,应该使用close()系统调用关闭 .close()接受一个参数,我们之前使用open()系统调用打开串口的文件描述符fd。就像close(fd)
c代码

#include <stdio.h>
#include <fcntl.h>  /* File Control Definitions          */
#include <termios.h>/* POSIX Terminal Control Definitions*/
#include <unistd.h> /* UNIX Standard Definitions         */
#include <errno.h>  /* ERROR Number Definitions          */
void main()
{
  int fd;
  fd = open("/dev/ttyUSB0",O_RDWR | O_NOCTTY);
  if(fd == ­1)
     printf("\n  Error! in Opening ttyUSB0\n");
  else
     printf("\n  ttyUSB0 Opened Successfully\n");
  close(fd);

结果(需要使用硬件连接)
在这里插入图片描述

配置termios结构体

成功打开和关闭串口后,可以配置正确的模式,波特率,数据格式,启动/停止位数等。在Linux中,它由一个名为termios的结构体完成。如下:

struct termios
{
tcflag_t c_iflag; /* input mode flags   */
tcflag_t c_oflag; /* output mode flags  */
tcflag_t c_cflag; /* control mode flags */
tcflag_t c_lflag; /* local mode flags   */
cc_t c_line;      /* line discipline    */
cc_t c_cc[NCCS];  /* control characters */
};

声明结构体,并使用两个函数配置它,tcgetattr() 和tcsetattr().tcsetattr()用于设置终端参数。函数在成功时返回0,失败时为-1,并设置errnod的值。tcgetattr()用于将串口的当前设置获取到我们刚刚声明的结构。它有两个参数,一个是文件描述符fd,对应于我们打开的串口,另一个是我们刚刚声明的结构的地址。

tcgetattr(fd, &SerialPortSettings);

在得到当前的设置后,我们要改变它适合我们的需要。我们将配置串行端口以9600波特率传输,8位,无奇偶校验,1个停止位,8-N-1配置。百科

设置波特率

波特率设置有两个函数
1.cfsetispeed()用于设置读或者输入的波特率
2.cfsetospeed()用于设置输出和写的波特率

cfsetispeed(&SerialPortSettings,B9600);
cfsetospeed(&SerialPortSettings,B9600);

波特率的设定需要根据连接的硬件来设定。

配置数据格式,开始/停止位,奇偶校验

termios结构的控制标志(c_cflag)配置数据格式(数据的8位或7位)、奇偶校验(偶数、奇数、None)和通信时使用的启动位和停止位的数量。配置这些信息涉及设置和清除控件标志的各个位
如:

//校验位设置
SerialPortSettings.c_cflag &= ~PARENB; /*CLEAR Parity Bit PARENB*/
SerialPortSettings.c_cflag |=  PARENB; /*SET   Parity Bit PARENB*/
//奇偶校验位
SerialPortSettings.c_cflag &= ~PARENB;   // No Parity
//设置停止位
SerialPortSettings.c_cflag &= ~CSTOPB; //Stop bits = 1 
//数据位8位
SerialPortSettings.c_cflag &= ~CSIZE; /* Clears the Mask       */
SerialPortSettings.c_cflag |=  CS8;   /* Set the data bits = 8 */ 

配置其他选项

关闭基于硬件的流控制(RTS/CTS)。

SerialPortSettings.c_cflag &= ~CRTSCTS;

打开串口(CREAD)的接收器,从串口读取其他数据将不起作用。

SerialPortSettings.c_cflag |= CREAD | CLOCAL;

关闭软件流控制

SerialPortSettings.c_iflag &= ~(IXON | IXOFF | IXANY);

在设置操作方式时,Linux中串口的默认操作方式是Cannonical模式。对于与外部设备的串行通信,如串行调制解调器、鼠标等。

SerialPortSettings.c_iflag &= ~(ICANON | ECHO | ECHOE | ISIG);

有关上面讨论的函数和常量的更多信息,可以在termios手册页面中找到。
接下来我们可以使用tcsetattr()函数来设置它们。tcsetattr()接受三个参数,第一个和最后一个参数与tcgetattr()函数中相同。第二个参数optional_actions用于控制修改起作用的时间,而结构体termios_p中保存了要修改的参数。optional_actions可以取如下的值。
TCSANOW:不等数据传输完毕就立即改变属性。
TCSADRAIN:等待所有数据传输结束才改变属性。
TCSAFLUSH:清空输入输出缓冲区才改变属性。
我们不等数据传输完毕就立即改变属性,即

tcsetattr(fd,TCSANOW,&SerialPortSettings)

软件设置就完成了,硬件连接后续……

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值