Linux串口通信编程

Linux串口编程(C++)

一、串口的开启

1.1 头文件包含

打开相应串口之前,把相关的头文件引入程序。

#include <termios.h>
#include <unistd.h>
#include <fcntl.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/iotcl.h>

  • <termios.h>:定义了大量的参数结构,用于串口的参数设置。一个重要的结构体是struct termios。
  • <unistd.h> :C 和 C++ 程序设计语言中提供对 POSIX 操作系统 API 的访问功能的头文件的名称。对于类 Unix 系统,unistd.h 中所定义的接口通常都是大量针对系统调用的封装(英语:wrapper functions),如 fork、pipe 以及各种 I/O 原语(read、write、close 等等)。Linux下开发的C程序都需要头文件unistd.h,但VC中没有个头文件。
  • <fcntl.h>:fcntl.h定义了很多宏和open,fcntl函数原型。
  • <stdio.h>:getchar()、putchar()、scanf()、printf()、gets()、puts()、sprintf()
  • <stdlib.h>:义了五种类型、一些宏和通用工具函数。常用的函数如malloc()、calloc()、realloc()、free()、system()、atoi()、atol()、rand()、srand()、exit()等等。
  • <sys/types.h>:是Unix/Linux系统的基本系统数据类型的头文件,含有size_t,time_t,pid_t等类型。
  • <sys/stat.h>:文件状态,是unix/linux系统定义文件状态所在的伪标准头文件。stat函数可以返回一个结构,里面包括文件的全部属性。
  • <sys/iotcl.h>:ioctl()是I/O操作的杂货箱。大部分驱动除了提供对设备的读写操作外,还须要提供对硬件控制的接口,比方查询一个framebuffer设备能提供多大的分辨率,读取一个RTC设备的时间,设置一个gpio的高低电平等等。而这些对硬件操作能力的实现一般都是通过ioctl方法来实现的。

1.2 串口开启

char * portname = "/dev/ttyUSB0";
int baudrate = 9600;
int fd = open(portname,O_RDWR|O_NOCTTY|O_NDELAY);
if(fd<0)
{
    perror(fd);exit(-1);
}else
{
    printf("open device %s succeed!\n",portname);
}

1.3 串口参数设置

//串口参数结构实例
struct termios portparams;
memset(&portparams,0,sizeof(portparams));
//获取现有串口参数  <termios.h>
tcgetattr(fd,&portparams);
//波特率
switch(baudrate)
{
    case 9600:
        buadrate = B9600;
        break;
    case 115200:
        baudrate = B115200;
        break;
}
//设置串口的c_cflag
portparams.c_cflag |= (CLOCAL | CREAD | O_NDELAY);
portparams.c_cflag &= ~CSTOPB;
portparams.c_cflag &= ~CSIZE;
portparams.c_cflag &= ~PARENB;
portparams.c_cflag |= CS8;
//设置串口的c_iflag
portparams.c_iflag |=IGNBRK;
//设置串口的c_oflag
portparams.c_oflag =& ~OPOST;
//设置串口的c_lflag
portparams.c_lflag =& (ISIG | ICANON | XCASE | ECHO | ECHOE | ECHOK | ECHONL | ECHOCTL | ECHOKE | IEXTEN);
//设置串口的c_cc
portparams.c_cc[VMIN]=60;
portparams.c_cc[VMIN]=1;
//清除IO buffer
tcflush(df,TCFLUSH);
//写入串口设置参数
int succeed = tcsetattr(fd,TCSANOW,&portparams);
if(succeed !=0)
{
    printf("set port failed!\n");
}
else
{
    printf("set port succeed!\n");
}

struct termios参数设置详细说明:

tcflag_t c_iflag;      /* input modes */
tcflag_t c_oflag;      /* output modes */
tcflag_t c_cflag;      /* control modes */
tcflag_t c_lflag;      /* local modes */
cc_t     c_cc[NCCS];   /* special characters */

二、串口的读写

2.1 基本读写

2.1.1 read(int fd,char * buff,int size)

 读取缓冲区:fd表示串口描述号,buff表示装存读取内容的内存,size表示读取多少个字符。

 返回值有0,-1,或者读取的字符数。

 -1表示读取出错;

2.1.2 write(int fd, char *buff, int size)

 向目标设备写数据。

 fd表示设备描述号,buff表示写的数据的内存地址,size表示写入数据量。

2.2 协议化读写

很多设备数据的发送是根据协议进行发送,对串口的读写必须按照协议进行。其中有以下几个问题需要解决:

  1. 发送数据的协议化
  2. 接收数据的协议化提取

不同设备读写的规则是不一样的。例如:

  1. 发送数据后,会返回数据。
  2. 发送数据后,不返回数据。
  3. 发送心跳报文。
  4. 不发送心跳报文。

等等。

进行读取和发送时,可以采用多线程实现。主线程进行发送,副线程用来读取和提取信息。

 

2.3  字符模板匹配

 

附录1 - struct termios 参数常量

c_iflag

c_iflag constants

 

IGNBRK

Ignore BREAK condition on input.

BRKINT

If IGNBRK is set, a BREAK is ignored. If it is not set but BRKINT is set, then a BREAK causes the input and output queues to be flushed, and if the terminal is the controlling terminal of a foreground process group, it will cause a SIGINT to be sent to this foreground process group. When neither IGNBRK nor BRKINT are set, a BREAK reads as a null byte ('\0'), except when PARMRK is set, in which case it reads as the sequence \377 \0 \0.

IGNPAR

Ignore framing errors and parity errors.

PARMRK

If IGNPAR is not set, prefix a character with a parity error or framing error with \377 \0. If neither IGNPAR nor PARMRK is set, read a character with a parity error or framing error as \0.

INPCK

Enable input parity checking.

ISTRIP

Strip off eighth bit.

INLCR

Translate NL to CR on input.

IGNCR

Ignore carriage return on input.

ICRNL

Translate carriage return to newline on input (unless IGNCR is set).

IUCLC

(not in POSIX) Map uppercase characters to lowercase on input.

IXON

Enable XON/XOFF flow control on output

IXANY

(XSI) Typing any character will restart stopped output. (The default is to allow just the START character to restart output.)

IXOFF

Enable XON/XOFF flow control on input.

IMAXBEL

(not in POSIX) Ring bell when input queue is full. Linux does not implement this bit, and acts as if it is always set.

IUTF8 (since Linux 2.6.4)

(not in POSIX) Input is UTF8; this allows character-erase to be correctly performed in cooked mode.

c_oflag

c_oflag flag constants defined in POSIX.1:

 

OPOST

Enable implementation-defined output processing.

 

The remaining c_oflag flag constants are defined in POSIX.1-2001, unless marked otherwise.

OLCUC

(not in POSIX) Map lowercase characters to uppercase on output.

ONLCR

(XSI) Map NL to CR-NL on output.

OCRNL

Map CR to NL on output.

ONOCR

Don't output CR at column 0.

ONLRET

Don't output CR.

OFILL

Send fill characters for a delay, rather than using a timed delay.

OFDEL

(not in POSIX) Fill character is ASCII DEL (0177). If unset, fill character is ASCII NUL ('\0'). (Not implemented on Linux.)

NLDLY

Newline delay mask. Values are NL0 and NL1. [requires _BSD_SOURCE or _SVID_SOURCE or _XOPEN_SOURCE]

CRDLY

Carriage return delay mask. Values are CR0, CR1, CR2, or CR3. [requires _BSD_SOURCE or _SVID_SOURCE or _XOPEN_SOURCE]

TABDLY

Horizontal tab delay mask. Values are TAB0, TAB1, TAB2, TAB3 (or XTABS). A value of TAB3, that is, XTABS, expands tabs to spaces (with tab stops every eight columns). [requires _BSD_SOURCE or _SVID_SOURCE or _XOPEN_SOURCE]

BSDLY

Backspace delay mask. Values are BS0 or BS1. (Has never been implemented.) [requires _BSD_SOURCEor _SVID_SOURCE or _XOPEN_SOURCE]

VTDLY

Vertical tab delay mask. Values are VT0 or VT1.

FFDLY

Form feed delay mask. Values are FF0 or FF1. [requires _BSD_SOURCE or _SVID_SOURCE or _XOPEN_SOURCE]

c_cflag

c_cflag flag constants

 

CBAUD

(not in POSIX) Baud speed mask (4+1 bits). [requires _BSD_SOURCE or _SVID_SOURCE]

CBAUDEX

(not in POSIX) Extra baud speed mask (1 bit), included in CBAUD. [requires _BSD_SOURCE or _SVID_SOURCE] (POSIX says that the baud speed is stored in the termios structure without specifying where precisely, and provides cfgetispeed() and cfsetispeed() for getting at it. Some systems use bits selected by CBAUD in c_cflag, other systems use separate fields, for example, sg_ispeed and sg_ospeed.)

CSIZE

Character size mask. Values are CS5, CS6, CS7, or CS8.

CSTOPB

Set two stop bits, rather than one.

CREAD

Enable receiver.

PARENB

Enable parity generation on output and parity checking for input.

PARODD

If set, then parity for input and output is odd; otherwise even parity is used.

HUPCL

Lower modem control lines after last process closes the device (hang up).

CLOCAL

Ignore modem control lines.

LOBLK

(not in POSIX) Block output from a noncurrent shell layer. For use by shl (shell layers). (Not implemented on Linux.)

CIBAUD

(not in POSIX) Mask for input speeds. The values for the CIBAUD bits are the same as the values for the CBAUD bits, shifted left IBSHIFT bits. [requires _BSD_SOURCE or _SVID_SOURCE] (Not implemented on Linux.)

CMSPAR

(not in POSIX) Use "stick" (mark/space) parity (supported on certain serial devices): if PARODD is set, the parity bit is always 1; if PARODD is not set, then the parity bit is always 0). [requires _BSD_SOURCE or _SVID_SOURCE]

CRTSCTS

(not in POSIX) Enable RTS/CTS (hardware) flow control. [requires _BSD_SOURCE or _SVID_SOURCE]

 

 

c_lflag

c_lflag flag constants:

 

ISIG

When any of the characters INTR, QUIT, SUSP, or DSUSP are received, generate the corresponding signal.

ICANON

Enable canonical mode (described below).

XCASE

(not in POSIX; not supported under Linux) If ICANON is also set, terminal is uppercase only. Input is converted to lowercase, except for characters preceded by . On output, uppercase characters are preceded by \ and lowercase characters are converted to uppercase. [requires _BSD_SOURCE or _SVID_SOURCE or _XOPEN_SOURCE]

ECHO

Echo input characters.

ECHOE

If ICANON is also set, the ERASE character erases the preceding input character, and WERASE erases the preceding word.

ECHOK

If ICANON is also set, the KILL character erases the current line.

ECHONL

If ICANON is also set, echo the NL character even if ECHO is not set.

ECHOCTL

(not in POSIX) If ECHO is also set, terminal special characters other than TAB, NL, START, and STOP are echoed as ^X, where X is the character with ASCII code 0x40 greater than the special character. For example, character 0x08 (BS) is echoed as ^H. [requires _BSD_SOURCE or _SVID_SOURCE]

ECHOPRT

(not in POSIX) If ICANON and ECHO are also set, characters are printed as they are being erased. [requires _BSD_SOURCE or _SVID_SOURCE]

ECHOKE

(not in POSIX) If ICANON is also set, KILL is echoed by erasing each character on the line, as specified by ECHOE and ECHOPRT. [requires _BSD_SOURCE or _SVID_SOURCE]

DEFECHO

(not in POSIX) Echo only when a process is reading. (Not implemented on Linux.)

FLUSHO

(not in POSIX; not supported under Linux) Output is being flushed. This flag is toggled by typing the DISCARD character. [requires _BSD_SOURCE or _SVID_SOURCE]

NOFLSH

Disable flushing the input and output queues when generating signals for the INT, QUIT, and SUSP characters.

TOSTOP

Send the SIGTTOU signal to the process group of a background process which tries to write to its controlling terminal.

PENDIN

(not in POSIX; not supported under Linux) All characters in the input queue are reprinted when the next character is read. (bash(1) handles typeahead this way.) [requires _BSD_SOURCE or _SVID_SOURCE]

IEXTEN

Enable implementation-defined input processing. This flag, as well as ICANON must be enabled for the special characters EOL2, LNEXT, REPRINT, WERASE to be interpreted, and for the IUCLC flag to be effective.

 

 

c_cc

c_cc array

 

VDISCARD

(not in POSIX; not supported under Linux; 017, SI, Ctrl-O) Toggle: start/stop discarding pending output. Recognized when IEXTEN is set, and then not passed as input.

VDSUSP

(not in POSIX; not supported under Linux; 031, EM, Ctrl-Y) Delayed suspend character (DSUSP): send SIGTSTP signal when the character is read by the user program. Recognized when IEXTEN and ISIG are set, and the system supports job control, and then not passed as input.

VEOF

(004, EOT, Ctrl-D) End-of-file character (EOF). More precisely: this character causes the pending tty buffer to be sent to the waiting user program without waiting for end-of-line. If it is the first character of the line, the read(2) in the user program returns 0, which signifies end-of-file. Recognized when ICANON is set, and then not passed as input

VEOL

(0, NUL) Additional end-of-line character (EOL). Recognized when ICANON is set.

VEOL2

(not in POSIX; 0, NUL) Yet another end-of-line character (EOL2). Recognized when ICANON is set.

VERASE

(0177, DEL, rubout, or 010, BS, Ctrl-H, or also #) Erase character (ERASE). This erases the previous not-yet-erased character, but does not erase past EOF or beginning-of-line. Recognized when ICANON is set, and then not passed as input.

VINTR

(003, ETX, Ctrl-C, or also 0177, DEL, rubout) Interrupt character (INTR). Send a SIGINT signal. Recognized when ISIG is set, and then not passed as input.

VKILL

(025, NAK, Ctrl-U, or Ctrl-X, or also @) Kill character (KILL). This erases the input since the last EOF or beginning-of-line. Recognized when ICANON is set, and then not passed as input.

VLNEXT

(not in POSIX; 026, SYN, Ctrl-V) Literal next (LNEXT). Quotes the next input character, depriving it of a possible special meaning. Recognized when IEXTEN is set, and then not passed as input.

VMIN

Minimum number of characters for noncanonical read (MIN).

VQUIT

(034, FS, Ctrl-) Quit character (QUIT). Send SIGQUIT signal. Recognized when ISIG is set, and then not passed as input.

VREPRINT

(not in POSIX; 022, DC2, Ctrl-R) Reprint unread characters (REPRINT). Recognized when ICANON and IEXTEN are set, and then not passed as input.

VSTART

(021, DC1, Ctrl-Q) Start character (START). Restarts output stopped by the Stop character. Recognized when IXON is set, and then not passed as input.

VSTATUS

(not in POSIX; not supported under Linux; status request: 024, DC4, Ctrl-T). Status character (STATUS). Display status information at terminal, including state of foreground process and amount of CPU time it has consumed. Also sends a SIGINFO signal (not supported on Linux) to the foreground process group.

VSTOP

(023, DC3, Ctrl-S) Stop character (STOP). Stop output until Start character typed. Recognized when IXONis set, and then not passed as input.

VSUSP

(032, SUB, Ctrl-Z) Suspend character (SUSP). Send SIGTSTP signal. Recognized when ISIG is set, and then not passed as input.

VSWTCH

(not in POSIX; not supported under Linux; 0, NUL) Switch character (SWTCH). Used in System V to switch shells in shell layers, a predecessor to shell job control.

VTIME

Timeout in deciseconds for noncanonical read (TIME).

VWERASE

(not in POSIX; 027, ETB, Ctrl-W) Word erase (WERASE). Recognized when ICANON and IEXTEN are set, and then not passed as input.

猜你喜欢

转载自www.cnblogs.com/tiderfang/p/9199196.html