Friday, June 15, 2012

Using the UART

Universal  Asynchronous Receive/Transmit is a form of serial communications used in conjunction with RS-232, RS-485 or RS-422. The 89S52 has one UART port, and the important registers that we will look are TMOD, SCON and SBUF registers. More info regarding this registers can be found on the datasheet.

Initializing Serial Port

1. Set Timer1 as Mode 2, Timer1 then acts as the baudrate generator.
    To do this, load TMOD with 0x20.
2. Load TH1with the desired value according to the baudrate.
    To calculate the value of TH1 we use the formula:

        TH1 = -((Crystal Frequency/12)/32) /desired Baud Rate

       Example: Value of TH1 for a baud rate of 9600 and a crystal frequency of 3.579545MHz

           Divide crystal frequency by 12

                       3579545 / 12 = 298295.4167

          As you can see, if we divide the crystal frequency by 12, the result is not a whole number, if the error is so little, then we can disregard it else choose a crystal frequency that is divisible by 12 to come up with 0% error such as 11.0592MHz or 22.1184MHz.

     Divide resulting value by 32
             
                      298295.4167/32 = 9321.731771

   Divide the resulting value by the desired baud rate

                       9321.731771/9600 = -0.971013726 ~= -1

         We have about 3% error with this crystal frequency

To get the value of TH1

     Subtract computed value from 0xFF and add 1

 TH1 = 0xFF

3. Load the SCON register with the standard 8-bit UART parameters, Mode1 with 8-bits data, no parity, 1 start bit, 1 stop bit and receive enabled.

4. Start Timer 1
5. Load SBUF with the character to be transferred
6. Check if TI is set, if set, clear it.

The Code


#include <at89x52.h>

void UARTputch (unsigned char ch)
{
    TI = 0;                //Clear TI
    SBUF = ch;        //Load data to SBUF
    while(!TI);          //Wait for transmission to finish
}

unsigned char UARTgetch()
{
     while(!RI);        //wait for a byte to receive
     RI = 0;             //Clear RI
     return(SBUF);  //return the contents of SBUF
}

void main (void)
{
  unsigned char rx_byte;
  TMOD = 0x20;     //Timer1 Mode2 Auto Reload
  TH1 = 0xFF;         //9600 baud at 3.579545MHz
  SCON = 0x50;     //UART parameters
  TR1 = 1;               //Start timer

   while(1)
    {
       rx_byte = UARTgetch();
       UARTputch(rx_byte);
   }  
}

The code presented above will echo a single byte that has been sent to the 8051 back to the sender.


                   


No comments:

Post a Comment