m
Line 1: Line 1:
 
[[Category:8051_tutorials]]
 
[[Category:8051_tutorials]]
=Video Tutorials=
+
In this tutorial, we are going to discuss the serial/UART communication of 8051. After understating the basics of 8051 UART module, We will see how to use the ExploreEmbedded libraries to communicate with any of the UART devices.<br><br>
==UART 8051 Part-1==
+
{{#ev:youtube|oIt-8XQxWKI|680}}
+
==UART 8051 Part-2==
+
{{#ev:youtube|MnwysbYYxk4|680}}
+
  
 +
[[File:0 UART main.gif]]
  
=UART Serial communication using 8051=
 
{{Box|type=l_green_light|text=
 
We have covered the [[8051_timers|basics of timers]] in the previous tutorial, with that we can see how can a microcontroller communicate with a computer serially.
 
  
==The basics==
+
=UART Registers=
There are two ways to connect a microcontroller to a computer.
+
The below table shows the registers associated with 8051 UART.<br>
* Using RS232 protocol to the legacy serial port.
+
{| class="table table-striped table-hover table-condensed table-bordered"
* Using a USB to serial convertor.
+
|-class="info"
From microcontroller programming point of view, there is fundamentally no difference.
+
!Register || Description
The communication between the computer and micrcontroller is asynchronous and full duplex.
+
*'''Asynchronous''': There is no fixed clock to synchronize transmission of data; rather a fix bit rate is specified at both transmitter and receiver, termed as '''Baud Rate'''. In simple words, it specifies number of bit received/transmitted in 1 second. With that transmitter and receiver get to know time duration for each bit transfer.
+
*'''Full Duplex'''Both computer and micrcontroller have the hardware capability to transmit and receive at the same time.
+
 
+
==The protocol==
+
'''RS232''':It is a legacy standard for serial communication.  The standard defines the electrical characteristics and timing of signals, the meaning of signals, and the physical size and pin-out of connectors.
+
==='''RS232 Signals'''===
+
There are various signal for handshaking and communication in RS232 protocol. These are hardly used with modern computers, hence we will see '''Transmit(Tx)''' and '''Receive(Rx)''' Signals only.
+
==='''Voltage Levels'''===
+
Table below shows the voltage levels for RS232. They are significantly different from the TTL high(5v) and Low(0v). Hence a line driver like the MAX232 is required as shown in the schematic.
+
}}
+
{| class="wikitable" style="text-align:center;background-color:#87A96B;margin: 1em auto 1em auto;"
+
 
|-
 
|-
!Logic level||Voltages(V)
+
|SCON|| Serial Control Register
 
|-
 
|-
| 0 ||+3 to +25V
+
|TCON|| Timer Control Register for Baud Rate Generator
 
|-
 
|-
| 1 ||-3 to -25V
+
|TMOD|| Timer Mode Control for Baud Rate Generator
 
|-
 
|-
| Z ||+3 to -3V
+
|SBUFF||Serial Buffer holds the data to be transmitted and the data received
 
|}
 
|}
 +
<br><br>
  
 
+
=UART Register Configuration=
==8051 Serial communication Registers ==
+
Now lets see how to configure the individual registers for UART communication.
===SBUFF: Serial buffer register===
+
{| class="table table-striped table-hover table-condensed table-bordered"
{{Box|type=l_green_light|text=
+
|-class="info"
The important registers for serial communication are:
+
|SCON
* '''SBUFF''', it is a serial buffer for data. It holds 8 bit data that needs to be transmitted or the data that is received. Since the serial port of 8051 is '''full duplex''', the microcontroller internally manages to transmit and receive data into the buffer register simultaneously.
+
}}
+
 
+
{| class="wikitable" style="text-align:center;background-color:#87A96B;margin: 1em auto 1em auto;"
+
 
|-
 
|-
!colspan = '8'|SBUFF
+
|7 || 6 ||  5 || 4 || 3 || 2 || 1 || 0 
 
|-
 
|-
|D7||D6||D5||D4||D3||D2||D1||D0
+
|SM0||SM1||SM2||REN||TB8||RB8||TI||RI
 
|}
 
|}
  
===SCON: Serial Control Register===
+
<b>SM0,SM1</b> Serial port mode selection<br>
{{Box|type=l_green_light|text=
+
{| class="table table-striped table-hover table-condensed table-bordered"
*'''SCON; Serial Control register''' SCON is also an 8 bit register used for configuring different modes for serial communication as described below.
+
|-class="info"
}}
+
 
+
{| class="wikitable" style="text-align:center;background-color:#87A96B;margin: 1em auto 1em auto;"
+
|-
+
!colspan = '8'|SCON
+
|-
+
|D7||D6||D5||D4||D3||D2||D1||D0
+
|-
+
|SM0||SM1||SM2||REN||TB8||RB8||TI||RI 
+
|}
+
{{Box|type=l_green_light|text=<br />
+
*SM0 - Serial port mode bit 0 is used for serial port mode selection.
+
*SM1 - Serial port mode bit 1.
+
}}
+
{| class="wikitable" style="text-align:center;background-color:#87A96B;margin: 1em auto 1em auto;"
+
|-
+
 
!SM0||SM1||Operation||Description||Baud Rate Source
 
!SM0||SM1||Operation||Description||Baud Rate Source
 
|-
 
|-
 
|0||0||Mode 0|| 8bit ShiftReg||1/12 the quartz frequency
 
|0||0||Mode 0|| 8bit ShiftReg||1/12 the quartz frequency
|-style="background: blue; color: white"
+
|-
 
|0||1||Mode 1|| 8 bit UART||Determined by the timer 1
 
|0||1||Mode 1|| 8 bit UART||Determined by the timer 1
 
|-
 
|-
Line 82: Line 45:
 
|1||1||Mode 0|| 9 bit UART||Determined by the timer 1
 
|1||1||Mode 0|| 9 bit UART||Determined by the timer 1
 
|}
 
|}
{{Box|type=l_green_light|text=<br />
+
 
*'''SM2 - Serial port mode 2 bit''', also known as multiprocessor communication enable bit. When set, it enables multiprocessor communication in mode 2 and 3, and eventually mode 1. It should be cleared in mode 0.
+
*<b>SM2 - Serial port mode 2 bit</b>, also known as multiprocessor communication enable bit. When set, it enables multiprocessor communication in mode 2 and 3, and eventually mode 1. It should be cleared in mode 0.
 
*'''REN - Reception Enable bit''' enables serial reception when set. When cleared, serial reception is disabled.
 
*'''REN - Reception Enable bit''' enables serial reception when set. When cleared, serial reception is disabled.
 
*'''TB8 - Transmitter bit 8'''. Since all registers are 8-bit wide, this bit solves the problem of transmitting the 9th bit in modes 2 and 3. It is set to transmit a logic 1 in the 9th bit.
 
*'''TB8 - Transmitter bit 8'''. Since all registers are 8-bit wide, this bit solves the problem of transmitting the 9th bit in modes 2 and 3. It is set to transmit a logic 1 in the 9th bit.
 
*'''RB8''' - Receiver bit 8 or the 9th bit received in modes 2 and 3. Cleared by hardware if 9th bit received is a logic 0. Set by hardware if 9th bit received is a logic 1.
 
*'''RB8''' - Receiver bit 8 or the 9th bit received in modes 2 and 3. Cleared by hardware if 9th bit received is a logic 0. Set by hardware if 9th bit received is a logic 1.
*'''TI''' - Transmit Interrupt flag is automatically set at the moment the last bit of one byte is sent. It's a signal to the processor that the line is available for a new byte transmit. It must be cleared from within the software.
+
*'''TI''' - Transmit Interrupt flag is automatically set at the moment the last bit of one byte is sent. It's a signal to the processor that the line is available for a new byte to transmit. It must be cleared from within the software.
*'''RI''' - Receive Interrupt flag is automatically set upon one byte receive. It signals that byte is received and should be read quickly prior to being replaced by a new data. This bit is also cleared from within the software.
+
*'''RI''' - Receive Interrupt flag is automatically set upon one-byte receive. It signals that byte is received and should be read quickly prior to being replaced by a new data. This bit is also cleared from within the software.
  
==The Baud Rate==
 
As discussed earlier, both transmitter and receiver should agree upon a fixed data transfer rate known as baud rate. For the 8051 the '''Timer 1''' is used to generate the baud rate in '''Auto reload mode''.
 
[[File:8051 Baud Rate.jpeg|thumbnail|x100px|Fig: Baud rate at 11.0592Mhz Crystal]]
 
The crystal frequency '''Fclk''' is divided by 12 internally which is used to execute instructions also known as Machine Clock. Mclk. The timer again divides the Mclk by 32 and uses it as timer frequecny, say Tclk.
 
  
Usually a 11.0592 Mhz crystal oscillator is used to provide clock to 8051. The value seems to be odd but we see how it makes sense.
+
{| class="table table-striped table-hover table-condensed table-bordered"
From above discussion<br/>
+
|-class="info"
     
+
|RCSTA
'''''Mclk = Fclk / 12 = 11.0592MHz/12 = 921.6KHz'''''<br/>
+
 
+
'''''Tclk = Mclk/32= 921.6KHz/32 = 28.8KHz''''' <br\>
+
 
+
If we look at the standard baud rates used for serial communication shown in the table below, we can observe that all the baud rates are factors or multiples of the  Tclk (28.8K)! This results in low error rates and hence is a commonly used crystal with 8051.
+
}}
+
{| class="wikitable" style="text-align:center;background-color:#87A96B;margin: 1em auto 1em auto;"
+
 
|-
 
|-
!Baud Rate|| Multiple (or Factor)
+
|7 || 6 ||  5 || 4 || 3 || 2 || 1 || 0 
 
|-
 
|-
|2400||Tclk/'''12'''
+
|SPEN || RX9 || SREN || CREN || ADDEN || FERR || OERR || RX9D
|-
+
|4800||Tclk/'''6'''
+
|-
+
|9600||Tclk/'''3'''
+
|-
+
|115200||Tclk*'''4'''
+
|-
+
|14400||Tclk*'''5'''
+
 
|}
 
|}
  
=The Schematic=
+
<b>SPEN:</b> Serial Port Enable bit<br>
{{Box|type=l_green_light|text=
+
1 = Serial port enabled (configures RC7/RX/DT and RC6/TX/CK pins as serial port pins)<br>
As discussed earlier, we can connect the 8051 microcontroller using RS232 line driver or using a USB to Serial converter like CP2102, as shown in the figure.
+
0 = Serial port disabled
}}
+
{{scroll box|width=650px|height=500px|text=<br />
+
[[File:8051 SERIALCOMMN Interface.PNG|x550px]]
+
}}
+
=The Code=
+
{{Box|type=l_green_light|text=
+
Again for this example we will divide the code into 2 '''c'''files. '''main.c''' contains the usage of the xplore labz '''UART.c''' library.
+
}}
+
===main.c===
+
{{Box|type=l_green_light|text=
+
The '''uart.h''' contains all the functions for initializing the UART, transmit/receive characters, strings and numbers.
+
The program receives a string and replies back the same string for ever!
+
As the program is very simple, let us see the '''uart.c''' in more detail.
+
}}
+
<syntaxhighlight>
+
#include <reg51.h>  
+
 
+
#include "uart.h" //Xplore Labz UART library
+
 
+
/* start the main program */
+
void main()
+
{
+
    char msg[50];
+
    UART_Init(); // function to initialzie UART
+
+
  while(1)
+
    {
+
 
+
UART_TxString("\n\n\rEnter a new String: ");
+
UART_RxString(msg); 
+
        UART_TxString("\n\rEntered String: ");
+
        UART_TxString(msg); //Transmit the received string
+
    }  
+
 
+
}
+
</syntaxhighlight>
+
==Basic functions uart.c==
+
{{Box|type=l_green_light|text=
+
The entire [[8051_Family_C_Library#Uart.c:_8051_Uart_C-Libraray|'''uart.c''']] library contains various functions let us discuss the few used in this tutorial.
+
'''''UART_Init()'''''
+
<syntaxhighlight>
+
void UART_Init()
+
{
+
      TMOD |=0x20; //Timer1 in Mode2.
+
      TH1=-3;    // 9600 Baud rate at 11.0592MHz
+
      SCON=0x50; // Asynchronous mode 8-bit data and 1-stop bit
+
      TR1=1;    //Turn ON the timer.
+
}
+
</syntaxhighlight>
+
This function initializes the UART module in 8051.<br/>
+
*Timer 1  is setup in 8-bit auto reload mode as discussed
+
earlier<br/>
+
*To get the baud rate of 9600 at 11.0592MHz crystal, we can see from the baud rate table that it requires a factor of three. Hence TH1 is loaded with -3 so that 28.8KHz is divided by 3 to get the exact baud rate.
+
*SCON is configured in widely used mode :Asynchronous mode 8-bit data and 1-stop bit
+
*The timer is turned on.
+
 
+
<br\>
+
'''''UART_RxChar()'''''
+
The RI interrupt flag sets as soon as data is received. The function waits till that happens, reads bytes and clears flag.
+
<syntaxhighlight>
+
char UART_RxChar()
+
{
+
  while(RI==0);   // Wait till the data is received
+
  RI=0;        // Clear Receive Interrupt Flag for next cycle
+
  return(SBUF);   // return the received char
+
}
+
</syntaxhighlight>
+
 
+
<br\>
+
'''''UART_TxChar()'''''
+
The character to be transmitted is loaded in buffer, and the function waits till it transmitted by checking the TI flag.
+
<syntaxhighlight>
+
void UART_TxChar(char ch)
+
{
+
    SBUF=ch;   // Load the data to be transmitted
+
    while(TI==0);    // Wait till the data is trasmitted
+
    TI=0;   //Clear the flag for next cycle.
+
}
+
</syntaxhighlight>
+
  
The '''UART_TxString()''' and '''UART_RxString()''' functions use '''UART_TxChar()''' and '''UART_RxChar()''' as building blocks.
+
<b>RX9:</b> 9-bit Receive Enable bit<br>
 +
1 = Selects 9-bit reception<br>
 +
0 = Selects 8-bit reception
  
 +
<b>SREN:</b> Single Receive Enable bit<br>
 +
Asynchronous mode:Don’t care.
  
}}
+
<b>CREN:</b> Continuous Receive Enable bit<br>
 +
Asynchronous mode:<br>
 +
1 = Enables continuous receive<br>
 +
0 = Disables continuous receive
  
=Download=
+
<b>ADDEN:</b> Address Detect Enable bit<br>
The download does not just contain the example discussed, it also has several other examples that you may go through!
+
Asynchronous mode 9-bit (RX9 = 1):<br>
 +
1 = Enables address detection, enables interrupt and load of the receive buffer when RSR is set<br>
 +
0 = Disables address detection, all bytes are received and ninth bit can be used as parity bit
  
[[File:Download Icon.jpeg|thumbnail|center|link=http://xplorelabz.com/wiki/images/9/92/Serial_communication_examples_8051.rar|8051_Serial_communication_examples]]
+
<b>FERR:</b> Framing Error bit<br>
 +
1 = Framing error (can be updated by reading RCREG register and receive next valid byte)<br>
 +
0 = No framing error
  
 +
<b>OERR:</b> Overrun Error bit<br>
 +
1 = Overrun error (can be cleared by clearing bit CREN)<br>
 +
0 = No overrun error
  
 +
<b>RX9D:</b> 9th bit of Received Data (can be parity bit but must be calculated by user firmware)
 +
<br><br>
  
  
 +
=Baud Rate Calculation=
 +
The main criteria for UART communication is its baud rate. Both the devices Rx/Tx should be set to same baud rate for successful communication.<br>
 +
This can be achieved by SPBRG register.  SPBRG is a 8-bit register which controls the baud rate generation.<br>
 +
Given the desired baud rate and FOSC, the nearest integer value for the SPBRG register can be calculated using the below formula.
  
 +
*BRGH = 1 High Speed
 +
$$SPBRG = (Fosc / (16 * BaudRate)) - 1$$
  
 +
*BRGH = 0 Low Speed
 +
$$SPBRG = (Fosc / (64 * Baud rate)) - 1$$
  
 +
It may be advantageous to use the high baud rate (BRGH = 1) even for slower baud clocks.
 +
This is because the FOSC/(16 (X + 1)) equation can reduce the baud rate error in some cases. Below table shows the list of standard BaudRates and the SPBRG values.
 +
[[FILE:Pic16f877a_BaudRates.png]]
  
 +
=Steps To Send Char=
 +
#Wait till the previous char is transmitted. TXIF will be set when the TXREG is empty.
 +
#Clear the TXIF for next cycle.
 +
#Load the new char to be transmitted into THR.<br>
 +
<html>
 +
<script src="https://gist.github.com/SaheblalBagwan/ef0f2b16bc6eb398a8e7a2d272bd74dc.js"></script>
 +
</html>
 +
<br><br>
  
 +
=Steps To Receive Char=
 +
#Wait till the Data is received. RCIF will be set once the data is received in RCREG register.
 +
#Clear the receiver flag(RCIF) for next cycle.
 +
#Copy/Read the received data from RCREG register.<br>
 +
<html>
 +
<script src="https://gist.github.com/SaheblalBagwan/f47ebf0daaffe565a1d64aa6daea8bab.js"></script>
 +
</html>
 +
<br><br>
  
 +
=Code=
 +
Below is the sample code to Transmit and receive the chars at 9600 baudrate with 20Mhz clock.
 +
<html>
 +
<script src="https://gist.github.com/SaheblalBagwan/28efb0ab8aa0523bd1fcaf40abca3d3b.js"></script>
 +
</html>
  
 +
=Using ExploreEmbedded Libraries=
 +
In the above tutorial we discussed how to configure and use the inbuilt Pic16f877a UART.<br>
 +
Now we will see how to use the ExploreEmbededd UART library.<br>
 +
For this you have to include the uart.c/uart.h files and associated gpio/stdutils files.<br>
 +
*Note:Refer the uart.h file for more info.
  
 +
<html>
 +
<script src="https://gist.github.com/sharanago/12a15188d6143edfa7ba6408d6c1da02.js"></script>
 +
</html>
 +
[[File:Pic16f877a uart.PNG]]<br><br>
  
  
[[File:8051_Timers_Poster.jpg|RIGHT|thumbnail|x150px|link=8051_timers|'''''PREVIOUS TUTORIAL''''']]
+
=Downloads=
{{#widget:Facebook_Like_Box|profile=http://www.facebook.com/ExploreEmbedded}}
+
Download the complete project folder from the below link:<br>
 +
[https://github.com/ExploreEmbedded/Pic16f877a_ExploreUltraPicDevKit/archive/master.zip Hardware design Files and Code Library]
  
  
Have a opinion, suggestion, feedback or question about the tutorial, please comment below!
+
Have a opinion, suggestion , question or feedback about the article let it out here!
 
{{DISQUS}}
 
{{DISQUS}}

Revision as of 17:53, 20 August 2016

In this tutorial, we are going to discuss the serial/UART communication of 8051. After understating the basics of 8051 UART module, We will see how to use the ExploreEmbedded libraries to communicate with any of the UART devices.

0 UART main.gif


UART Registers

The below table shows the registers associated with 8051 UART.

Register Description
SCON Serial Control Register
TCON Timer Control Register for Baud Rate Generator
TMOD Timer Mode Control for Baud Rate Generator
SBUFF Serial Buffer holds the data to be transmitted and the data received



UART Register Configuration

Now lets see how to configure the individual registers for UART communication.

SCON
7 6 5 4 3 2 1 0
SM0 SM1 SM2 REN TB8 RB8 TI RI

SM0,SM1 Serial port mode selection

SM0 SM1 Operation Description Baud Rate Source
0 0 Mode 0 8bit ShiftReg 1/12 the quartz frequency
0 1 Mode 1 8 bit UART Determined by the timer 1
1 0 Mode 2 9 bit UART 1/32 the quartz frequency
1 1 Mode 0 9 bit UART Determined by the timer 1
  • SM2 - Serial port mode 2 bit, also known as multiprocessor communication enable bit. When set, it enables multiprocessor communication in mode 2 and 3, and eventually mode 1. It should be cleared in mode 0.
  • REN - Reception Enable bit enables serial reception when set. When cleared, serial reception is disabled.
  • TB8 - Transmitter bit 8. Since all registers are 8-bit wide, this bit solves the problem of transmitting the 9th bit in modes 2 and 3. It is set to transmit a logic 1 in the 9th bit.
  • RB8 - Receiver bit 8 or the 9th bit received in modes 2 and 3. Cleared by hardware if 9th bit received is a logic 0. Set by hardware if 9th bit received is a logic 1.
  • TI - Transmit Interrupt flag is automatically set at the moment the last bit of one byte is sent. It's a signal to the processor that the line is available for a new byte to transmit. It must be cleared from within the software.
  • RI - Receive Interrupt flag is automatically set upon one-byte receive. It signals that byte is received and should be read quickly prior to being replaced by a new data. This bit is also cleared from within the software.


RCSTA
7 6 5 4 3 2 1 0
SPEN RX9 SREN CREN ADDEN FERR OERR RX9D

SPEN: Serial Port Enable bit
1 = Serial port enabled (configures RC7/RX/DT and RC6/TX/CK pins as serial port pins)
0 = Serial port disabled

RX9: 9-bit Receive Enable bit
1 = Selects 9-bit reception
0 = Selects 8-bit reception

SREN: Single Receive Enable bit
Asynchronous mode:Don’t care.

CREN: Continuous Receive Enable bit
Asynchronous mode:
1 = Enables continuous receive
0 = Disables continuous receive

ADDEN: Address Detect Enable bit
Asynchronous mode 9-bit (RX9 = 1):
1 = Enables address detection, enables interrupt and load of the receive buffer when RSR is set
0 = Disables address detection, all bytes are received and ninth bit can be used as parity bit

FERR: Framing Error bit
1 = Framing error (can be updated by reading RCREG register and receive next valid byte)
0 = No framing error

OERR: Overrun Error bit
1 = Overrun error (can be cleared by clearing bit CREN)
0 = No overrun error

RX9D: 9th bit of Received Data (can be parity bit but must be calculated by user firmware)


Baud Rate Calculation

The main criteria for UART communication is its baud rate. Both the devices Rx/Tx should be set to same baud rate for successful communication.
This can be achieved by SPBRG register. SPBRG is a 8-bit register which controls the baud rate generation.
Given the desired baud rate and FOSC, the nearest integer value for the SPBRG register can be calculated using the below formula.

  • BRGH = 1 High Speed

$$SPBRG = (Fosc / (16 * BaudRate)) - 1$$

  • BRGH = 0 Low Speed

$$SPBRG = (Fosc / (64 * Baud rate)) - 1$$

It may be advantageous to use the high baud rate (BRGH = 1) even for slower baud clocks. This is because the FOSC/(16 (X + 1)) equation can reduce the baud rate error in some cases. Below table shows the list of standard BaudRates and the SPBRG values. Pic16f877a BaudRates.png

Steps To Send Char

  1. Wait till the previous char is transmitted. TXIF will be set when the TXREG is empty.
  2. Clear the TXIF for next cycle.
  3. Load the new char to be transmitted into THR.



Steps To Receive Char

  1. Wait till the Data is received. RCIF will be set once the data is received in RCREG register.
  2. Clear the receiver flag(RCIF) for next cycle.
  3. Copy/Read the received data from RCREG register.



Code

Below is the sample code to Transmit and receive the chars at 9600 baudrate with 20Mhz clock.

Using ExploreEmbedded Libraries

In the above tutorial we discussed how to configure and use the inbuilt Pic16f877a UART.
Now we will see how to use the ExploreEmbededd UART library.
For this you have to include the uart.c/uart.h files and associated gpio/stdutils files.

  • Note:Refer the uart.h file for more info.

Pic16f877a uart.PNG


Downloads

Download the complete project folder from the below link:
Hardware design Files and Code Library


Have a opinion, suggestion , question or feedback about the article let it out here!