Serial Communication

Hello!! Before I start this post I want to say that if anyone of you wants to add me to their linkedin network here is my profile link : in.linkedin.com/in/msminhas93/

Often we need to communicate between two devices. This can be either parallel or serial. In parallel communication there is an individual data line for each bit, so normally there would be 8 data lines for 8 bit data. In asynchronous we require only two lines. One for transmission and the other for reception.

Theory

So the main thing in serial communication is ‘baud rate’. It is nothing but the bits sent per second. In serial asynchronous communication the baud rate of both transmitter and receiver have to be equal. If there is any mismatch there is bound to be error in sending and receiving data.

Now you might wonder what is sent serially? The answer is ASCII values of the character or symbol to be transmitted is sent serially. Now ASCII is a 7 bit hex code. There is the extended ASCII code as well. You can find all the ASCII values here.

Now let us take an example. Suppose I want to send character M serially. The ASCII value of M is 0x4D. The binary equivalent is 0b01001101. Now we send this data as pulses, changing the bits after the time 1/baud_rate.

070120141331

So this is how the serial data looks like. Some of you might have this doubt that how on earth will the processor or controller come to know that the other party is transmitting data and it has to take those bits. This is a very good doubt.

The beginning of serial data is marked by a start bit and on similar grounds there is a stop bit or two. Just like one normally says ‘hello’ at the start of a conversation and ‘bye’ at the end we send the start and stop bits for the same purpose.

The other question that may arise in the mind of the curious is that what if there is noise in the system? This is a valid question as well. So there are error checking bits like parity bits which are sent along with the data serially. (Parity can be even or odd. Now if the system uses even parity, then it will make the number of ‘1’ bits in the data even by adding 1 or 0. So if the data already has even number of ones the even parity bit is 0 and if the data has odd number of ones then the even parity bit is set or is 1 so that the total number of ones in the data is even.) Well this sums up asynchronous serial communication part.

Now this is known as UART module in the microcontrollers. UART stands for universal asynchronous transmitter and receiver. Most modern microcontrollers have a dedicated hardware for asynchronous serial communication called UART. msp430 also has this facility. Now what this means that you have to just configure the peripheral and the baud rate generation, parity bits and all other factors as well as the receiving part is done by this hardware. (If you wanted to send data serially without hardware dedicated for the same you would have to make the port high and low, use delay subroutines and the rotate instructions for doing the same task. The detection will also be tedious.)

This is how the data will look when  you send it via UART module.

w_example

Well let’s begin with the USCI module that provided in the msp430 micro controllers. This provides a UART mode for asynchronous serial communication. There are few basic initialization registers like all peripherals of msp430. Note that you can use grace for initializing the UART mode. But I’ll be covering the normal method by using the command registers and configuring it to meet our needs.

Let us begin.

UART mode features include:
• 7- or 8-bit data with odd, even, or non-parity
• Independent transmit and receive shift registers
• Separate transmit and receive buffer registers
• LSB-first or MSB-first data transmit and receive
• Built-in idle-line and address-bit communication protocols for multiprocessor systems
• Receiver start-edge detection for auto-wake up from LPMx modes
• Programmable baud rate with modulation for fractional baud rate support
• Status flags for error detection and suppression
• Status flags for address detection
• Independent interrupt capability for receive and transmit

The list of all registers related to the UART mode are listed below.

registers_list

Now the procedure how to initialize these registers is given in the msp430g2 user manual.

initializing

Just set those bits which you want as per the explanation given in the user guide.

Then there are the UCA0TXBUF and UCA0RXBUF via which the serial data is transmitted and received respectively. If you want to send any character just put it in the UCA0TXBUF register and it will be transmitted. Just check whether the byte has been sent or not by checking the UCA0TXIFG bit of IFG2 register. If it is set means the module is busy sending the previous byte or data and one has to wait till it is reset.

With this background you should be able to program the controller to send and receive data.

Before we shift to the program there is something that I need to tell you. For hardware UART via launchpad without having to use the rs232 cable and max232 IC. For newer launchpad versions i.e. 1.5 and above there is the position of the jumpers printed on the launchpad itself for hardware UART and software UART respectively.

Hardware UART on Launchpad 1.4

If you have a Launchpad of v1.4 (versions that have no ‘Rev x.x’ printed below the ‘MSP-EXP430G2’ label are pre 1.5) is is possible to use hardware UART by replacing the MSP430 with a newer model, such as the MSP430G2553 and then cross connecting the serial pins in header J3 i.e the TXD and RXD(use a cross jumper or female to female wires for the same.)

Program

#include "serial.h"
#include "lcd.h"
int main(void) {
    WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
    uart_init();
    lcd_init();
    IE2 |= UCA0RXIE;
    println("START");
    __bis_SR_register(LPM0_bits + GIE);
}
#pragma vector=USCIAB0RX_VECTOR
__interrupt void USCI0RX_ISR(void)
{
	if(UCA0RXBUF == '0')
        {
            send_command(0x01);
        }
	else
        send_data(UCA0RXBUF);
}

/*
 *  serial.h
 *  Created on   	: 01-Jan-2014 12:25:06 PM
 *  Author	  	: Manpreet Singh Minhas
 *  Website		: https://learningmsp430.wordpress.com/
 *  This is a standard header for 9600 baud rate serial communication.
 */

#ifndef SERIAL_H_
#define SERIAL_H_

#include<msp430g2553.h>// Change this as per your micro-controller chip.
void uart_init(void);
void send_byte(int data);
void print(char *data);
void println(char *data);
void send_int(int a);
void send_intln(int a);
void uart_init()
{
	P1SEL  |= BIT1|BIT2; // Port for UART transmission and reception purpose.
	P1SEL2 |= BIT1|BIT2;
    UCA0CTL1 |= UCSWRST; // Software reset
    UCA0CTL1 |= UCSSEL_1;// Select ACLK
    UCA0BR0 = 3;// This is the count for getting 9600 baud rate 32768/9600 = 3.4133
    UCA0BR1 = 0;
    UCA0MCTL = UCBRS1 + UCBRS0;// Modulation bits = 0b00000011
    UCA0CTL1 &= ~UCSWRST;	// Start the UART
}
void send_byte(int data)
{
	while (!(IFG2&UCA0TXIFG));
	UCA0TXBUF = data;
}
void print(char *data)
{
	while(*data)
	{
		send_byte(*data);
		data++;
	}
}
void println(char *data)
{
	while(*data)
	{
		send_byte(*data);
		data++;
	}
	send_byte('\n');
	send_byte('\r');
}
void send_int(int a)
{
	int temp;
	int rev=0;
	int dummy =a;
	 while (dummy)
	   {
	      rev = rev * 10;
	      rev = rev + dummy%10;
	      dummy = dummy/10;
	   }
	while(rev)
	{
		temp=rev%10;
		send_byte(0x30+temp);
		rev /=10;
	}
}
void send_intln(int a)
{
	int temp;
	int rev=0;
	int dummy =a;
	 while (dummy)
	   {
	      rev = rev * 10;
	      rev = rev + dummy%10;
	      dummy = dummy/10;
	   }
	while(rev)
	{
		temp=rev%10;
		send_byte(0x30+temp);
		rev /=10;
	}
	 send_byte('\n');
	 send_byte('\r');
}
#endif/* SERIAL_H_ */

Well this program will send the data received serially to lcd. For sending data you will require a software like hyper terminal, putty, energia serial monitor, arduino serial monitor etc. So just configure that to 9600 baud rate with no parity bits and only one stop bit and you are all set to send data serially. If you have any problem you can comment or send me mail.

Video

Advertisements

6 thoughts on “Serial Communication

  1. I am using msp430f6736. In that I am using UART module to echo a received character back to the hyperterminal. I have received the data in the receive buffer of msp430. And I transfered it to the transmit buffer. After debugging using emulator, the received character is there in transmit buffer and also the transmit completer flag is also set. But I have not received anything in hyperterminal. Please help me to find out the problem.Here is my code.

    #include
    char buffer;
    void main(void)
    {
    WDTCTL = WDTPW | WDTHOLD; // Stop WDT

    // Setup LFXT1
    UCSCTL6 &= ~(XT1OFF); // XT1 On
    UCSCTL6 |= XCAP_3; // Internal load cap
    // Loop until XT1 fault flag is cleared
    do
    {
    UCSCTL7 &= ~(XT2OFFG | XT1LFOFFG | DCOFFG);
    // Clear XT2,XT1,DCO fault flags
    SFRIFG1 &= ~OFIFG; // Clear fault flags
    } while (SFRIFG1 & OFIFG); // Test oscillator fault flag

    //Setup LED //Toggle for every interrupt
    // P1DIR = BIT6 | BIT7 ; // P1.6 AND P1.7 to output direction
    // P1OUT &= ~(BIT6 | BIT7); // Clear P1.0

    // Setup P1.4 UCA0RXD, P1.5 UCA0TXD
    P1SEL |= BIT4 | BIT5 ; // Set P1.4, P1.5 to non-IO
    P1DIR |= ~BIT4 | BIT5 ; // Enable UCA1RXD, UCA1TXD

    //Setup eUSCI_A1

    UCA1CTLW0 = 0x1041; // Put state machine in reset**//ACLK//7 bit data//1 stop bit// parity disabled
    UCA1BRW = 0x0003; // 32kHz/9600=3.41
    UCA1MCTLW = 0x5300; // Modulation UCBRSx=0x53, //UCBRFx=0
    UCA1CTLW0 = 0x1040; ; // Initialize USCI state machine
    UCA1IE = 0x0003; // Enable eUSCI_A1 RX and TX interrupt

    while(1)
    {
    __bis_SR _register(LPM3_bits | GIE); // Enter LPM3, interrupts //enabled
    }
    }

    // USCI_A1 interrupt service routine
    #pragma vector=USCI_A1_VECTOR
    __interrupt void USCI_A1_ISR(void)
    {
    switch (__even_in_range(UCA1IV, 8))

    {
    case USCI_NONE: break; // No interrupt
    case USCI_UART_UCRXIFG: // RXIFG
    buffer = UCA1RXBUF;

    while (!(UCA0IFG & UCTXIFG)) ; // USCI_A1 TX buffer ready?
    UCA1TXBUF = buffer;
    P1OUT ^= BIT6 ;
    break;
    case USCI_UART_UCTXIFG:
    break; // TXIFG
    case USCI_UART_UCSTTIFG:
    break; // TTIFG
    case USCI_UART_UCTXCPTIFG:
    break; // TXCPTIFG
    default: break;
    }
    // __bic_SR_register(LPM3_bits);
    }

    • Is your ISR working properly? You have put the toggle line to test that I presume. Next thing is that are you using any launchpad for this or have you made your own pcb? Have you connected the Tx pin to Rx pin in the launchpad? If you are using launchpad check that the UART mode select jumpers are in hardware mode. If there is some external circuit and you are using rs232 to usb converter then ensure that ground pin is connected.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s