Project 5.1 UARTs

Communicate with the Blackboard using a PC's COM port



For this project, you will configure the UART on ZYNQ to communicate with a terminal program running on your PC.


The ZYNQ chip used on the Blackboard has two UART controllers, and one has been configured to communicate with a COM port on your PC. UART1 is connected to the FTDI USB controller, and from there to your PC using the same USB cable that provides power and the programming interface. The FTDI controller is “transparent", so that the UART data pins (RXD and TXD) are delivered directly to a COM port on your PC. On the PC side, any terminal program can connect to the COM port, and send and receive characters to ZYNQ’s UART.

After setting up ZYNQ’s UART and the terminal program (you can use the terminal program that is included in the SDK tool), you will write some C programs to move data back and forth and create some usable C functions.


1. Configure ZYNQ’s UART to pass a character to the PC

Configure the Blackboard/ZYNQ UART1 interface to communicate with a terminal program running on the PC. The background topic documents provide guidance on configuring the UART, but you must read the Blackboard programmer’s reference and/or the ZYNQ TRM to learn specific information about the UART1 registers, and how to properly configure them.

The SDK tool includes a terminal program that you can use to communicate with the Blackboard’s UART port - see the “UART" background topic for information on using SDK’s terminal emulator.

After you configure the UART, transfer a single character from the Blackboard to the PC. If you wanted to transfer the character “A" for example, you could include a statement like the one below, and then write the defined character to the FIFO data port.

unint8_t mycharacter = 'A';

2. Send a character to the UART and respond

Send the character “N" to the Blackboard, and then return your name after the character is received. To do this, you will need to define a string (or an array of characters) for your name, and then send the characters one at a time to the FIFO data port.

3. Create a C function to send an arbitrary string

Create a C function to send an arbitrarily long string to the UART. Your function should be able to handle strings of more than 64 bytes, so you must check to be sure you are not overfilling the FIFO and losing data. You can only send up to 64 bytes at a time, and you can’t send more bytes until the FIFO is empty (or has room). You can pass the string to your C function, and your function should be able to manage sending that on to the UART, including segmenting it into 64-byte (or less) chunks.

4. Create two useful C functions for later use

Create two functions write_reg_data (uint32_t address, uint32_t data) and read_reg_data (uint32_t address) that can write or read data from any register. These two functions will be very useful, because you can use them to modify or check any register on the fly. Use the read function to read the contents of one of the UART control registers, and verify the register contents are correct. You should add these functions to “my_functions.c" and make them visible through “my_header.h" so you can use them in later projects.

5. Use your write function to turn on an LED

Use your write function from requirement #4 to write values to an LED control register to turn on or off at least one of Blackboards LED’s from the terminal program (any LED is OK).


1. Read the XADC voltage at a regular interval and send the result to the terminal program

Set up the Global Timer to create interrupts every 500ms, read a data point from the ADC at each interrupt, and send the data point to the PC. The ADC input is connected to a potentiometer that can create an analog voltage in the 0V - 1V range, so your terminal window should update twice each second with a new data point representing the measured voltage. You should be able to change that voltage in real-time by changing the position of the pot.

2. Reconfigure the UART1 interface so that it is controlled using interrupts.

Change your code from requirement 3 above (that code writes arbitrarily long strings) so that it uses interrupts instead of polling. Your new function should enable the FIFO_empty interrupt, so when the FIFO finally empties you can you can take the interrupt and add more data. Your function should also check the FIFO fill level before adding more data, so that you don’t inadvertently overflow.

Also, write another new function that generates an interrupt every time a new character is entered into the receive FIFO. Your interrupt handler should transfer the character to a buffer on each interrupt, and then toggle an LED to visually indicate you handled the interrupt properly for each new character. (In a “real” application, a scheduler would check the buffer every so often, and parse the characters to learn of any new commands).

You can execute a “while (1)" loop while waiting for interrupts. Note that the UART1 interrupt uses ID #82.