Home Blog Feed

Marumugam: Serial Port Manipulation in C

Serial communications is the most popular and cheaper way of communicating between two devices. The obvious advantage is lesser number of conductors used. There are lots of information available in internet, so we’ll focus on our experiment without discussing the in-depth details.

Serial Interface

For communication between two or more devices there should be some well defined interface. In the world of Serial Communication it is specified by RS232. RS232 is defined by Electronic Industries Association (EIA). It defines the conventions to be followed for serial communication. At first, it is used for connecting telephone lines to the computer. RS232-standard specifies the voltage levels for MARK (HIGH) and SPACE (LOW).

Value Voltage-range
MARK < -3V
SPACE > +3V

Voltages between -3V and +3V is neither MARK nor SPACE

Female DB-9 RS232 Connector

marumugam-female-connector.png

Male DB-9 RS232 Connector

marumugam-male-connector.png

In this experiment we are going to use only two pins namely TXD and SGND. We connect the TXD pin to Anode of LED and the Cathode of LED is connected to SGND through a Resistor. Thats all about the circuit. The DB-9 RS232 male connector is used to connect the circuit to the PC.

Pin Symbol I/O Active HIGH/LOW Description User/Not
1 DCD Input LOW Data Carrier Detect Not Used
2 RXD Input DATA Receive Not Used
3 TXD Output DATA Transmit Used
4 DTR Output LOW Data Terminal Ready Not Used
5 SGND - GND Signal Ground Used
6 DSR Output LOW Data Set Ready Not Used
7 RTS Input LOW Request To Send Not Used
8 CTS Input LOW Clear To Send Not Used
9 RI Output - Ring Indicator Not Used

Asynchronous Communication

For the computer to understand the serial data coming into it, it needs some way to determine where one character ends and the next begins. This guide deals exclusively with asynchronous serial data.

marumugam-rs232-singalling.gif

In asynchronous mode the serial data line stays in the MARK (HIGH) state until a character is transmitted. A start bit preceeds each character and is followed immediately by each bit in the character, an optional parity bit, and one or more stop bits. The start bit is always a SPACE (LOW) and tells the computer that new serial data is available. Data can be sent or received at any time, thus the name asynchronous.

With these hardware background now we are going to dive into software part. I’m using Ubuntu Linux-10.10 ( Maverick Meerkat ). Linux already has serial port drivers. For now we’ll see how to use those drivers. I’ll discuss how serial drivers works in a separate article.

In Unix/Linux everything is file. Yes, the serial port is also treated as file. So we can write and read the data to/from serial port just like a file.

The file names are as follows:

System Port-1 Port-2
Digital UNIX /dev/tty01 /dev/tty02
HP-UX /dev/tty1p0 /dev/tty2p0
IRIX /dev/ttyf1 /dev/ttyf2
Linux /dev/ttyS0 /dev/ttyS1
Solaris /dev/ttya /devttyb

Coding:


#include <stdio.h>     // Standard input/output definitions
#include <string.h>    // String function definitions
#include <unistd.h>   // UNIX standard function definitions
#include <fcntl.h>      // File control definitions
#include <errno.h>     // Error number definitions
#include <termios.h>  // POSIX terminal control definitions

// function to open the port
int open_port(void)
{
  int port;
  //open the port and store the file descriptor in 'port'
  port = open("/dev/ttyS0", O_RDWR | O_NOCTTY | O_NDELAY);
  if (port == -1){
    // Could not open the port
    perror("open_port: Unable to open /dev/ttyS0 - ");
  }else{
    fcntl(port, F_SETFL, 0); //leave this
  }
  return (port);
}


int main()
{
  int port,n;
  char str[30];

  //termios - structure contains options for port manipulation
  struct termios specs; // for setting baud rate

  //setup part
  port = open_port();
  tcgetattr(port, &specs);

  //now the specs points to the opened port's specifications
  specs.c_cflag = (CLOCAL | CREAD ); //control flags


  //output flags
  //CR3 - delay of 150ms after transmitting every line
  specs.c_oflag = (OPOST | CR3);


  //set Baud Rate to 50bps
  cfsetospeed(&specs,B50);


  //our custom specifications set to the port
  //TCSANOW - constant that prompts the system to set
  //specifications immediately.
  tcsetattr(port,TCSANOW,&specs);

  //execution part
  printf("\nEnter the data:\t");
  scanf("%s",str);
  n = write(port,str,11); // n = no of bytes written
  if (n<0) {
    printf("\nError");
  }


  //close the port
  close(port);
  return(0);
}

Here is mine. It is no a good practice to solder individual wore. Set of six wire sleeves are available in shops. Use them.

marumugam-rs232-connector.jpg
marumugam-led1.jpg
marumugam-terminal-screenshot.png
marumugam-led2.jpg