Original address: http://www.cnblogs.com/feisky/archive/2009/10/23/1588771.html
Linux operating system from the beginning of the serial port provides a good support, this article on Linux under the serial port communication programming simple introduction.
Introduction of Serial port
Serial port is a kind of common interface of computer, with few connecting lines, simple communication and wide use. The common serial port is the Rs-232-c interface (also known as EIA Rs-232-c), which was established in 1970 by the American Electronics Industry Association (EIA) Joint Bell System, modem manufacturers and computer terminal manufacturers for serial communication standards. Its full name is "Data terminal equipment (DTE) and data communication equipment (DCE) between the serial Binary data Interchange Interface technical standards" the standard stipulates the use of a 25-foot DB25 connector, the signal content of each pin of the connector is defined, and the level of various signals are specified. The transmission cable length should be 50 feet in case the code element distortion is less than 4%.
Linux operating system from the beginning of the serial port provides a good support, this article on Linux serial port communication Programming Simple introduction, if you want to deeply understand, it is recommended to see the reference of this article "Serial Programming Guide for POSIX Operating Systems "
Pin description of computer serial port
Serial number |
Signal Name |
Symbol |
Flow |
Function |
2 |
Send data |
TXD |
Dte→dce |
DTE sends serial data |
3 |
Receive data |
RXD |
Dte←dce |
DTE receives serial data |
4 |
Request Send |
Rts |
Dte→dce |
DTE requests DCE to switch line to send mode |
5 |
Allow send |
Cts |
Dte←dce |
DCE tells DTE line to be connected to send data |
6 |
Data Equipment ready. |
Dsr |
Dte←dce |
DCE ready. |
7 |
Signal Ground |
|
|
Signal Common Ground |
8 |
Carrier detection |
DCD |
Dte←dce |
Indicates that the DCE received the remote carrier |
20 |
The data terminal is ready. |
DTR |
Dte→dce |
DTE, ready. |
22 |
Ringing indication |
RI |
Dte←dce |
Indicates that the DCE is connected to the line and the ringing occurs. |
Serial operation
Header file required for serial port operation
#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 definitions */#include <termios.h> /*posix terminal Control definition */#include <errno.h>/ * ERROR number Definition */ |
Open the serial port
Under Linux, the serial port file is located in/dev
Serial Port one is/DEV/TTYS0
Serial Port Two for/DEV/TTYS1
Opening the serial port is done by using the standard file Open function:
int fd;/* open serial port with read/write */fd = open ("/dev/ttys0", O_RDWR), if ( -1 = = FD) {/* Cannot open serial port one */perror ("Prompt Error! ");} |
Set up the serial port
The most basic setting of the serial port includes the baud rate setting, the checksum bit and the stop bit setting.
The main setting of the serial port is to set the member values of the struct Termios structure body.
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_lflag;/* Local mode flags */unsigned char c_line; /* Line Discipline */unsigned char C_CC[NCC]; /* Control characters */}; |
Setting this structure is complicated, and I'm just going to talk about some common settings:
Baud rate setting
Here is the code to modify the baud rate:
struct termios opt;tcgetattr (FD, &opt); Cfsetispeed (&opt,b19200); /* Set to 19200bps*/cfsetospeed (&opt,b19200); tcsetattr (fd,tcanow,&opt); |
To set the baud rate example function:
/ @brief set the serial communication rate * @param FD type int Open the file handle of the serial port * @param speed type int serial port velocity * @return Void*/int speed_arr[] = {B38400 , B19200, B9600, B4800, B2400, B1200, b300,b38400, B19200, B9600, B4800, B2400, B1200, B300,};int name_arr[] = {38400, 1 9200, 9600, 4800, 2400, 38400, 19200, 9600, 4800, Max, 2400,};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); } }} |
Setting of the parity bit and stop bit:
Invalid inspection |
8 Guests |
Option.c_cflag &= ~parenb; Option.c_cflag &= ~CSTOPB; Option.c_cflag &= ~csize; Option.c_cflag |= ~cs8; |
The miraculous Test (ODD) |
7 Guests |
Option.c_cflag |= ~parenb; Option.c_cflag &= ~parodd; Option.c_cflag &= ~CSTOPB; Option.c_cflag &= ~csize; Option.c_cflag |= ~CS7; |
Even efficacy (even) |
7 Guests |
Option.c_cflag &= ~parenb; Option.c_cflag |= ~parodd; Option.c_cflag &= ~CSTOPB; Option.c_cflag &= ~csize; Option.c_cflag |= ~CS7; |
Space validation |
7 Guests |
Option.c_cflag &= ~parenb; Option.c_cflag &= ~CSTOPB; Option.c_cflag &= &~CSIZE; Option.c_cflag |= CS8; |
To set the validation function:
/*** @brief set serial data bit, stop bit and parity bit * @param FD type int open serial port file handle * @param databits type int data bit value is 7 or 8* @param stopbits type int stop bit value is 1 or @param parity type int validation type value is N,e,o,,s*/int set_parity (int fd,int databits,int stopbits,int par ity) {struct Termios options; if (Tcgetattr (fd,&options)! = 0) {perror ("Setupserial 1"); return (FALSE); }options.c_cflag &= ~csize; Switch (databits)/* Set the number of data bits */{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 ': Case ' o ': Options.c_cflag |= (parodd | PARENB); /* Set to be miraculous */Options.c_iflag |= INPCK; /* disnable parity checking */break; Case ' E ': Case ' e ': Options.c_cflag |= Parenb; /* Enable parity */Options.c_cflag &= ~parodd; /* Convert to Parity */Options.c_iflag |= INPCK; /* disnable parity checking */break;case ' s ': Case ' s ':/*as no parity*/options.c_cflag &= ~parenb;options.c_c Flag &= ~cstopb;break; default:fprintf (stderr, "Unsupported parity\n"); return (FALSE); }/* Set 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 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); } |
It is important to note that:
If it is not the development of terminals and the like, but the serial port to transmit data, and do not need to process the serial port, then use the original model (raw mode) to communicate, set up the following way:
Options.c_lflag &= ~ (Icanon | ECHO | Echoe | ISIG); /*input*/options.c_oflag &= ~opost; /*output*/ |
Read/write serial
Set up a good serial port, read and write serial port is very easy, the serial port as a file read and write is.
- Send data
Char buffer[1024]; int Length; int nbyte; Nbyte = Write (fd, buffer, Length) |
- Read serial data
The read function reads with the file operation, and if the data is transferred to the raw mode, the number of characters returned by the read functions is the number of characters received by the actual serial port.
You can use functions that manipulate files to implement asynchronous reads, such as Fcntl, or select.
Char buff[1024]; int Len; int readbyte = read (Fd,buff,len); |
Close the serial port
Closing the serial port is closing the file.
Example
Here is a simple example of reading serial data, using some of the functions and header files defined above
/************************************************* Code Description: Using the serial port two test, the data sent is a character, but did not send a string ending symbol, so received, followed by the end symbol. I test using a microcontroller to send data to the second serial port, test pass. /#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 Two FD = Opendev (dev); set_spee D (fd,19200), if (Set_parity (fd,8,1, ' N ') = = FALSE) {printf ("Set Parity error\n"); exit (0);} while (1)//loop reading data {while ((nread = read (FD, buff, >0)) {printf ("\nlen%d\n", nread); buff[nread+1] = ' n '; printf ("\n%s", buff); }}close (FD);
return 0;} |
Resources
- Serial Programming Guide for POSIX Operating Systems
- Source code for Linux
- Code Download: Code
The above articles are transferred from the IBM Linux Technical Library.
The complete function of the serial port configuration is given below. Generally, for the versatility of functions, commonly used options are listed in the function, which makes it much easier for users to debug later. The setting function is as follows:
int set_opt (int fd,int nspeed, int nBits, char nevent, int nstop) {struct Termios newtio,oldtio;/* Save test existing serial port parameter settings, here If the string number is wrong, there will be a related error message */if (tcgetattr (fd,&oldtio)! = 0) {perror ("Setupserial 1"); return-1; } bzero (&newtio, sizeof (Newtio)); /* Step one, set the character size */Newtio.c_cflag |= clocal | Cread; Newtio.c_cflag &= ~csize; /* Set Stop bit */switch (nBits) {case 7:newtio.c_cflag |= CS7; Break Case 8:newtio.c_cflag |= CS8; Break }/* Set 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; Break Case ' N '://No ParityBit Newtio.c_cflag &= ~parenb; Break }/* Set 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 stop bit */if (nstop = = 1) newtio.c_cflag &= ~CSTOPB; else if (nstop= = 2) newtio.c_cflag |= CSTOPB; /* Set wait time and minimum receive character */newtio.c_cc[vtime] = 0; Newtio.c_cc[vmin] = 0; /* Handle the non-received characters */Tcflush (Fd,tciflush); /* Activate the new configuration */if ((Tcsetattr (fd,tcsanow,&newtio))!=0) {perror ("com set error"); return-1; } printf ("Set done!\n"); return 0; }
The following gives a complete function of opening the serial port, the same writing takes into account a variety of different situations. The program looks like this:
/* Open the serial port function */int open_port (int fd,int comport) {char *dev[]={"/dev/ttys0", "/dev/ttys1", "/dev/ttys2"}; Long vdisable; if (comport==1)//serial 1 {FD = open ("/dev/ttys0", o_rdwr| o_noctty| O_ndelay); if ( -1 = = FD) {perror ("Can ' t Open Serial Port"); Return (-1); }} else if (comport==2)//serial 2 {FD = open ("/dev/ttys1", o_rdwr| o_noctty| O_ndelay); if ( -1 = = FD) {perror ("Can ' t Open Serial Port"); Return (-1); }} else if (comport==3)//serial 3 {FD = open ("/dev/ttys2", o_rdwr| o_noctty| O_ndelay); if ( -1 = = FD) {perror ("Can ' t Open Serial Port"); Return (-1); }/* Recover serial port for blocking status */if (Fcntl (FD, F_SETFL, 0) <0) printf ("Fcntl failed!\n"); else printf ("fcntl=%d\n", Fcntl (FD, f_setfl,0)); /* Test whether the terminal is set*/if (Isatty (Stdin_fileno) ==0) printf ("Standard input was not a terminal device\n"); else printf ("Isatty success!\n"); printf ("fd-open=%d\n", FD); return FD; }
Finish
Serial port Development (RPM)