Introduction to serial ports
The serial port is a common interface for computers. It has a wide range of applications, such as a few connection lines and simple communication. Commonly used serial port is RS-232-C interface (also known as EIA RS-232-C) it was in 1970 by the American Association of Electronic Industry (EIA) the serial communication standard jointly developed by Bell systems, modem manufacturers, and computer terminal manufacturers. Its full name is "Technical Standard for Serial Binary data exchange interfaces between data terminal devices (DTE) and data communication devices (DCE)", which requires a 25-pin db25 connector, specify the signal content of each pin of the connector and the signal levels. The transmission distance should be 4% in length when the code element distortion is less than 50 feet.
The Linux operating system has provided good support for the serial port from the very beginning. This article briefly introduces the serial port communication programming in Linux, it is recommended that you refer to serial programming guide for POSIX operating systems.
Computer Serial Port Pin description
Serial number |
Signal name |
Symbol |
Flow Direction |
Function |
2 |
Send data |
Txd |
DTE → DCE |
DTE sends serial data |
3 |
Receive data |
Rxd |
DTE certificate DCE |
DTE receives serial data |
4 |
Send request |
RTS |
DTE → DCE |
DTE requests DCE to switch the line to the sending Method |
5 |
Allowed to send |
CTS |
DTE certificate DCE |
DCE indicates that the DTE line is connected and data can be sent |
6 |
Data device preparation |
DSR |
DTE certificate DCE |
DCE ready |
7 |
Signal Location |
|
|
Common Signals |
8 |
Carrier Detection |
DCD |
DTE certificate DCE |
Indicates that the DCE receives the remote carrier |
20 |
Data Terminal preparation |
DTr |
DTE → DCE |
DTE ready |
22 |
Ringing indicator |
Ri |
DTE certificate DCE |
Indicates that the DCE is connected to the line, and a ringing occurs. |
Back to Top
Serial Port operation
Header files required for serial port operations
# Include <stdio. h>/* standard input/output definition */# include <stdlib. h>/* standard function library definition */# include <unistd. h>/* UNIX standard function definition */# include <sys/types. h> # include <sys/STAT. h> # include <fcntl. h>/* file control definition */# include <termios. h>/* ppsix terminal control definition */# include <errno. h>/* Error Code definition */ |
Back to Top
Open serial port
In Linux, the serial port file is located under/dev.
Serial Port 1 is/dev/ttys0
Serial Port 2:/dev/ttys1
To open a serial port, use the standard file to open the function:
Int FD;/* Open the serial port in read/write mode */FD = open ("/dev/ttys0", o_rdwr); If (-1 = FD) {/* Unable to open serial port 1 */perror ("error message! ");} |
Back to Top
Set serial port
The most basic settings for the serial port include the baud rate settings, the verification bit, and the stop bit settings.
The serial port setting mainly sets the Member values of the struct termios struct.
Struct termio {unsigned short c_iflag;/* input mode sign */unsigned short c_oflag;/* output mode sign */unsigned short c_cflag;/* Control Mode sign */unsigned short c_lflag; /* Local Mode flags */unsigned char c_line;/* line discipline */unsigned char c_cc [NCC];/* control characters */}; |
Setting this struct is complex. Here I will only talk about some common settings:
Baud Rate Settings
The following code modifies the baud rate:
Struct termios OPT; tcgetattr (FD, & OPT); cfsetispeed (& OPT, b19200);/* set to 19200bps */cfsetospeed (& OPT, b19200); tcsetattr (FD, tcanow, & OPT ); |
Example function for setting the baud rate:
/*** @ Brief sets the serial communication rate * @ Param FD type int opens the serial port file handle * @ Param speed int serial port speed * @ return void */INT speed_arr [] = {b38400, b19200, b9600, b4800, b2400, b1200, b300, b38400, b19200, b9600, b4800, b2400, b1200, b300,}; int name_arr [] = {38400,192 00, 9600,480 0, 2400,120 0, 300,384 00, 19200,960 0, 4800,240 0, 1200,300,}; void set_speed (int fd, int speed) {int I; int status; struct termios OPT; tcgetattr (FD, & OPT); for (I = 0; I <sizeof (speed_arr)/sizeof (INT); I ++) {If (speed = name_arr [I]) {tcflush (FD, tcioflush); cfsetispeed (& OPT, speed_arr [I]); cfsetospeed (& OPT, speed_arr [I]); status = tcsetattr (fd1, tcsanow, & OPT); If (status! = 0) {perror ("tcsetattr fd1"); return;} tcflush (FD, tcioflush );}}} |
Set the verification bit and stop bit:
Invalid Verification |
8-digit |
Option. c_cflag & = ~ Parenb; Option. c_cflag & = ~ Cstopb; Option. c_cflag & = ~ Csize; Option. c_cflag | = ~ Cs8; |
Odd Effect Test (ODD) |
7-digit |
Option. c_cflag | = ~ Parenb; Option. c_cflag & = ~ Parodd; Option. c_cflag & = ~ Cstopb; Option. c_cflag & = ~ Csize; Option. c_cflag | = ~ Cs7; |
Even verification (even) |
7-digit |
Option. c_cflag & = ~ Parenb; Option. c_cflag | = ~ Parodd; Option. c_cflag & = ~ Cstopb; Option. c_cflag & = ~ Csize; Option. c_cflag | = ~ Cs7; |
Space Verification |
7-digit |
Option. c_cflag & = ~ Parenb; Option. c_cflag & = ~ Cstopb; Option. c_cflag & = &~ Csize; Option. c_cflag | = cs8; |
Set the verification function:
/*** @ Brief sets the serial data bit, stop bits and check bits * @ Param FD type int open serial port file handle * @ Param databits type int data bits value is 7 or 8 * @ Param stopbits type int Stop bits value is 1 or 2 * @ Param parity type int validation type value: N, e, O, S */INT set_parity (int fd, int databits, int stopbits, int parity) {struct termios options; If (tcgetattr (FD, & options )! = 0) {perror ("setupserial 1"); Return (false);} options. c_cflag & = ~ Csize; Switch (databits)/* set the number of digits */{Case 7: options. c_cflag | = cs7; break; case 8: options. c_cflag | = cs8; break; default: fprintf (stderr, "unsupported data size \ n"); Return (false);} switch (parity) {Case 'N ': case 'N': options. c_cflag & = ~ Parenb;/* clear parity enable */options. c_iflag & = ~ Inpck;/* enable parity checking */break; Case 'O': options. c_cflag | = (parodd | parenb);/* set it to an odd test */options. c_iflag | = inpck;/* disnable parity checking */break; Case 'E': options. c_cflag | = parenb;/* enable parity */options. c_cflag & = ~ Parodd;/* convert to an even test */options. c_iflag | = inpck;/* disnable parity checking */break; Case's ':/* as no parity */options. c_cflag & = ~ Parenb; options. c_cflag & = ~ Cstopb; break; default: fprintf (stderr, "unsupported parity \ n"); Return (false) ;}/ * set the stop bit */switch (stopbits) {Case 1: options. c_cflag & = ~ Cstopb; break; Case 2: options. c_cflag | = cstopb; break; default: fprintf (stderr, "unsupported Stop bits \ n"); Return (false);}/* set input parity option */If (parity! = 'N') options. c_iflag | = inpck; tcflush (FD, tciflush); options. c_cc [vtime] = 150;/* set timeout of 15 seconds */options. c_cc [Vmin] = 0;/* update the options and do it now */If (tcsetattr (FD, tcsanow, & options )! = 0) {perror ("setupserial 3"); Return (false);} return (true );} |
Note that:
If it is not a development terminal, but a serial port is used to transmit data, instead of a serial port for processing, the original mode (RAW mode) is used for communication. The setting method is as follows:
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG); /*Input*/options.c_oflag &= ~OPOST; /*Output*/ |
Back to Top
Read/write serial port
After setting the serial port, it is easy to read and write the serial port.
- Send data
char buffer[1024];int Length;int nByte;nByte = write(fd, buffer ,Length) |
- Reading serial data
Use the file operation READ function to read data. If the data is transmitted in RAW mode, the number of characters returned by the READ function is the number of characters actually received by the serial port.
You can use functions of Operation files to Implement Asynchronous reading, such as fcntl or select operations.
char buff[1024];int Len;int readByte = read(fd,buff,Len); |
Back to Top
Close serial port
Close the serial port is to close the file.
Back to Top
Example
The following is a simple example of reading serial data. Some functions and header files defined above are used.
/*************************************** ******************************* Code Description: in the serial port 2 test, the sent data is a character, but no end symbol is sent. Therefore, after receiving the data, the end symbol is added. I used a single-chip microcomputer to send data to the second serial port. The test passed. **************************************** * ****************************/# Define false-1 # define true 0 /*************************************** * ****************************/INT opendev (char * Dev) {intfd = open (Dev, o_rdwr); // | o_noctty | o_ndelayif (-1 = FD) {perror ("can't open serial port "); return-1;} elsereturn FD;} int main (INT argc, char ** argv) {int FD; int nread; char buff [512]; char * Dev = "/dev/ttys1"; // Serial Port 2 FD = opendev (Dev); set_speed (FD, 19200); If (set_parity (FD, 'N') = false) {printf ("set parity error \ n"); exit (0);} while (1) // cyclically read data {While (nread = read (FD, buff, 512)> 0) {printf ("\ nlen % d \ n", nread ); buff [nread + 1] = '\ 0'; printf ("\ n % s", buff) ;}// close (FD ); // exit (0 );} |
References
- Serial programming guide for POSIX Operating Systems
- Linux source code
- Download Code: Code
About the author
Zuo Jin, working in Nansha Information Technology Park, loves Linux, Java, and blue sky and white clouds. Contact him through the zuo170@163.com.