Laboratory Exercise 6 - Serial Communication (1)
Laboratory Exercise 6 - Serial Communication (1)
Laboratory Exercise 6 - Serial Communication (1)
The last exercise sheet dealt with communication with microcomputers using simple digital signals,
LEDs and push buttons. This is quite suitable for human-machine interaction.
However, for the transmission of larger amounts of data with complex content, such as
measurement data, this type of communication is too slow and costly. To transmit a simple 16-bit
integer, 16 connections would be necessary on each side.
A common serial bus is the so-called "Universal Asynchronous Receiver Transmitter" (UART).
Your task in this experiment is to program the UART present in our microcontroller for output to a
terminal.
2.) Preparation
2. 1.) Clock configuration
For the UART to function correctly, it is necessary that the PLLs (Phased Lock Loops) and the
dividers for the CPU and peripheral clock are configured correctly.
For this, the file AStartup.S is required, which you must copy into your Eclipse project. The file is
stored in ILIAS.
The easiest way to copy the file is to drag it from an Explorer window directly into your project in
the Eclipse Project Explorer window.
During the next build process, AStartup.S is automatically compiled by the assembler and
integrated by the linker.
In order for this to work without errors, you still have to make the following changes in your source
code:
Thomas Erforth, Christian Langen, Laboratory Exercise 6 - Serial Communication.odt, 13.07.2020, Rev 2.06
Page 1 from 8
Karlsruhe University of Applied Sciences Laboratory Microcontroller Systems
Faculty EIT Laboratory Exercise 6
To do this, connect the enclosed USB cable to the personal computer and the microcontroller board.
The conversion of the transmission from the microcontroller UART to USB is carried out
transparently by a converter module by FTDI populated on the microcontroller board.
Under Windows, Linux or Mac OSX, an FTDI driver takes care of setting up a virtual COM
interface.
The number of the virtual COM interface varies under Windows from computer to computer.
You can figure out the current serial port number in the control panel under Device Manager ->
Ports (COM and LPT).
To operate the COM interface under Linux and Mac OSX, please ask one of the lab instrcutors.
Accept the settings for the window "Options Controlling Local Serial Lines" from the screen shot
below.
Under "Serial Line" you must enter the "COM Port" determined above.
Thomas Erforth, Christian Langen, Laboratory Exercise 6 - Serial Communication.odt, 13.07.2020, Rev 2.06
Page 2 from 8
Karlsruhe University of Applied Sciences Laboratory Microcontroller Systems
Faculty EIT Laboratory Exercise 6
If you do not see any output in the PUTTY window under the following conditions, you may need
to install the FTDI driver manually.
After the serial port of lab hardware is connected to the personal computer and PUTTY configured
as above the board switches on, and the TX LED on lab hardware is flickering.
The driver can be found in the Eclipse installation 'GNUARMEclipse.zip'. The setup executable is
stored in the file 'CDM21228_Setup.zip'.
After we have changed the entry point into our program from "_startup:" to "main:", we have to
adjust the debug configuration accordingly.
To do this, select your currently valid debug configuration in Eclipse under "Run / Debug
Configurations".
Under the “Startup” tab, check the “Set breakpoint at: main” and “Continue” boxes at the very
bottom of the tab page.
To carry out the experiments, you need the data sheet of the microcontroller "UM10114.pdf", which
is also stored in ILIAS.
3.) Tasks
3.1.) Task 1: Configuration of the Microcontroller Outputs
Our microcontroller does not have enough connections to make all peripheral functions directly
available.
Several functions are placed on one connector and must be selected as needed.
After power-up, most of the connections are wired as GPIOs (General Purpose Input Outputs).
We use UART0 with the connections TXD (Transmit) and RXD (Receive).
The selection of the desired function is done in the so-called "Pin Connect Block" with the help of
three registers: PINSEL0, PINSEL1 and PINSEL2 (Pin Select 0 to 2).
Thomas Erforth, Christian Langen, Laboratory Exercise 6 - Serial Communication.odt, 13.07.2020, Rev 2.06
Page 3 from 8
Karlsruhe University of Applied Sciences Laboratory Microcontroller Systems
Faculty EIT Laboratory Exercise 6
These registers are described in the data sheet in chapter "Chapter 8: LPC21xx/22xx Pin Connect
Block".
Task:
Find the corresponding PINSEL register in the data sheet and determine with which value the
register must be written in order to switch UART0 to the connections.
Furthermore, take the corresponding register address from the data sheet.
For better readability, use the ".equ" directive in your program to assign the corresponding
addresses to the register names.
Then you no longer have to remember the address and can use the name directly:
When writing, the data goes into the "UART0 Transmit Holding Register" (U0THR).
When reading, data is read from the so-called "UART0 Receiver Buffer Register" (U0RBR).
This register contains the data received from the communication partner.
Task:
Figure out the base address of the UART0 registers in the data sheet.
Thomas Erforth, Christian Langen, Laboratory Exercise 6 - Serial Communication.odt, 13.07.2020, Rev 2.06
Page 4 from 8
Karlsruhe University of Applied Sciences Laboratory Microcontroller Systems
Faculty EIT Laboratory Exercise 6
Furthermore, you need the offsets for the UART0 Line Control Register (U0LCR) and the
UART0 Line Status Register (U0LSR).
Define the names for the determined addresses / offset in the same way as described above
using the ".equ" directive:
To do this, create a sub-program as you have already learned in the previous exercises.
Use r5 as a pointer register, which you load with the corresponding address.
ldr r6, [r5] // Load content of register to which pointer points into r6
or
ldr r6, #0x1234 // Write value to r6
Firstly configure the PINSEL register to apply the UART0 RXD and TXD signals to the
processor connections.
Make sure that only the bits intended for UART0 are set. Proceed as follows:
4. In r6, set the bits intended for UART0 to the correct value (e.g. with "orr").
Thomas Erforth, Christian Langen, Laboratory Exercise 6 - Serial Communication.odt, 13.07.2020, Rev 2.06
Page 5 from 8
Karlsruhe University of Applied Sciences Laboratory Microcontroller Systems
Faculty EIT Laboratory Exercise 6
The next step is to program the transmission parameters for the UART into the U0LCR register.
"8 bit word length", "1 stop bit", "no parity", "disable break transmission".
Furthermore, the "Divisor Latch Access Bit" (DLAB) must be set to one (1) in order to be able to
configure the data transfer rate of 9600 baud later.
From the data sheet, determine the value that must be written into the U0LCR register. Then
write this value into the register.
2. Load value in r6
Note: Note that the U0LCR register is only 8 bits wide. So you need the write register
instruction for the 8-bit operations: "strb".
Now the "UART0 Divisor Latch Register" (U0DLL) must be configured with the correct value for
the data transfer rate of 9600 baud.
By setting the "DLAB" bit in register U0LCR, the U0DLL register is also at the base address. The
register value is calculated according to the following formula:
DLL = PCLK / (16 x BR)
PCLK is the peripheral clock and is 18.432 MHz, BR stands for the Baud Rate.
Task:
Calculate the register value settings and write them into the U0DLL register.
Also note the register width of 8 bits here.
The parameters are the same, except that this time the "Divisor Latch Access Bit" (DLAB) is set
to zero (0).
Thomas Erforth, Christian Langen, Laboratory Exercise 6 - Serial Communication.odt, 13.07.2020, Rev 2.06
Page 6 from 8
Karlsruhe University of Applied Sciences Laboratory Microcontroller Systems
Faculty EIT Laboratory Exercise 6
Determine the value of the U0LCR register with the DLAB bit set to zero (0) and write it into
the U0LCR register.
Since the DLAB bit in the U0LCR register has been reset, the "UART0 Transmit Holding Register"
(U0THR) (write) and the "UART0 Receiver Buffer Register" (U0RBR) (read) can both now be
found at this address. The reuse of 8-bit peripherals for the LPC2129 declares the short in register
addresses so they have to be reused for different purposes.
Before writing anything into the U0THR register, you must check whether the register is empty, i.e.
whether the previous byte has already been transmitted.
For this purpose, the status in U0LSR is read. The "TransmitterHoldingRegister Empty" (THRE)
bit is set (1) if the U0THR register is empty, what is somewhat confusing.
Task:
Send a byte by a subroutine to the connected personal computer and use the terminal
program PuTTY to check whether the byte was transmitted and received correctly.
To do this, determine the position of the THRE bit in the U0LSR register in the data sheet.
Also note the register width of 8 bits here. You must therefore work with "ldrb" and "strb"
instructions.
Procedure:
2. Load r0 with the byte to be transmitted, look for a suitable value in an ASCII table for
it.
4. Check whether Transmitter Holding Register Empty (THRE) bit is set (e.g. by means
of "tst" command = 'logical AND of two values').
Thomas Erforth, Christian Langen, Laboratory Exercise 6 - Serial Communication.odt, 13.07.2020, Rev 2.06
Page 7 from 8
Karlsruhe University of Applied Sciences Laboratory Microcontroller Systems
Faculty EIT Laboratory Exercise 6
6. Check whether the character has arrived in the terminal program on the personal
computer.
After you have successfully transmitted and received a single character, you now extend your
program with a subroutine for transmitting a complete string.
To do so, place the string to be transmitted as data at the end of your program.
Access to this data is done with the help of a pointer. If you do not remember how to do this, look
again to Exercise 2, Task 3.
Task:
Hints:
1. Use the assembler directive '.asciz' followed by your string enclosed in inverted
commas, e.g. .asciz "Hello world".
2. The 'asciz' directive automatically appends a 0x0 byte to the end of the string. Use this
'0' byte as a termination criterion in your output routine.
Design a super loop around the string transmisson of task 4 to resend the string after reaching the
zero termination. In the loop reset the pointer to the first string character again.
Thomas Erforth, Christian Langen, Laboratory Exercise 6 - Serial Communication.odt, 13.07.2020, Rev 2.06
Page 8 from 8