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
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 Name
(V24) 9pin Dir Full
name
Remarks The
most important lines are RxD, TxD, and GND. Others are used with
|
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.
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; )
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.
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.
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.