LPC812 MAX Experiment: UART
Experiment: Work with a Serial Bus - UART
So far the microcontroller has had limited possibilities to communicate with the user. Technically it would have been possible to communicate information via an LED or a buzzer but it is not a very user friendly method and it would take time to communicate longer messages.
The mbed Microcontroller can communicate with a host PC through a "USB Virtual Serial Port" over the same USB cable that is used for programming. In this lab you will experiment with that serial port.
Information
Note that the mbed microcontroller is not aware that it appears as a virtual serial port on the Host PC. That is handled by the onboard interface as shown in this image from the mbed-HDK page:
The LPC812 has three UART interfaces:
Peripheral Name | RX Pin | TX Pin | Arduino Shield Alias | EA Serial Header | Description |
---|---|---|---|---|---|
UART1 | PIO0_0 | PIO0_4 | D0 / D1 | Pin 8 / 7 | Used for communication |
UART2 | PIO0_1 / USBRX | PIO0_6 / USBTX | N/A | N/A | USB Virtual Serial Port |
UART3 | PIO0_10 | PIO0_11 | SDA / SCL | Pin 10 / 9 | Pins shared with I2C |
In most cases you will only use UART2 and only for printing. UART1 can be use for communication with external peripherals. UART3 is rarely used as it shares pins with the I2C bus and can only be used if the I2C bus is unused.
Background
In this experiment you will learn how to work with the Universal Asynchronous Receiver/Transmitter, or UART for short. The term asynchronous refers to the fact that no explicit clock signal is transmitted. The transmitter and receiver must agree beforehand on the bit rate, i.e., how long time a transmitted bit shall take. The idle state (no transmission) is a high signal. Transmission begins with a start bit, which is low. The negative edge is detected by the receiver and 1.5 bit periods after this, bit sampling begins. Eight data bits are sampled. The least significant bit (LSB) is typically transmitted first. An optional parity bit is then transmitted (for error checking of the data bits). Often this bit is omitted if the transmission channel is assumed to be noise free or if there are error checking higher up in the protocol layers. The transmission is ended by a stop bit. Typically one bit, but 1.5 and 2 bits are sometimes also used. Most common for inter-board communication is 8N1, meaning 8 data bits, no parity and one stop bit.
On a side note, there are methods to determine the bit rate of a received signal but that is out of scope for this experiment.
An UART channel consists of two signals (besides ground):
- TXD: transmit data, direction from transmitter to receiver. This is an output.
- RXD: receive data, direction from transmitter to receiver. This is an input.
TXD and RXD are crossed between transmitter and receiver, i.e., TXD is connected to RXD and vice versa. For more information about asynchronous serial communication, see http://en.wikipedia.org/wiki/Universal_asynchronous_receiver/transmitter and http://en.wikipedia.org/wiki/Asynchronous_serial_communication.
Note and understand the difference between the signaling method (asynchronous serial communication) and standards of voltage signaling. The signal drawn in the image above illustrates the signal to/from the UART peripheral inside the LPC800. It is a 3.3V logic signal. This is common for communication between units on the same board, or closely mounted boards. RS232 is a common signaling standard with large voltage swings (+- 3-15V) that is used between units that are physically apart. RS422 and RS485 are other commonly used signaling standards.
Communication is normally point-to-point, meaning that a transmitter sends data to one receiver. There are signaling standards that also supports network topologies (for example RS422 and RS485). Higher protocol layers must then be involved in implementing addressing schemes between the nodes.
Hardware
In these labs you will only need the LPC812 MAX board but it must be modified to allow you to use the mbed interface's Virtual COM port.
Hardware Modification Needed
If you want to use the mbed interface Virtual COM port you need to modify your LPC812 MAX board. The instructions can be found in the mbed-NXP-LPC800-MAX-Getting-Started.
Software
Your mbed Microcontroller can appear on your computer as a serial port. On Mac and Linux, this will happen by default. For Windows, you need to install a driver:
Windows
See Windows-serial-configuration for full details about setting up Windows for serial communication with your mbed Microcontroller
On the PC side, a terminal application is needed. A terminal application connects to a COM port and displays everything received and also allows sending data from the application (via keyboard and sending a file). These are examples of a few good terminal applications:
- TeraTerm (which is recommended), http://sourceforge.jp/projects/ttssh2/files
- PuTTY, http:///www.chiark.greenend.org.uk/~sgtatham/putty/
- Terminal by Bray, http://sites.google.com/site/braypp/terminal
- RealTerm, http://sourceforge.net/projects/realterm/files/
Download and install the selected terminal application. The next step is to configure the application. Typical configuration settings are selecting COM port, setting bit rate (for example 9600 bps), set if parity is used and number of stop bits. Flow control is another setting that is common. Select None for this setting. Other settings require either additional hardware or software support.
For TeraTerm, select New Connection in the File menu. Select the COM port that appears when the FTDI UART-to-USB cable is connected to the PC. Click OK. The screenshot below illustrates the dialog window for setting up a new serial connection.
To set the bit rate and other relevant settings for the serial channel, go to Setup menu and select Serial Port. A dialog, like illustrated in the screenshot below, opens. Make sure Flow control is set to none.
There are many different settings for how the terminal program shall behave (i.e., interpret received characters). Some adjustments might be needed, for example when to start displaying received characters on a new line. Under menu Setup, sub-menu Terminal setup it is possible to control these things. The screenshot below illustrates the settings possible for when a new-line shall be performed on received characters. A common setting is LF, but it also depends on which character the LPC800 application outputs.
Information
Some terminal programs (e.g. TeraTerm) list the available serial ports by name. However, if you do need to know the identity of the serial port so that you can attach a terminal or an application to it:
- Windows - Look under the "Ports" section in "Device Manager" (''Start -> Control Panel -> System -> Hardware -> Device Manager''). The name will be ''mbed Serial Port (COMx)'', where ''x'' is the number of the COM port allocated.
- Mac OS X - Use the command ls /dev/tty.usbmodem*
- Linux - Use the command ls /dev/ttyACM*
1) printf
Communication over the USB Serial port simply uses the standard Serial Interface, specifying the internal (USBTX, USBRX) pins to connect to the Serial Port routed over USB.
The Serial Interface defaults to a 9600 baud standard serial connection (8 bits, 1 stop bit, no parity), so your host program should be set to the same settings. If you want to communicate at a different standard baud rate, ensure you modify the settings of both the Serial Interface and the Host PC application!
The program below uses the Serial interface available in the mbed library.
Import library
Public Member Functions |
|
Serial (PinName tx, PinName rx, const char *name=NULL) | |
Create a
Serial
port, connected to the specified transmit and receive pins.
|
|
void | baud (int baudrate) |
Set the baud rate of the serial port.
|
|
void | format (int bits=8, Parity parity=SerialBase::None, int stop_bits=1) |
Set the transmission format used by the serial port.
|
|
int | readable () |
Determine if there is a character available to read.
|
|
int | writeable () |
Determine if there is space available to write a character.
|
|
void | attach (void(*fptr)(void), IrqType type=RxIrq) |
Attach a function to call whenever a serial interrupt is generated.
|
|
template<typename T > | |
void | attach (T *tptr, void(T::*mptr)(void), IrqType type=RxIrq) |
Attach a member function to call whenever a serial interrupt is generated.
|
|
void | send_break () |
Generate a break condition on the serial line.
|
Use the following program to verify that everything works. You should see the "Hello World!" message in your terminal program on the Host PC.
Hello
#include "mbed.h" Serial pc(USBTX, USBRX); // tx, rx int main() { pc.printf("Hello World!\n"); }
Troubleshoot
If you modify your program and download it on the microcontroller you might need to disconnect and connect the terminal program on the Host PC to see the printouts from your modified program.
Create a program that determines the Endianness of the microcontroller and prints the result. Assume we have a 32-bit number: 0x0AC0FFEE in hexadecimal notation. The table below illustrates how the bytes are stored differently between a big and little Endian system.
Memory address | n | n+1 | n+2 | n+3 |
---|---|---|---|---|
Big-endian | 0x0A | 0xC0 | 0xFF | 0xEE |
Little-endian | 0xEE | 0xFF | 0xC0 | 0x0A |
Now think of a solution how to test this.
Tip: Create an unsigned int-pointer and an unsigned char-pointer. Let these pointers point to the same unsigned int-variable. Write a value in the unsigned int-variable with the unsigned int-pointer. Then read out the four parts via the unsigned char-pointer.
What Endian does the LPC812 have (little or big endian)?
The printf() function works like normal. It is possible to output strings and general expressions. Verify that this works.
2) Printing events
In this experiment you shall create a program that writes in the console every time a push-button is pressed. For simplicity, use the breadboard setup in the Digital Input Experiment.
3) Reading from the Console
In this experiment we will learn how the microcontroller can read input from the terminal program on the Host PC. The Serial class supplies functions to read and write one character (getc and putc) at a time. The calls are blocking, meaning that the microcontroller will stay in the library function call until the user (on the Host PC side) has entered the characters and hit the enter key.
Test the code below.
Test
#include "mbed.h" Serial pc(USBTX, USBRX); // tx, rx int main() { pc.printf("This is a test of getc...\n"); while(1) { int rxChar; rxChar = pc.getc(); pc.printf("%c", rxChar); } }
Run the program and enter five characters and then hit enter. What happens?
The reason for this is that there is a queue on the Host PC side. Each time getc() is called on the microcontroller side, a character is removed from the queue.
As an extra experiment, create a program that reads input from the console and converts it to a number. Check that only digits are entered and that the final number is within the range of a 32-bit number.
4) Performance test
In this experiment we will investigate the performance of the printing functionality. The default speed for the Serial class is 9600 baud which is enough for printing startup messages and warnings but when printing large amounts of data it becomes a limiting factor. The program below uses the Timer class from the mbed library to measure how much time passes when printing.
Complete the program below and then run it to see the limitation of the 9600 baud default setting.
#include "mbed.h" Serial pc(USBTX, USBRX); // tx, rx Timer timer; int main() { pc.printf("This is a performance test...\n"); char buff[513]; // initialize the buffer with some characters to print ... // puts expects the string to be null terminated buff[512] = '\0'; timer.start(); int begin = timer.read_ms(); for (int num = 0; num < 10; num++) { pc.puts(buff); } int end = timer.read_ms(); timer.stop(); // print information about how much time passed and the bitrate ... }
Now use the baud function in the Serial class to set a higher baud rate, for example 115200, and run the program again. Don't forget to change the baud rate in the terminal program on the Host PC as well.
Solution(s)
Import programlpc812_exp_solution_uart
Solutions for the UART experiments for LPC812 MAX
Please log in to post comments.