1、串口的 介绍
串口的介绍,
串口发送的顺序;
1.空闲位:这里是连续的 1
2.起始位:低电平
3.数据位:对于传输的数据位这里是自己去设定传输位数,可以5、6、7、8位,但是我们一般设置为 8位
串口的数据是从低位开始发送
4.奇偶校验位:保证传输数据位中的 1 的个数是奇数还是偶数。奇校验;保证数据位中的‘1’是奇数个,当数据位中的‘1’是奇数个的时候,那么校验位填零;当数据位中的‘1’是偶数个的时候,则校验位填为‘1’。
5.停止位:低电平。持续时间为一个或者 1.5 个字符的时间。
2、硬件引脚的认识
3、Linux 下端口 /dev/ttyn、/dev/pts/n、/dev/ttySn:
终端的查看,是借用了 tty 命令去查看。
/dev/ttyn : 终端,一般就是我们在 ubuntu 里面终端的时候,就是 ttyn
/dev/pts/n : 虚拟终端 ,比如当我们使用 secureCRT 连接 ubuntu 的时候,这个时候 secureCRT 的终端。
/dev/ttySn: 使用串口登录串行端口终端,也就是设备通过串口端连接终端,ttyS0、ttyS1,分别对应了 COM1 和 COM 2
4、串口的基本知识 4.1、串口传输模式
串口传输的模式,可以分为两种,标准输入模式(规范模式)和非标//代码效果参考:http://www.zidongmutanji.com/bxxx/113334.html
准输入模式(非规范模式)标准输入模式:
这种模式是终端设备标准的处理模式。通信中,是以行为单位进行传输,行的结束是以 enter 为结束符。read 的时候,会将一行的数据,完整地进行输入,一行的结束默认是 enter (ASCII 是 LF,既换行 ,回车是 cr,)。在标准输入模式下,字符被输入终端之后,还可以进行清除,删除,重写,换行等操作,所以,根据自己的实际需求,写好字符之后,按下 enter 作为作为一行输入的结束。
非标准输入模式:
这种模式一般是用于需要每次读取固定字符的情况下(比如一个字符),并允许使用,字符接收时间的定时器。也就是说,可以在每次读取固定长度字符串的程序中,或者连接的设备会突然发送大量的字符内容的情况下。
4.2、流控
流控,可以分为硬件流控和软件流控。流控实现的是,当接收端不能接收串口数据的时候,通知数据的发送端,使其不再发送数据的这么一种机制。软件流控,实现的方法是通过一些特殊的字符进行定义,X0N(DC1,八进制的话是,021) 和 结束,X0FF(DC3,八进制是,023),来开始和结束数据流的进行。开始和结束的这个特殊的字符,是被定义在 ASCII 。所以,当传输的信息是文本信息的时候,软件流控是非常的好用的。但是,流控是不被建议运用在传输二进制文件。
硬件流控,是通过硬件特定的管脚,发送电平实现的。
4.3、ASCII
CR-od(十六进制)--回车---\r(C语言)
NL(LF)-oa(new line、line feed)-换行\n(C语言)
5、串口的操作 5.1、文件的打开
int open_port(void)
{
int fd; / File descriptor for the port / //代码效果参考:http://www.zidongmutanji.com/bxxx/161362.html
fd = open("/dev/ttyf1", O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == ?1)
{
/
Could not open the port.
/
perror("open_port: Unable to open /dev/ttyf1 ? ");
}
else
fcntl(fd, F_SETFL, 0);
return (fd);
}
O_NOCTTY : 告诉系统,当前的程序上不受终端的控制,所以就不会受到 ctrl+ c 的影响。
NDELAY : 和 NONBLOCK 类似。NDELAY 不会受到 DCD 信号的影响。非阻塞
5.2、串口读
n = write(fd, "ATZ\r", 4);
if (n < 0)
fputs("write() of 4 bytes failed!\n", stderr);
5.3、串口的写
相比于串口读,串口写的操作,还是存在一点的技巧的。当 read 一个以 原始模式的传输数据串口的时候,read 的返回值,是串口实际接收字符的个数。当没有 read 到字符的时候,read 操作会编程阻塞模式,直到字符的到来,或者错误的发生。所以,为了 read 的时候,读取不到字符的时候,立即马上返回,可以进行下面的操作:
fcntl( fd, F_SETFL, FNDELAY)
FNDELAY 会导致,当串口没有字符被读取到的时候,立即返回 零//代码效果参考:http://www.zidongmutanji.com/bxxx/322232.html
。如果需要设置阻塞模式的话:fcntl( fd, F_SETFL, 0);
5.4、关闭
close( fd )
6、接口
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 / 控制字符
};、
6.1、control flag
控制模式,主要是对,波特率,传输的数据位,校验位、停止位、和流控进行设置。对于控制标志的设置,是通过下面的常量(宏)进行配置。
Constant Description
CBAUD Bit mask for baud rate
B0 0 baud (drop DTR) // 波特率
B50 50 baud
B75 75 baud
B110 110 baud
B134 134.5 baud
B150 150 baud
B200 200 baud
B300 300 baud
B600 600 baud
B1200 1200 baud
B1800 1800 baud
B2400 2400 baud
B4800 4800 baud
B9600 9600 baud
B19200 19200 baud
B38400 38400 baud
B57600 57,600 baud
B76800 76,800 baud
B115200 115,200 baud
EXTA External rate clock
EXTB External rate clock
CSIZE Bit mask for data bits // 传输数据位的掩模
CS5 5 data bits
CS6 6 data bits
CS7 7 data bits
CS8 8 data bits // 8 bit 数据位
CSTOPB 2 stop bits (1 otherwise) // 2 个停止位
CREAD Enable receiver // 允许接收字符
PARENB Enable parity bit // 使能校验位
PARODD Use odd parity instead of even // 使用奇校验
HUPCL Hangup (drop DTR) on last close
CLOCAL Local line ? do not change "owner" // 本地接收
of port
LOBLK Block job control output
CNEW_RTSCTS // CNEW_RTSCTS 和CRTSCTS 使能硬件流控
CRTSCTS Enable hardware flow control (notsupported on all platforms)
CLOCAL 和 CREAD 这两个选项,应该被选中。而对标志的设置,永远也不要对这些标志做初始化的操作,而应该是使用与、或 的操作,达到清零或者置一的操作。
6.1.1、波特率的设置
tcgetattr(fd, options);
struct termios options;
options.c_cflag |= (CLOCAL | CREAD);
tcgetattr(fd, option);
cfsetispeed(fd, B115200);
tcsetattr(fd, TCSANOW, options);
tcgetattr 函数,实现获取当前串口的配置信息。当完成新的配置之后,就需要将这些信息进行激活。,就使用tcsetattr。
TCSANOW Make changes now without waiting for data to complete
TCSADRAIN Wait until everything has been transmitted
TCSAFLUSH Flush input and output buffers and make the change
TCSANOW 标志,表明所做的更改设置,会立即生效,不会等待数据发送或者接收完毕,
6.1.2、设置字符大小
传输字符大小的设置,没有函数接收可以使用,而是通过 宏代码 实现。
options.c_cflag = ~CSIZE; / Mask the character size bits /
options.c_cflag |= CS8; / Select 8 data bits /
实现传输字符的设置,一定先要进行 options.c_cflag = ~CSIZE 之后,才可以进行位数的设置。
6.1.3、校验位和停止位的设置
校验位可以设置为,无校验、奇校验、偶校验,三种。
? No parity (8N1): // 8bitdata 无校验,1个停止位
options.c_cflag = ~PARENB // 关闭校验
options.c_cflag = ~CSTOPB // 一个停止位
options.c_cflag = ~CSIZE; // 8个数据位
options.c_cflag |= CS8;
? Even parity (7E1): // 7个 数据位,偶校验,一个停止位
options.c_cflag |= PARENB // 校验使能
options.c_cflag = ~PARODD // 偶校验
options.c_cflag = ~CSTOPB // 一个停止位
options.c_cflag = ~CSIZE; // 7个数据位
options.c_cflag |= CS7;
? Odd parity (7O1):
options.c_cflag |= PARENB // 校验使能
options.c_cflag |= PARODD // 奇校验
options.c_cflag = ~CSTOPB // 一个停止位
options.c_cflag |= CS7;
停止位的设定是通过 CSTOPB 实现的。如停止位为 1 ,则清除 CSTOPB。如停止位为 2,则激活 CSTOPB。
6.1.4、硬件流控的设置
一些 Linux 系统是支持硬件流控的。如果 CNEW_RTSCTS 和 CRTSCTS 在自己的系统中,是被定义的话,就可以借助他们来实现硬件流控的开启:
options.c_cflag |= CNEW_RTSCTS; / Also called CRTSCTS /
当然,也可以进行关闭:
options.c_cflag = ~CNEW_RTSCTS
6.2、local flag
本地模式,c_lflag 用于控制串口输入的字符,比如终端输入的字符是否支持回显。通常上,需要对 c_lflag 设置,实现,规范模式,或者原始模式。
ISIG Enable SIGINTR, SIGSUSP, SIGDSUSP,and SIGQUIT signals
ICANON Enable canonical input (else raw)
XCASE Map uppercase \lowercase (obsolete)
ECHO Enable echoing of input characters
ECHOE Echo erase character as BS?SP?BS
ECHOK Echo NL after kill character
ECHONL Echo NL
NOFLSH Disable flushing of input buffers after interrupt or quit characters
IEXTEN Enable extended functions
ECHOCTL Echo control characters as ^char and delete as ~?
ECHOPRT Echo erased character as character erased
ECHOKE BS?SP?BS entire line on line kill
FLUSHO Output being flushed
PENDIN Retype pending input at next read or input char
TOSTOP Send SIGTTOU for background output
如果终端的模式,设置为规范模式(标准输入),那么需要设置 ICANNO ECHO ECHOE选项。
options.c_lflag |= (ICANON | ECHO | ECHOE);
如果终端是原始模式(非标准输入),那么就需要进行不选中ICANNO ECHO ECHOE,同时添加 ISIG 选项。
options.c_lflag = ~(ICANON | ECHO | ECHOE | ISIG);
注意:
当传输的命令是传送给 MODEN 的时候,或者传送的命令是发送给已经开启了回显的 B 电脑的时候,发送端 A ,绝对不要打开回显功能(不要打开 ECHO 和 ECHOE ),因为会在两个串口之间生成回环的反馈。
6.3、输入模式
输入模式的,c_iflag ,对串口接收的 字符 进行的操作。
Constant Description
INPCK Enable parity check // 使能校验检查
IGNPAR Ignore parity errors
PARMRK Mark parity errors
ISTRIP Strip parity bits // 删除校验位
IXON Enable software flow control (outgoing)
IXOFF Enable software flow control (incoming)
IXANY Allow any character to start flow again
IGNBRK Ignore break condition
BRKINT Send a SIGINT when a break condition isdetected
INLCR Map NL to CR
IGNCR Ignore CR
ICRNL Map CR to NL
IUCLC Map uppercase to lowercase
IMAXBEL Echo BEL on input line too long
6.3.1、设置输入校验
如果在 c_cflag 中使能了 PARENB,也就是使能了校验位,那么就需要在输入模式,使能校验检测。
一般是:
options.c_iflag |= (INPCK | ISTRIP);
6.3.2、软件流控
软件流控的实现是,需要 IXON, IXOFF, and IXANY 常量
打开软件流控:
options.c_iflag |= (IXON | IXOFF | IXANY)
关闭:
options.c_iflag = ~(IXON | IXOFF | IXANY);
IXON 和 IXOFF 是被定义在 c_cc 数组当中。
6.4、输出模式
设置 c_oflag 控制的是当串口完成数据的接收,并且完成输入模式操作之后,如果将数据进行数据。数据的输出,可以进行操作,或者直接以原始的模式进行输出。
Constant Description
OPOST Postprocess output (not set = raw output)
OLCUC Map lowercase to uppercase
ONLCR Map NL to CR?NL
OCRNL Map CR to NL
NOCR No CR output at column 0
ONLRET NL performs CR function
OFILL Use fill characters for delay
OFDEL Fill character is DEL
NLDLY Mask for delay time needed between lines
NL0 No delay for NLs
NL1 Delay further output after newline for 100 milliseconds
CRDLY Mask for delay time needed to return carriage to left column
CR0 No delay for CRs
CR1 Delay after CRs depending on current column position
CR2 Delay 100 milliseconds after sending CRs
CR3 Delay 150 milliseconds after sending CRs
TABDLY Mask for delay time needed after TABs
TAB0 No delay for TABs
TAB1 Delay after TABs depending on current column position
TAB2 Delay 100 milliseconds after sending
TABs
TAB3 Expand TAB characters to spaces
BSDLY Mask for delay time needed after BSs
BS0 No delay for BSs
BS1 Delay 50 milliseconds after sending BSs
VTDLY Mask for delay time needed after VTs
VT0 No delay for VTs
VT1 Delay 2 seconds after sending VTs
FFDLY Mask for delay time needed after FFs
FF0 No delay for FFs
FF1 Delay 2 seconds after sending FFs
6.4.1、 输出的字符,如果进行操作的话,需要对 OPOST 进行设置:
options.c_oflag |= OPOST;
6.4.2、如果选择为原始数据输出的话:
options.c_oflag = ~OPOST;
当 OPOST 被关闭之后,那么对于 c_oflag 所有的设置将会被忽略。
6.5、字符控制
在 c_cc 数组中,实现了对定时器等一些操作,下面是配置信息:
Constant Description Key
VINTR Interrupt CTRL?C
VQUIT Quit CTRL?Z
VERASE Erase Backspace (BS)
VKILL Kill?line CTRL?U
VEOF End?of?file CTRL?D
VEOL End?of?line Carriage return (CR)
VEOL2 Second end?of?line Line feed (LF)
VMIN Minimum number of characters to read
VTIME Time to wait for data (tenths of seconds)
6.5.1、设置软件流控的字符
当使用了软件流控的时候,需要对,c_cc【VSTART】 和 c_cc【VSTOP】 进行设置,他们应该被设置为 DC1 和 DC3,DC1 和 DC3 在 SCII 中,代表了 XON 和 XOFF。
6.5.2、定时和字符个数的设置
MIN > 0, TIME = 0 : 读取函数在读到了 MIN 值的字符数后返回。
MIN = 0, TIME > 0 : TIME 决定了超时值,读取函数在读到一个字节的字符,或者等待读
取时间超过 TIME (t = TIME 0.1s)以后返回,也就是说,即使没有从串口中读到数
据,读取函数也会在 TIME 时间后返回。
MIN > 0, TIME > 0 : 读取函数会在收到了 MIN 字节的数据后,或者超过 TIME 时间没收
到数据后返回。此计时器会在每次收到字符的时候重新计时,也只会在收到第一个字节后才
启动。
MIN = 0, TIME = 0 : 读取函数会立即返回。实际读取到的字符数,或者要读到的字符
数,会作为返回值返回。根据 Antonino(参考 conditions), 可以使用 fcntl(fd, F_SETFL,
FNDELAY), 在读取前获得同样的结果。
7、串口的操作介
(1)头文件
#include
#include
#include
#include
#include
#include
#include
常用串口设置函数:
(1)属性的获取与设置
int tcgetattr(int fd, struct termios termios_p);
获取属性存放在 struct termios 里面,而 fd 是打开串口的的文件描述符。
int tcsetattr(int fd, int optional_actions, const struct termios termios_p); 设置属性(termios结构) // 激活自己的配置
cfgetispeed 得到输入速度
Cfgetospeed 得到输出速度
Cfsetispeed 设置输入速度
Cfsetospeed 设置输出速度
Tcdrain 等待所有输出都被传输
tcflow 挂起传输或接收
tcflush 刷清未决输入和/或输出
Tcsendbreak 送BREAK字符
tcgetpgrp 得到前台进程组ID
tcsetpgrp 设置前台进程组ID
8、串口流程
(1)保存原先串口的配置
struct termios newtio,oldtio;
tcgetattr(fd, oldtio);
获取原先串口的配置。
(2)激活本地连接和接收使能
这一步,是用于本地进行接收的。
newtio.c_cflag |= CLOCAL | CREAD;
(3)设置波特率
cfsetispeed(Opt,B19200); /设置为19200Bps/
cfsetospeed(Opt,B19200); // 设置输出的波特率为 19200
波特率的设置,都是 BXXXXX
(4)设置数据位的位数
newtio.c_cflag = ~CSIZE;
newtio.c_cflag |= CS8; // 设置数据位为 8 位
(5)设置奇偶校验
设置奇校验
newtio.c_cflag |= PARENB;
newtio.c_cflag |= PARODD;
newtio.c_iflag |= (INPCK | ISTRIP);
设置偶校验:
newtio.c_iflag |= (INPCK|ISTRIP);