(12 intermediate revisions by the same user not shown)
Line 55: Line 55:
 
{| class="table table-striped table-hover table-condensed table-bordered"
 
{| class="table table-striped table-hover table-condensed table-bordered"
 
|-class="info"
 
|-class="info"
|RCSTA
+
|TMOD
 
|-
 
|-
|7 || 6 ||  5 || 4 || 3 || 2 || 1 || 0
+
!colspan="4"|Timer1||colspan="4"|Timer 0  
 
|-
 
|-
|SPEN || RX9 || SREN || CREN || ADDEN || FERR || OERR || RX9D
+
|7||6||5||4||3||2||1||0
 +
|-
 +
|Gate||C/T||M1||M0||Gate||C/T||M1||M0
 
|}
 
|}
 +
*<b>Gate Control</b>
 +
0 = Timer enabled<br>
 +
1 = Timer enabled if INTx\ is high
 +
*<b>C/T:</b>Counter or Timer Selector
 +
0 = Internal count source (clock/12)<br>
 +
1 = External count source (Tx pin)
 +
*<b>M1-M0:</b>Mode Control
 +
00-Mode 0, 13 bit count mode<br>
 +
01-Mode 1, 16 bit count mode<br>
 +
10-Mode 2, Auto reload mode<br>
 +
11-Mode 3, Multiple mode
  
<b>SPEN:</b> Serial Port Enable bit<br>
+
1 = Serial port enabled (configures RC7/RX/DT and RC6/TX/CK pins as serial port pins)<br>
+
{| class="table table-striped table-hover table-condensed table-bordered"
0 = Serial port disabled
+
|-class="info"
 +
|TCON
 +
|-
 +
|7 || 6 ||  5 || 4 || 3 || 2 || 1 || 0
 +
|-
 +
|TF1||TR1||TF0||TR0|| || || ||
 +
|}
  
<b>RX9:</b> 9-bit Receive Enable bit<br>
+
*<b>TRx:</b> Timer x run control
1 = Selects 9-bit reception<br>
+
0 = Timer not running<br>
0 = Selects 8-bit reception
+
1 = Timer running
 
+
*<b>TFx:</b> Timer x OverFlow flag
<b>SREN:</b> Single Receive Enable bit<br>
+
0 = Timer has not overflowed/rolled over<br>
Asynchronous mode:Don’t care.
+
1 = Timer has overflowed/rolled over
 
+
<b>CREN:</b> Continuous Receive Enable bit<br>
+
Asynchronous mode:<br>
+
1 = Enables continuous receive<br>
+
0 = Disables continuous receive
+
 
+
<b>ADDEN:</b> Address Detect Enable bit<br>
+
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
+
 
+
<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=
 
=Baud Rate Calculation=
Line 104: Line 102:
 
From above discussion<br/>
 
From above discussion<br/>
 
        
 
        
'''''Mclk = Fclk / 12 = 11.0592MHz/12 = 921.6KHz'''''<br/>
+
'''''Mclk = Fclk / 12 = 11.0592MHz/12 = 921.6KHz'''''<br>
  
'''''Tclk = Mclk/32= 921.6KHz/32 = 28.8KHz''''' <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.
 
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="table table-striped table-hover table-condensed table-bordered"
{| class="wikitable" style="text-align:center;background-color:#87A96B;margin: 1em auto 1em auto;"
+
|-class="info"
|-
+
 
!Baud Rate|| Factor)
 
!Baud Rate|| Factor)
 
|-
 
|-
Line 120: Line 117:
 
|9600||Tclk/'''3'''
 
|9600||Tclk/'''3'''
 
|-
 
|-
|14400||Tclk*'''2'''
+
|14400||Tclk/'''2'''
 
|}
 
|}
  
Line 128: Line 125:
 
$$TH1 = 256 - (Fosc/(32 * 12 * Baudrate))$$  //If( SMOD==0 in PCON register)
 
$$TH1 = 256 - (Fosc/(32 * 12 * Baudrate))$$  //If( SMOD==0 in PCON register)
 
$$TH1 = 256 - (Fosc/(32 * 6 * Baudrate))$$  //If( SMOD==1 in PCON register)
 
$$TH1 = 256 - (Fosc/(32 * 6 * Baudrate))$$  //If( SMOD==1 in PCON register)
{| class="table table-striped table-hover table-condensed table-bordered"
 
|-class="info"
 
|TMOD
 
|-
 
|7 || 6 ||  5 || 4 || 3 || 2 || 1 || 0
 
|-
 
|Gate||C/T||M1||M0||Gate||C/T||M1||M0
 
|}
 
*Gate Control.
 
0 = Timer enabled<br>
 
1 = Timer enabled if INTx\ is high
 
  
*<b>C/T:</b>Counter or Timer Selector
+
Now with Fosc = 11.0592Mhz, TH1 value for 9600 baudrate will be:
0 = Internal count source (clock/12)<br>
+
TH1 = 256-(11.0592*10^6)/(32 * 12 * 9600) = 253 = 0xFD = -3
1 = External count source (Tx pin)
+
  
*<b>M1-M0:</b>Mode Control
+
=Uart Init Steps=
00-Mode 0, 13 bit count mode<br>
+
#Select the 8-bit , 1-Start and 1-Stop bit mode in SMOD
01-Mode 1, 16 bit count mode<br>
+
#Configure the Timer1 for auto reload mode(Mode-2)
10-Mode 2, Auto reload mode<br>
+
#Load the baud rate generator value to TH1
11-Mode 3, Multiple mode
+
#Start the Timer for baudrate generation
 
+
<html><script src="https://gist.github.com/SaheblalBagwan/c7da45b94e94fb6c9278db95b3e559c2.js"></script></html>
+
<br><br>
{| class="table table-striped table-hover table-condensed table-bordered"
+
|-class="info"
+
|TCON
+
|-
+
|7 || 6 ||  5 || 4 || 3 || 2 || 1 || 0
+
|-
+
|TF1||TR1||TF0||TR0|| || || ||
+
|}
+
 
+
*<b>TRx:</b> Timer x run control
+
0 = Timer not running<br>
+
1 = Timer running
+
 
+
*<b>TFx:</b> Timer x OverFlow flag
+
0 = Timer has not overflowed/rolled over<br>
+
1 = Timer has overflowed/rolled over
+
  
 
=Steps To Send Char=
 
=Steps To Send Char=
#Wait till the previous char is transmitted. TXIF will be set when the TXREG is empty.
+
#Load the new char to be transmitted int SBUF.<br>
#Clear the TXIF for next cycle.
+
#Wait till the char is transmitted. TI will be set when the data in SBUF is transmitted.
#Load the new char to be transmitted into THR.<br>
+
#Clear the TI for next cycle.
 
<html>
 
<html>
<script src="https://gist.github.com/SaheblalBagwan/ef0f2b16bc6eb398a8e7a2d272bd74dc.js"></script>
+
<script src="https://gist.github.com/SaheblalBagwan/f98eb4474a489eebf80fb3667c99d8a8.js"></script>
 
</html>
 
</html>
 
<br><br>
 
<br><br>
  
 
=Steps To Receive Char=
 
=Steps To Receive Char=
#Wait till the Data is received. RCIF will be set once the data is received in RCREG register.
+
#Wait till the Data is received. RI will be set once the data is received in SBUF register.
#Clear the receiver flag(RCIF) for next cycle.
+
#Clear the receiver flag(RI) for next cycle.
#Copy/Read the received data from RCREG register.<br>
+
#Copy/Read the received data from SBUF register.<br>
 
<html>
 
<html>
<script src="https://gist.github.com/SaheblalBagwan/f47ebf0daaffe565a1d64aa6daea8bab.js"></script>
+
<script src="https://gist.github.com/SaheblalBagwan/567a0845d21299df010a2c27c80df232.js"></script>
 
</html>
 
</html>
 
<br><br>
 
<br><br>
  
 
=Code=
 
=Code=
Below is the sample code to Transmit and receive the chars at 9600 baudrate with 20Mhz clock.
+
Below is the sample code to Transmit and receive the chars at 9600 baudrate with 11.0592Mhz clock.
 
<html>
 
<html>
<script src="https://gist.github.com/SaheblalBagwan/28efb0ab8aa0523bd1fcaf40abca3d3b.js"></script>
+
<script src="https://gist.github.com/SaheblalBagwan/022405d82a54424f638c4a06b52082b7.js"></script>
 
</html>
 
</html>
  
 
=Using ExploreEmbedded Libraries=
 
=Using ExploreEmbedded Libraries=
In the above tutorial we discussed how to configure and use the inbuilt Pic16f877a UART.<br>
+
In the above tutorial we discussed how to configure and use the inbuilt 8051 UART.<br>
 
Now we will see how to use the ExploreEmbededd UART library.<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>
 
For this you have to include the uart.c/uart.h files and associated gpio/stdutils files.<br>
Line 199: Line 168:
  
 
<html>
 
<html>
<script src="https://gist.github.com/sharanago/12a15188d6143edfa7ba6408d6c1da02.js"></script>
+
<script src="https://gist.github.com/SaheblalBagwan/d657c1091766d4b938cd904cb1a504b0.js"></script>
 
</html>
 
</html>
 
[[File:Pic16f877a uart.PNG]]<br><br>
 
[[File:Pic16f877a uart.PNG]]<br><br>
 
  
 
=Downloads=
 
=Downloads=
Download the complete project folder from the below link:<br>
+
Download the sample code and design files from [https://github.com/ExploreEmbedded/8051_DevelopmentBoard this link].
[https://github.com/ExploreEmbedded/Pic16f877a_ExploreUltraPicDevKit/archive/master.zip Hardware design Files and Code Library]
+
  
  
Have a opinion, suggestion , question or feedback about the article let it out here!
+
Have an opinion, suggestion , question or feedback about the article let it out here!
 
{{DISQUS}}
 
{{DISQUS}}

Latest revision as of 10:13, 2 September 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 Operation Description Baud Rate Source
0 0 Mode 0 8-bit UART 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.


TMOD
Timer1 Timer 0
7 6 5 4 3 2 1 0
Gate C/T M1 M0 Gate C/T M1 M0
  • Gate Control

0 = Timer enabled
1 = Timer enabled if INTx\ is high

  • C/T:Counter or Timer Selector

0 = Internal count source (clock/12)
1 = External count source (Tx pin)

  • M1-M0:Mode Control

00-Mode 0, 13 bit count mode
01-Mode 1, 16 bit count mode
10-Mode 2, Auto reload mode
11-Mode 3, Multiple mode


TCON
7 6 5 4 3 2 1 0
TF1 TR1 TF0 TR0
  • TRx: Timer x run control

0 = Timer not running
1 = Timer running

  • TFx: Timer x OverFlow flag

0 = Timer has not overflowed/rolled over
1 = Timer has overflowed/rolled over

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.
For the 8051 the Timer 1' is used to generate the baud rate in Auto reload mode.

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 the timer frequency, say Tclk.

Usually, an 11.0592 Mhz crystal oscillator is used to provide the clock to 8051. The value seems to be odd but we see how it makes sense. From above discussion

Mclk = Fclk / 12 = 11.0592MHz/12 = 921.6KHz

Tclk = Mclk/32= 921.6KHz/32 = 28.8KHz

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.

Baud Rate Factor)
2400 Tclk/12
4800 Tclk/6
9600 Tclk/3
14400 Tclk/2

The above factors should be loaded to Timer1(TH1) in Mode2 in order to generate the required baud rate. The final formula for baud rate is as below. Baudrate = Fosc/(32 * 12 * (256-TH1)) $$TH1 = 256 - (Fosc/(32 * 12 * Baudrate))$$ //If( SMOD==0 in PCON register) $$TH1 = 256 - (Fosc/(32 * 6 * Baudrate))$$ //If( SMOD==1 in PCON register)

Now with Fosc = 11.0592Mhz, TH1 value for 9600 baudrate will be: TH1 = 256-(11.0592*10^6)/(32 * 12 * 9600) = 253 = 0xFD = -3

Uart Init Steps

  1. Select the 8-bit , 1-Start and 1-Stop bit mode in SMOD
  2. Configure the Timer1 for auto reload mode(Mode-2)
  3. Load the baud rate generator value to TH1
  4. Start the Timer for baudrate generation



Steps To Send Char

  1. Load the new char to be transmitted int SBUF.
  2. Wait till the char is transmitted. TI will be set when the data in SBUF is transmitted.
  3. Clear the TI for next cycle.



Steps To Receive Char

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



Code

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

Using ExploreEmbedded Libraries

In the above tutorial we discussed how to configure and use the inbuilt 8051 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 sample code and design files from this link.


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