Programming on the serial port in Linux

Source: Internet
Author: User
Tags control characters unsupported vmin

From https://www.ibm.com/developerworks/cn/linux/l-serials/

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 is less than 4% in the code element Distortion
In this case, the length of the transmission cable should be 50 feet.

The Linux operating system has provided good support for the serial port from the very beginning. This article will give a brief introduction to the serial port communication programming in Linux. If you need a deep understanding, we recommend 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.

close(fd);

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 );}

From http://www.linuxidc.com/Linux/2011-02/32253.htm

Common Data communication methods can be divided into parallel communication and serial communication.

Parallel communication refers to the use of multiple data transmission lines to send one piece of data simultaneously. It features high transmission speed and is suitable for short-distance communication, but requires high transmission speed.

Serial communication refers to the Sequential transmission of data in one position using a transmission line. It is characterized by the simplicity of communication lines. It can achieve communication with simple cables, reducing costs. It is suitable for applications with long-distance communication but slow transmission speeds. Commonly used serial ports are RS-232-C interface (the full name is "data terminal equipment (DTE) and data communication equipment (DCE) Serial Binary data exchange interface technology standard ").

UART Controller: it can work in interrupt (Interrupt) mode or DMA (Direct Memory Access) mode. The 16-byte FIFO (first-in-first-out register) supports a maximum baud rate of 230.4 kbps.

UART operation: data transmission, data receiving, interruption, baud rate, loopback mode, infrared mode, and automatic traffic control mode.

Serial port settings include: baud rate, number of start bits, number of data bits, number of Stop bits, and traffic control protocol. Here, you can configure a bandwidth of 115200, a starting bit of 1B, a data bit of 8B, a stop bit of 1B, and a traffic-free control protocol.

The names of devices corresponding to serial 1 and Serial 2 are "/dev/ttys0" and "/dev/ttys1 ".

In Linux, you can use simple "read" and "write" functions to read and write the serial port. The difference is that you need to set other parameters of the serial port.

6.4.2 serial port settings

The serial port setting mainly sets the struct termios struct value:

# Include <termios. h>

Struct termio

{

Unsigned short c_iflag;/* input mode flag */

Unsigned short c_oflag;/* output mode flag */

Unsigned short c_cflag;/* Control Mode flag */

Unsigned short c_lfag;/* Local Mode flag */

Unsigned short c_line;/* line discipline */

Unsigned short c_cc [NCC];/* control characters */

};

You can assign values to c_cflag to set the baud rate, character size, data bit, stop bit, parity bit, and hardware traffic control.

Procedure for setting serial port properties:

1. Save the original serial port configuration

For the sake of security and convenience of debugging programs in the future, you can save the configurations of the original serial port and use the tcgetattr (FD, & oldtio) function ). This function obtains the parameters related to the FD pointing to the object and saves them in the termios structure referenced by lodtio. This function can be used to test whether the configuration is correct and whether the serial port is available. After successful debugging, the function returns 0, failed, and the function returns-1.

If (tcgetattr (FD, & oldtio )! = 0)

{

Perror ("setupserial 1 ");

Return-1;

}

2. The activation options include clocal and cread.

Clocal and cread are used for local connection and enable reception, respectively. These two options are activated by bit mask.

Newtio. c_cflag | = clocal | cread;

3. Set the baud rate

The cfsetispeed and cfsetospeed functions are used to set the baud rate.

Cfsetispeed (& newtio, b115200 );

Cfsetospeed (& newtio, b115200 );

Generally, you need to set the baud rate of the input and output functions to the same. These functions return 0 and fail-1 upon success.

4. Set the character size

There are no ready-to-use functions and a bit mask is required. Generally, the bitmask in the Data bit is removed first and then set again as required.

Options. c_cflag & = ~ Csize;/* mask the character size bits */

Options. c_cflag | = cs8;

5. Set the parity bit

First, enable the check bit enable in c_cflag to mark parenb and whether to perform even verification, and also activate the parity enable in c_iflag. For example, the Code is as follows:

Newtio. c_cflag | = parenb;

Newtio. c_cflag | = parodd;

Newtio. c_iflag | = (inpck | istrip );

The enable even verification code is:

Newtio. c_iflag | = (inpck | istrip );

Newtio. c_cflag | = parenb;

Newtio. c_cflag & = ~ Parood;

6. Set the stop bit

Implemented by activating cstopb in c_cflag. If the stop bit is 1, cstopb is cleared. If the stop bit is 0, cstopb is activated. The following is the code when the stop bit is 1:

Newtio. c_cflag & = ~ Cstopb;

7. set minimum characters and wait time

If you do not have special requirements on the receiving character and waiting time, you can set it to 0:

Newtio. c_cc [vtime] = 0;

Newtio. c_cc [Vmin] = 0;

8. process the referenced object to be written.

After resetting the serial port, the referenced object to be written must be reprocessed. You can call tcflush (FD, queue_selector) to process the referenced object to be written. The Processing Method for transmitted data or received but unread data depends on the value of queue_selector.

Possible values of queue_selector:

Tciflush: refreshes the received data but does not read it.

Tcoflush: refreshes the written data but does not transmit it.

Tciolflush: refresh the received data but not read, and refresh the written data but not transmit it.

In this example, use 1:

Tcflush (FD, tciflush)

9. Activate Configuration

The function tcsetattr is used:

Function prototype: tcsetattr (FD, option, & newtio );

Newtio is a termios variable. The optional values are as follows:

Tcsanow: The changed configuration takes effect immediately.

Tcsadrain: The changed configuration takes effect after all output data written to FD is completed.

Tcsaflush: The changed configuration takes effect after all output data written to the FD reference object is completed. All accepted but read inputs are discarded before the change.

If this function is successfully called, 0 is returned, and-1 is failed.

If (tcsetattr (FD, tcsanow, & newtio ))! = 0)

{

Perror ("COM set error ");

Return-1;

}

/* Complete functions configured for serial ports. For the versatility of functions, common options are usually listed in the functions, which greatly facilitates debugging and usage in the future */
Int set_opt (int fd, int nspeed, int nbits, char nevent, int nstop)
{
Struct termios newtio, oldtio;
/* Save the existing serial port parameter settings for the test. If the serial port number or other errors occur, related error information will be displayed */
If (tcgetattr (FD, & oldtio )! = 0)
{
Perror ("setupserial 1 ");
Return-1;
}
Bzero (& newtio, sizeof (newtio ));
/* Step 1: Set the character size */
Newtio. c_cflag | = clocal | cread;
Newtio. c_cflag & = ~ Csize;
/* Set the stop bit */
Switch (nbits)
{
Case 7:
Newtio. c_cflag | = cs7;
Break;
Case 8:
Newtio. c_cflag | = cs8;
Break;
}
/* Set the parity bit */
Switch (nevent)
{
Case 'O': // odd
Newtio. c_cflag | = parenb;
Newtio. c_cflag | = parodd;
Newtio. c_iflag | = (inpck | istrip );
Break;
Case 'E': // even
Newtio. c_iflag | = (inpck | istrip );
Newtio. c_cflag | = parenb;
Newtio. c_cflag & = ~ Parodd;
Case 'N': // No parity bit
Newtio. c_cflag & = ~ Parenb;
Break;
}
/* Set the baud rate */
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;
Case 460800:
Cfsetispeed (& newtio, b460800 );
Cfsetospeed (& newtio, b460800 );
Break;
Default:
Cfsetispeed (& newtio, b9600 );
Cfsetospeed (& newtio, b9600 );
Break;
}
/* Set the stop bit */
If (nstop = 1)
Newtio. c_cflag & = ~ Cstopb;
Else if (nstop = 2)
Newtio. c_cflag | = cstopb;
/* Set the wait time and minimum characters to receive */
Newtio. c_cc [vtime] = 0;
Newtio. c_cc [Vmin] = 0;
/* Process unaccepted characters */
Tcflush (FD, tciflush );
/* Activate new configuration */
If (tcsetattr (FD, tcsanow, & newtio ))! = 0)

{
Perror ("COM set error ");
Return-1;
}
Printf ("set done! \ N ");
Return 0;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.