Lab 8: Asynchronous serial communication

Description

The PIC16F628A microcontroller has a built in Universal Synchronous Asynchronous Receiver Transmitter (USART) hardware that allows to communicate with a wide range of serial devices such as memory chips, LCDs, personal computers, etc. The USART module has two modes of operation: synchronous (requires a synchronized clock between the transmitter and receiver) and asynchronous (no synchronization clock required). As the asynchronous mode is more popular, we will focus today’s lab session on this and will establish a two way serial data link between the PIC microcontroller and a PC.

Required Theory

Serial communications are used in microcontroller-based systems, mostly due to the scarcity of available I/O pins. Besides for long distance communications, serial data transfer is more simple and cost effective as the required hardware connections in the data link can be reduced to three (Tx, Rx, and Gnd).

There are two different types of serial communications: synchronous and asynchronous. The key challenge in a serial data link is to maintain the synchronization between the transmitter and the receiver. The asynchronous method uses a start and stop bit protocol to synchronize the two ends. Each character byte is sent in a frame consisting of a start bit , followed by the character bits, followed (optionally) by a parity bit, and finalized by one or more stop bits. The sender and receiver have to be initialized to use the same data rate, number of data bits, and number of stop bits.

In idle condition, the transmit output is at logic high. When the transmitter is ready to send a character byte, it signals the receiver by pulling the transmit line low for one clock period. This is the start bit and it tells the receiver that a frame follows. The receiver reads the number of character bits expected according to the adopted protocol until the line is pulled to logic high by the transmitter (one or more stop bits), and that is the end of the frame. The whole process is repeated every time the transmitter has to send a character byte. This form of serial transmission is called asynchronous because the receiver resynchronizes itself to the transmitter every time the data is sent using the start bit. However, within each frame the two parties are synchronized.

On the other hand, the synchronous serial communication transmit characters in blocks with no framing bits surrounding them. The transmitter and receiver are synchronized with a separate clock line or, in some cases, the clock signal is contained in the transmitted characters. In both the types of serial communications, the rate at which the data is sent and received is known as the baud rate.

The USART module inside the PIC16F628A microcontroller supports both types of serial communications but it is best suited for the asynchronous method. In asynchronous mode, RB2 acts as a data transmit (TX) output, and RB1 as data receive (RX) input. A byte of serial data is sent as a string of 10 bits; a start bit, eight data bits, and a stop bit, as shown below.

The PC’s serial port (also known as COM port) uses the RS232-C standard for serial communication. This standard specifies the electrical, mechanical, functional signal and procedural specifications of the serial communication interface. A logic high for RS232-C is a signal voltage in the range of -3 V to -15 V (typically -12 V), and a logic low is between +3 V to +15 V (typically +12 V). So unlike the PIC microcontroller’s logic levels, an RS232-C high is a negative voltage, and a low is a positive voltage. The table below shows the standard connections for RS232-C, for 25-pin, 9-pin and RJ-45 connectors. For details on each of these signal pins, you can find tons of literature online. For this experiment, we are implementing a minimal serial interface between the PIC microcontroller and a PC by using only the TX, RX, and GND signals.

RS232 signal pins in a DB-9 female connector

We are going to use asynchronous mode to communicate with an RS232-C serial port on the PC. Since the PIC16F628A already has a built in hardware (USART) that supports asynchronous serial communication, so all that is required is an external level shifter to translate TTL signals from PIC to RS232-C levels, and vice-versa. This can be achieved by using a MAX232 chip made by Maxim. The chip requires a few external capacitors for its internal charge pumps to generate +12 V and -12 V required for the RS232-C communication. A simple way to send and receive bytes through the PC’s serial port is by using the application named HyperTerminal that comes with Windows operating system. You can open the HyperTerminal application window through Start ? Menu ? Programs ? Accessories ? Communications? Hyperterminal. You can create a connection with your serial port (e.g. COM1), choose a baud rate, number of bits, parity setting, etc. When HyperTerminal connects to the serial port, whatever character you type is sent (as ASCII) through the serial port. The received characters are also displayed on the screen.

Circuit Setup

The circuit setup for this experiment is shown below. It has the basic setup circuit from PIC16F628A breadboard module and a level shfter using MAX232 chip. The MAX232 requires four external capacitors (each 1 uF) for its internal charge pumps. A MAX232 is actually a dual driver/receiver and we are just using one. For more details on the MAX232 chip, read the datasheet. On PC’s side, only three lines are connected (Tx, Rx, and Ground) to the COM port through a 9-pin connector.

Software

As usual, the program is developed with the MikroC Pro for PIC compiler. The MikroC compiler provides UART library that supports asynchronous serial communication in full duplex mode (that means transmit and receive simultaneously). This makes the programming lot easier. For example, if you want to initialize the hardware UART module of PIC16F628A with the data rate of 9600 baud, you just need to write UART1_Init(9600). The example code given here establishes a two way asynchronous serial link between the PIC16F628A microcontroller and the PC. The microcontroller sends the message ‘Type in a Number’ that is displayed on the Hyperterminal window. When you enter any character from the keyboard, it will be sent to the microcontroller through the COM port. The PIC microcontroller will read it and send it back to the PC, which will be again displayed on the Hyperterminal window. The Hyperterminal setttings for this should be

Bits per second: 9600, Data Bits: 8, Parity: None, Stop bits: 1, Flow control: None.

/*
Lab 8: Hardware UART
MCU: PIC16F628A
External 4MHz Crystal, MCLR Enabled, PWRT Enabled, WDT OFF
Copyright @ Rajendra Bhatt
Dec 12, 2010
*/

void newline(){
 UART1_Write(13); // Carriage Return
 UART1_Write(10); // Line Feed
}

void main() {
 unsigned char MyError, Temp;
 CMCON = 7;       // Disable Comparators
 TRISB = 0b00000010;
 UART1_Init(9600);
 Delay_ms(100);
 UART1_Write_Text("Testing UART! ");
 newline();

 do {
  UART1_Write_Text("Type in a Number: ");
  while(!UART1_Data_Ready());
  Temp = UART1_Read();
  newline();
  UART1_Write_Text("You entered: ");
  UART1_Write(Temp);
  newline();
 } while(1);
}  // End main()

Download HEX file

Output

Here’s a snapshot of the output from the Hyperterminal window on my Windows XP machine. In order to display what you typed you need to turn on the ‘Echo typed character locally’ option on the settings.

Related Posts

26 comments

  • Hi, i have built my own uart code and circuit, and it works perfectly. and display con command ‘but not display on LCD .please anyone help me

  • i want to display text in c# textbox “CLEARED” to lcd via pic18f452. i am using mikroC. For serial transmission i am using a cp2120 usb-ttl module. i am simulating with proteus. Can you please correct this code i have written and explain why it is behaving…

    code for “send” button in c# is :
    private void button1_Click(object sender, EventArgs e)
    {
    string text = txt_decision.Text;
    serialPorr1.WriteLine(text);
    }

    code for PIC in mikroC is :
    //LCD INITIALISATIONS//
    char text;
    void main(){
    uart1_Init(9600);
    delay_ms(100);
    Lcd_Init();
    delay_ms(100);
    Lcd_Cmd(_lcd_clear);
    while(1){
    if (UART1_Data_Ready() == 1){
    UART1_Read_Text(text, “D”, 6);
    Lcd_Out(1,3,text);
    delay_ms(2000);
    }
    }
    }

    When i click SEND the Lcd displays EEARE then i click it again it shows RLEAR, if i click again it goes back to show EEARE….What seems to be the problem in my codes ???

  • this is my code avr atmega16 using mikroc pro for avr but not receiving anything plz help me

    sbit LCD_RS at PORTD2_bit;
    sbit LCD_EN at PORTD3_bit;
    sbit LCD_D4 at PORTD4_bit;
    sbit LCD_D5 at PORTD5_bit;
    sbit LCD_D6 at PORTD6_bit;
    sbit LCD_D7 at PORTD7_bit;

    sbit LCD_RS_Direction at DDD2_bit;
    sbit LCD_EN_Direction at DDD3_bit;
    sbit LCD_D4_Direction at DDD4_bit;
    sbit LCD_D5_Direction at DDD5_bit;
    sbit LCD_D6_Direction at DDD6_bit;
    sbit LCD_D7_Direction at DDD7_bit;
    // End LCD module connections
    char uart_rd;
    char txt1[] = “TPM TRACKING”;
    char txt2[] = “JJM”;
    char txt3[12] = “0123456789”;

    char i,j; // Loop variable
    char txt[10];
    void Interrupt()
    {
    if(RXC_bit)
    {
    txt[i]=UDR;
    i++;
    }
    RXC_bit=0;
    }

    void main()
    {
    UART1_Init(9600); // Initialize UART module at 9600 bps
    RXCIE_bit=1;
    Delay_ms(300); // Wait for UART module to stabilize
    UART1_Write_Text(“Init”);
    UART1_Write(13);
    UART1_Write(10);

    Lcd_Init();
    Lcd_Out(1,6,txt1); // Write text in first row
    Lcd_Out(2,6,txt2); // Write text in second row
    Delay_ms(200);
    Lcd_Cmd(_LCD_CLEAR); // Clear display

    while (1)
    { // Endless loop
    // If data is received,
    EEPROM_Write(0x00,txt[i]);
    Delay_ms(200);
    j = EEPROM_Read(0x00); // Read data from address 2 and display it on PORTA
    Delay_ms(200);
    Lcd_Chr_Cp(j);
    Delay_ms(200);
    Lcd_Cmd(_LCD_CLEAR); // Clear display
    }
    }

    • Could u please check and try to adjust contrast potentiometer as if it is out of contrast voltage range, nothing will be displayed ( visible) on display. It happened with me for my first project of lcd display my code and every thing was fine even i tried many times reprogramming PIC but no response i got on lcd. Finally i found that it was only contrast potentiometer improper adjustments.

  • please tell some how to get a response from the pic microcontroller

  • here is my code . but i am unable to get character what i typed.can anyone please help me

    #define USE_OR_MASKS
    #include
    #include
    #include
    #include
    #include
    #include
    #include
    #include

    #define _XTAL_FREQ 8000000 //MHz
    #define MEMCON = 0b10000000

    #define ADCON1 = 0b00001111
    #pragma config OSC = INTIO67 // Oscillator Selection bits (HS oscillator)
    #pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable bit (Fail-Safe Clock Monitor disabled)
    #pragma config IESO = OFF // Internal/External Oscillator Switchover bit (Two-Speed Start-up disabled)
    #pragma config PWRT = OFF // Power-up Timer Enable bit (PWRT disabled)
    #pragma config WDT = OFF // Watchdog Timer (WDT enabled)
    #pragma config LVP = ON // Single-Supply ICSP Enable bit (Single-Supply ICSP enabled)
    void putc1USART( char data );
    char Read1USART( void );
    char Rx; //[] = “Welcome and Enter the Data: \n\r”;
    char Tx ;

    void InitUART(void);
    void newline(void);

    //void ReadData(void);

    void main(){

    //unsigned char Temp;

    InitUART();

    puts1USART(“Testing USART \n\r”);
    Delay10KTCYx(1);

    puts1USART(“Type character:”);
    putc1USART(Rx);

    while(!DataRdy1USART());
    Rx = getc1USART();

    putc1USART(‘\n’);
    puts1USART(” Entered character is:”);
    putc1USART(Rx);
    putc1USART(‘\n’);

    }

    //Tx = getc1USART();

    //Delay10KTCYx(10);
    //putc1USART(Tx);
    //Delay10KTCYx(10);

    //} while(1);

    /*
    void newline(void){
    putc1USART(‘\n’); // Carriage Return
    putc1USART(‘\r’); // Line Feed
    }
    */

    void InitUART(void)
    {
    TRISCbits.RC6=0;
    TRISCbits.RC7=1;

    OSCCON = 0b01110010;
    RCSTA1bits.SPEN = 1;
    RCSTA1bits.RX9 = 0;
    //RCSTA1bits.SREN = 0;
    RCSTA1bits.CREN = 1;
    RCSTA1bits.ADDEN = 0;
    RCSTA1bits.FERR = 0;
    RCSTA1bits.OERR = 0;
    RCSTA1bits.RX9D = 0;

    TXSTA1bits.CSRC =0;
    TXSTA1bits.TX9 =0;
    TXSTA1bits.TXEN =0;
    TXSTA1bits.SYNC = 0;
    TXSTA1bits.SENDB = 0;
    TXSTA1bits.BRGH = 0;
    TXSTA1bits.TRMT = 0;
    TXSTA1bits.TX9D = 0;
    TXSTA1bits.TXEN =1; //——— reset Tx

    INTCONbits.GIE = 1;
    INTCONbits.PEIE = 1;
    PIE1bits.RC1IE = 1; //enable interrupt.
    PIE1bits.TX1IE = 1;
    IPR1bits.RC1IP = 1;
    IPR1bits.TX1IP = 1;

    BAUDCON1bits.BRG16=1;
    BAUDCON1bits.WUE=1;

    while (!OSCCONbits.IOFS);
    //Close1USART(); //turn off usart if was previously on
    //—–configure USART —–
    Open1USART(USART_TX_INT_OFF & USART_RX_INT_OFF & USART_ASYNCH_MODE & USART_EIGHT_BIT & USART_CONT_RX & USART_BRGH_LOW, 51);

    }

  • Where is char Myerror used for?

  • Pingback: Macam-Macam Mouse | 02113039 Aqiel Al Rosyid Noor Web Blog

  • hi, i have built my own uart code and circuit, and it works perfectly. but i want to make the uart communication wireless, so i have bought RF tx and rx pair, but it doesn’t work with the rf pair. then i’ve also found out that if give separate +5v and GND to max232 and the microcontroller then uart no longer works. plz give solution to both the problems. thanks

  • Swagata Mukherjee

    Normally when I am writing program, it is communicating with pc. but when I am doing external interrupt and using option register bits, then it is not working with pc. Can you please help.. I need to do the both external interrupt and pc communication simultaneously. please help

  • hi. i have a problem. when i use hyperterminal i must send a key to pic then it show me “Testing UART!”. how can i send a text to pc without sending a character to pic.

    thanks.

  • hi every body
    How can use a SSI(syncron serial interface) with picmicro with uart_raed()?

  • can we use pic16f688 instead of pic16f628 for interfacing with pc? please can you give me the circuit diagram and program with hex

  • Hi again!
    Thank for your reply. 🙂
    This is my final question.
    I change the code to:

    for ( k =0; k < 5; k ++){
    while(!UART1_Data_Ready());
    ch[k]= UART1_Read();
    Delay_ms (100);
    }

    what do you think about it?

  • Hi again!
    I read the Mikro help.
    I use this code to receive character by character:

    while(!UART1_Data_Ready());
    for ( k =0; k < 5; k ++){
    ch[k]= UART1_Read();
    Delay_ms (100);
    }

    Is it right?
    Thank in advance1

  • Hi,
    Can you tell me UART1_Data_Ready() and UART1_Read() in detail.
    How can i use them to receive character by character.
    The example you gave above only receive one character.
    And i have a question in you code above.
    your code is :
    while(!UART1_Data_Ready());
    Temp = UART1_Read();

    I think it mus be :
    while(UART1_Data_Ready());
    Temp = UART1_Read();
    Thank you in advance if you answer me as soon as possible!

    • Read mikroC Pro for PIC compiler manual for details on these functions. The code is correct, you are just confused with the while statement. The program pauses at the while statement until the data is ready, so it is while(!UART1_Data_Ready());.

  • Its very helpful for me.I am doing project to display readout on seven segment display from digital dial gauge display indicator using pic16f628a and rs232 communication.Baker digital dial gauge display output is in ascii character.And i want these readings to be displayed on seven segment display using pic16f628a.Dial gauge display having rs232 connection.How to program it .?Can you help me…

  • hello admin and Thanks for the tutorial

    your tutorials are of great help. I am doing a project to control a robotic arm through pc using C#. I have been looking around the whole net and cant figure it out how use the serial ports in C#. Can you please post any project considering controlling the pic controller through C or C#. This would be a great help for all of people out there who are thinking of interfacing hardware to PC…
    Regards

  • Check your hyperterminal settings once again and confirm you have the same settings that I described in the tutorial.

  • thanks for the tuto

    i tried this.

    but with hyperterminal i have many “rebonds”.
    for exemple if i press “g”, hyperterminal return fg or other characters.

    but he doesn’t return exactly the character sended.

    if you have a soluce …

    ps : scuse for my language but i ‘m french.

  • Pingback: Electronics-Lab.com Blog » Blog Archive » Tutorial on PIC Serial communication

Leave a Reply to Sanjyot Cancel reply

Your email address will not be published. Required fields are marked *