CSE 477 – Hardware Design Capstone
Spring 2003
Carl Ebeling

Lab 4 : 8051 Serial Interface

Objectives:

In this lab will you will learn to use the 8051 serial interface including:

1.      Setting the baud rate using a timer

2.      Using interrupts to send and receive characters

3.      Implementing simple buffered putchar() and getchar() functions 

Setting up the serial interface

Refer to the 8051 documentation to see how to set the baud rate of the serial port using timer 1. We will be using a baud rate of 9600 - figure out how the timer should be configured to implement this baud rate. 

In addition, you will need to connect to the serial connector on the XSV board to the RXD/TXD pins of the the embedded 8051 microcontroller.  This connection goes through the X95108 CPLD, which is also used to connect the parallel port to the FPGA.  We will have to use our own SVF file to program the CPLD so that this connection is made - the dnldpar.svf program only connects the parallel port. You can test your connection with the program serial.c  in the lab4 folder. (You will have to set the timer for a 9600 baud rate for this to work.) 

For reference, the following diagram gives the pinout of the 9 pin serial connector.  With the appropriate SVF file (UWdwnldpar.svf) we can use the serial connector on the XSV board.

 

The connectors
--------------

PCs have 9pin/25pin male SUB-D connectors. The pin layout is as follows (seen from outside your PC):

       1         5
      _______________
      \  . . . . .  /
       \  . . . .  /
        -----------
         6       9

Name (V24)    9pin  Dir  Full name               Remarks
--------------------------------------------------------------------------
    TxD         3    o   Transmit Data           Data
    RxD         2    i   Receive Data            Data
    RTS         7    o   Request To Send         Handshaking
    CTS         8    i   Clear To Send           Handshaking
    DTR         4    o   Data Terminal Ready     Status
    DSR         6    i   Data Set Ready          Status
    RI          9    i   Ring Indicator          Status
    DCD         1    i   Data Carrier Detect     Status
    GND         5    -   Signal ground           Reference level
     -          -    -   Protective ground       Don't use this one
                                                 as signal ground!

 

The most important lines are RxD, TxD, and GND. Others are used with
modems, printers and plotters to indicate internal states.

To test our serial interface, we will use hyperterminal, a standard windows program that allows for basic communication through the serial port. The program is usally found in the Accessories folder. When you make a new hyperterminal connection you need to have the following PROPERTIES:

Select the appropiate COM port. (P0 corresponds to COM3?)

Select "Set Default settings" or do the following to set the parameters:

Baud rate. Hyperterminal and the microcontroller have to be set to the same baud rate. If the baud rates are different by a big percentage, then chances are no characters are sent either way. 

Data bits: 8.

Parity: NONE

Stop bits: 1

Flow control: none (we do not use the wires required for hardware flow control)

Menu: Properties->Settings-> ASCII setup (button). Check mark: echo typed character locally (otherwise only characters that are recieved by hyperterminal are displayed.

Simple getchar/putchar

In this part, you will implement simple getchar() and putchar() routines on the 8051. getchar() returns the character that has been received by the serial port. If there is a character waiting, it just returns it. If there is no character, then getchar() returns NULL. The user can thus call getchar() repeatedly if necessary until a character is returned, since getchar() doesn't hang until a character has been received. 

putchar(c) sends a character c to the serial port. If the port is not ready, i.e. it is in the process of sending a character, then putchar() returns NULL.  Otherwise it sends the character and returns a 1. 

Test these routines by writing a program that reads characters from the serial interface, and writes them back, transforming lower case letters to upper case, and vice versa. In case of non-alphabetic character echo the same character back) 

(The character codes for the alphabets : 'A' = 65, 'Z'=90 , 'a'=97 and 'z'=122; )

Serial Interface Interrupt Routine

The getchar and putchar routines in Part 2 do not have any buffering and thus do not allow a lot of concurrent processing. In this part, you will write one interrupt routine, that sends a character and that receives a character depending on which interrupt is triggered. The interrupt routine is called to send a character by the interrupt that indicates serial port send buffer is free. If there is a character waiting to be sent (use a global variable for this), then the routine sends the character and clears the global variable. If there is no character waiting to be sent, then it does nothing.

The interrupt routine is also called when the serial port receives a character. This character should be stored in a global variable. If the global variable already has a character, then an error condition should be flagged. 

You will now use the interrupt routine that you just wrote to implement getchar() and putchar(). These routines no longer look at the serial port registers directly, but rather at the global variables used by the interrupt routines. However, if putchar() is called and the global variable is empty, then putchar() must send that character explicitly since the interrupt routine will not be called again.

Test these routines by writing a program that reads characters from the serial interface, and writes them back, but transforming lower case letters to upper case, and vice versa. 

Buffered readchar/putchar

In this part, you will increase the buffering for both input and output from a single global variable to a buffer of size 32 to allow concurrent processing. These buffers are implemented using circular queues. puchar() adds characters at the tail of this output queue and the interrupt routine reads characters from the head whenever it can send a character.  (Again, putchar() must make sure the character is sent when the buffer is already empty.)  The interrupt routine writes characters to the tail of the input queue as they arrive, and puchar() reads them from the head.  Don't forget to implement error flags for cases where data gets lost.

To test the buffer you should implement a software flow-control along with the simple echo application. To test the buffering, implement Xoff and Xon, which are software flow control characters.  When the 8051 receives and Xoff character, it stops sending until it receives an Xon character.  This way, you can cause the 8051 to buffer up characters by first sending Xoff, typing some characters and then sending Xon.  The characters between the Xoff/Xon should be stored up and then echoed all at once. 

In practical terms Xoff and Xon are reserved characters that you can define however you wish; for example, you could use ‘$’ for Xon and ‘#’ for Xoff.

What to Turnin

Demonstrate your program to the TA. Hand in a printout of the C programs you wrote. You should also be able to answer detailed questions about every part.