The objective is to utilize the Universal Asynchronous Receiver/Transmitter (UART)
to connect the Stellris Launchpad board to the host computer. In the example project, we send
characters to the microcontroller unit (MCU) of the board by pressing keys on the keyboard.
These characters are sent back (i.e., echoed, looped-back) to the host computer by the MCU
and are displayed in a hyperterminal window.
The objective is to utilize the Universal Asynchronous Receiver/Transmitter (UART)
to connect the Stellris Launchpad board to the host computer. In the example project, we send
characters to the microcontroller unit (MCU) of the board by pressing keys on the keyboard.
These characters are sent back (i.e., echoed, looped-back) to the host computer by the MCU
and are displayed in a hyperterminal window.
Original Title
UART interface to a computer using ARM microcontroller
The objective is to utilize the Universal Asynchronous Receiver/Transmitter (UART)
to connect the Stellris Launchpad board to the host computer. In the example project, we send
characters to the microcontroller unit (MCU) of the board by pressing keys on the keyboard.
These characters are sent back (i.e., echoed, looped-back) to the host computer by the MCU
and are displayed in a hyperterminal window.
The objective is to utilize the Universal Asynchronous Receiver/Transmitter (UART)
to connect the Stellris Launchpad board to the host computer. In the example project, we send
characters to the microcontroller unit (MCU) of the board by pressing keys on the keyboard.
These characters are sent back (i.e., echoed, looped-back) to the host computer by the MCU
and are displayed in a hyperterminal window.
Objective The objective of this lab is to utilize the Universal Asynchronous Receiver/Transmitter (UART) to connect the Stellris Launchpad board to the host computer. In the example project, we send characters to the microcontroller unit (MCU) of the board by pressing keys on the keyboard. These characters are sent back (i.e., echoed, looped-back) to the host computer by the MCU and are displayed in a hyperterminal window. Asynchronous Communication The most basic method for communication with an embedded processor is asynchronous serial. It is implemented over a symmetric pair of wires connecting two devices (referred as host and target here, though these terms are arbitrary). Whenever the host has data to send to the target, it does so by sending an encoded bit stream over its transmit (TX) wire. This data is received by the target over its receive (RX) wire. The communication is similar in the opposite direction. This simple arrangement is illustrated in Fig. 10.1. This mode of communications is called asynchronous because the host and target share no time reference (no clock signal). Instead, temporal properties are encoded in the bit stream by the transmitter and must be decoded by the receiver. Chapter 5 Asynchronous Serial Communication After LEDs and pushbuttons, the most basic method for communica- tion with an embedded processor is asynchronous serial. Asynchronous serial communication in its most primitive form is implemented over a symmetric pair of wires connecting two devices here Ill refer to them as the host and target, although those terms are arbitrary. Whenever the host has data to send to the target, it does so by sending an encoded bit stream over its trans- mit (TX) wire; this data is received by the target over its receive (RX) wire. Similarly, when the target has data to send to the host it transmits the en- coded bit stream over its TX wire and this data is received by the host over its RX wire. This arrangement is illustrated in Figure 5. This mode of commu- nications is called asynchronous because the host and target share no time reference. Instead, temporal properties are encoded in the bit stream by the transmitter and must be decoded by the receiver. Host Target TX RX RX TX Figure 5.1: Basic Serial Communications Topology Revision: 1396a85 (2013-01-07) 71 Figure 10.1: Basic Serial Communication A commonly used device for encoding and decoding such asynchronous bit streams is a Uni- versal Asynchronous Receiver/Transmitter (UART). UART is a circuit that sends parallel data through a serial line. UARTs are frequently used in conjunction with the RS-232 standard (or specication), which species the electrical, mechanical, functional, and procedural character- istics of two data communication equipment. A UART includes a transmitter and a receiver. The transmitter is essentially a special shift 82 83 register that loads data in parallel and then shifts it out bit by bit at a specic rate. The receiver, on the other hand, shifts in data bit by bit and reassembles the data. One of the basic encodings used for asynchronous serial communications is illustrated in Fig. 10.2. Every character is transmitted in a frame which begins with a (low) start bit followed by eight data bits and ends with a (high) stop bit. The data bits are encoded as high or low signals for (1) and (0), respectively. Between frames, an idle condition is signaled by transmitting a continuous high signal. Thus, every frame is guaranteed to begin with a high-low transition and to contain at least one low-high transition. Alternatives to this basic frame structure include dierent numbers of data bits (e.g. 9), a parity bit following the last data bit to enable error detection, and longer stop conditions. Fig. 10.2 CHAPTER 5. ASYNCHRONOUS SERIAL COMMUNICATION A commonly used device for encoding and decoding such asynchronous bit streams is a Universal Asynchronous Receiver/Transmitter (UART) which converts data bytes provided by software into a sequence of individual bits and, conversely, converts such a sequence of bits into data bytes to be passed o to software. The STM32 processors include (up to) ve such devices called US- ARTs (for universal synchronous/asynchronous receiver/transmitter) because they support additional communication modes beyond basic asynchronous communications. In this Chapter we will explore serial communication be- tween the (target) STM32 USART and a USB/UART bridge connected to a host PC. UARTs can also be used to interface to a wide variety of other pe- ripherals. For example, widely available GSM/GPRS cell phone modems and Bluetooth modems can be interfaced to a micro-controller UART. Similarly GPS receivers frequently support UART interfaces. As with the other inter- faces well consider in future chapters, the serial protocol provides access to a wide variety of devices. frame start stop TX 0 1 2 3 4 5 6 7 Figure 5.2: Serial Communications Protocol One of the basic encodings used for asynchronous serial communications is illustrated in Figure 5. Every character is transmitted in a frame which begins with a (low) start bit followed by eight data bits and ends with a (high) stop bit. The data bits are encoded as high or low signals for (1) and (0), respectively. Between frames, an idle condition is signaled by transmitting a continuous high signal. Thus, every frame is guaranteed to begin with a high- low transition and to contain at least one low-high transition. Alternatives to this basic frame structure include dierent numbers of data bits (e.g. 9), a parity bit following the last data bit to enable error detection, and longer stop conditions. There is no clock directly encoded in the signal (in contrast with signal- ing protocols such as Manchester encoding) the start transition provides the only temporal information in the data stream. The transmitter and receiver 72 Revision: 1396a85 (2013-01-07) Figure 10.2: Transmission of a byte There is no clock directly encoded in the signal the start transition provides the only temporal information in the data stream. The transmitter and receiver each independently maintain clocks running at (a multiple of) an agreed frequency commonly called the baud rate. These two clocks are not synchronized and are not guaranteed to be exactly the same frequency, but they must be close enough in frequency (better than 2%) to recover the data. Before the transmission starts, the transmitter and receiver must agree on a set of parameters in advance, which include the baud-rate (i.e., number of bits per second), the number of data bits and stop bits, and use of parity bit. To understand how the UARTs receiver extracts encoded data, assume it has a clock running at a multiple of the baud rate (e.g., 16x). Starting in the idle state (as shown in Fig. 10.3), the receiver samples its RX signal until it detects a high-low transition. Then, it waits 1.5 bit periods (24 clock periods) to sample its RX signal at what it estimates to be the center of data bit 0. The receiver then samples RX at bit-period intervals (16 clock periods) until it has read the remaining 7 data bits and the stop bit. From that point this process is repeated. Successful extraction of the data from a frame requires that, over 10.5 bit periods, the drift of the receiver clock relative to the transmitter clock be less than 0.5 periods in order to correctly detect the stop bit. each independently maintain clocks running at (a multiple of) an agreed fre- quency commonly, and inaccurately, called the baud rate. These two clocks are not synchronized and are not guaranteed to be exactly the same frequency, but they must be close enough in frequency (better than 2%) to recover the data. Sample clock (16x) 24 16 idle start TX 0 1 Figure 5.3: UART Signal Decoding To understand how the receiver extracts encoded data, assume it has a clock running at a multiple of the baud rate (e.g. 16x) starting from an idle state as illustrated in Figure 5. The receiver samples its RX signal until it detects a high-low transition. It then waits 1.5 bit periods (24 clock periods) to sample its RX signal at what it estimates to be the center of data bit 0. The receiver then samples RX at bit-period intervals (16 clock periods) until it has read the remaining 7 data bits and the stop bit. From that point the process repeats. Successful extraction of the data from a frame requires that, over 10.5 bit periods, the drift of the receiver clock relative to the transmitter clock be less that 0.5 periods in order to correctly detect the stop bit. Exercise 5.1 Testing the USB/UART Interface Before we discuss the implementation of UART communications with the STM32, it may be helpful to use the Saleae Logic to see the asynchronous signals. We will use the USB-UART bridge to generate signals that we will then capture with logic analyzer. Later, this will be an essential tool for debugging your code executing on the STM32. It is extremely dicult to debug hardware device drivers using only a software debugger such as GDB because these debuggers provide no visibility into what the hardware is actually doing. For example, if one neglects to congure the clocks to a specic hardware peripheral, that peripheral will do nothing in response to software commands even if all the peripheral specic software is completely correct. Perhaps even more vexing is when the hard- ware interface almost works. For example, in developing the I2C examples Revision: 1396a85 (2013-01-07) 73 Figure 10.3: UART Signal Decoding 84 CHAPTER 10. ASYNCHRONOUS SERIAL INTERFACING (UART) UART in LM4F120 The simplest form of UART communication is based upon polling the state of the UART device. The UART module in LM4F120 microntroller has 16-element FIFO and 10-bit shift register, which cannot be directly accessed by the programmer. The FIFO and shift register in the transmitter are separate from the FIFO and shift register associated with the receiver. While the data register occupies a single memory word, it is really two separate locations; when the data register is written, the written character is transmitted by the UART. When the data register is read, the character most recently received by the UART is returned. The UART Flag Register (UARTFR) contains a number of ags to determine the current UART state. The important ags are: TXFE Transmit FIFO Empty TXFF Transmit FIFO Ful l RXFE Recei ve FIFO Empty RXFF Recei ve FIFO Ful l To transmit data using the UART, the application software must make sure that the transmit FIFO is not full (it will wait if TXFF is 1) and then write to the transmit data register(e.g., UART2 DR R). When a new byte is written to UART1 DR R, it is put into the transmit FIFO. Byte by byte, the UART gets data from the FIFO and loads into 10-bit shift register which transmits the frame one bit at a time at a specied baud rate. The FIFO guarentees that the data are transmitted in the order they were written. Stop d7 d6 d5 d4 d3 d2 d1 d0 Start 16 x 8 transmit FIFO Transmit data register Tranmit data Write data Shift clock Transmit shift register Figure 10.4: UART Data Transmission Receiving frame is a little bit trickier than transmission as we have to synchronize the receive shift register with the data. The receive FIFO empty ag, RXFE, is clear when new input data are in the receive FIFO. When the software reads from UART1 DR R, data are removed from the FIFO. The other ags associated with the receiver are RXFF (Receive FIFO Full). Four status bits are also associated with each byte of data. These status bits are Overrun Error(OE), Break Error(BE), Parity Error(PE) and Framing Error(FE). The status of these bits can be 85 checked using UART Receive Status/Error Clear Register(UARTRSR/UARTECR). Receive shift register Stop d7 d6 d5 d4 d3 d2 d1 d0 Start Receive Data Register Read data Shift clock Receive data OE BE PE FE Flags Data 16 x 12 receive FIFO Figure 10.5: UART Data Reception Initialization and Conguration Stellaris Launchpad has eight UART modules connected to dierent ports of the microcon- troller.[Table 14-1] In this lab, we will be using UART module 2 connected to PD6 (U2Rx) and PD7 (U2Tx) of GPIO port D. As with all other peripherals, UART must be initialized before it can be used. This initialization includes pin conguration, clock distribution, and device initialization. The steps required to initialize the UART are stated below: 1. The rst initialization step is to enable the clock signal to the respective UART module in Run Mode Clock Gating Control UART register (RCGCUART).[pg. 318] To enable UART2 module bit 2 of this register should be asserted. 2. Enable the clock for the appropriate GPIO port to which UART is connected. The clock can be enabled using the RCGCGPIO register [pg. 314]. Table 14-1 [pg. 851] can be used to nd out the port to which UART is connected. 3. To enable the alternate functionality set the appropriate bits of GPIO Alternate Func- tion Select (GPIOAFSEL) register.[pg. 630] Now, write the value in GPIO Port Control (GPIOPCTL) register to enable UART signals for the appropriate pins.[pg. 647] 4. PD7 is also connected to Non-maskable interrupt (NMI) which is protected from accidental programming.[Table 10-2] In order to use PD7 as Tx of UART2 we must disable its write protection by unlocking GPIO Commit (GPIOCR) register and set its appropriate bits.[pg. 644] To unlock GPIO Commit we must write 0x4C4F.434B to GPIO Lock (GPIOLOCK) register.[pg. 643] Now, we will discuss the steps required to congure the UART module. 1. The rst step is calculate the baud-rate divisor (BRD) for setting the required baud- rate. The baud-rate divisor is a 22-bit number consisting of a 16-bit integer and a 6-bit fractional part. UART Integer Baud-Rate Divisor (UARTIBRD) register species the 86 CHAPTER 10. ASYNCHRONOUS SERIAL INTERFACING (UART) integer part and UART Fractional Baud-Rate Divisor (UARTFBRD) [] register species the fractional part of baud-rate. [pg. 871, 872] Following expression gives the relation of baud-rate divisor and system clock [pg. 851] BRD = BRDI + BRDF = UARTSysClk/(ClkDiv BaudRate) As the system clock (SysClk) is 16MHz and the desired baud-rate is 115200 bits/sec, then the baud-rate divisor can be calculated as: BRD = 16, 000, 000/(16 115, 200) = 8.6805 So, the value 8 should be written in DIVINT eld of UARTIBRD register. Fractional part of baud-rate divisor is calculated in the following equation and the result should be written to the DIVFRAC eld of UARTFBRD register. UARTFBRD[DIV FRAC] = integer(0.6805 64 + 0.5) = 44 2. After calculating the baud rate divisor we must disable the UART by asserting UARTEN bit in UART Control (UARTCTL) register. [pg. 875] 3. Integer and fractional values of baud rate divisor, calculated previously, should be written to the appropriate bits of UARTIBRD and UARTFRD registers respectively. 4. Write the desired parameters for the serial communication you want to congure in UART Line Control (LCRH) register.[pg. 873] In this experiment, we will be using a word length of 8, one stop bit and enable the FIFOs. 5. To congure the clock source for UART congure the appropriate bit of UART Clock Conguration (UARTCC) register.[pg. 899] We will be using system clock for our exper- iment. 6. After conguring all the parameters, now enable the UART by asserting the UARTEN bit in UART Control (UARTCTL) register. Source Code 1 2 // Re gi s t e r d e f i n i t i o n s f o r Cl ock Enabl e 3 #de f i ne SYSCTL RCGCUART R ( ( ( v o l a t i l e unsi gned l ong ) 0x400FE618 ) ) 4 #de f i ne SYSCTL RCGCGPIO R ( ( ( v o l a t i l e unsi gned l ong ) 0x400FE608 ) ) 5 6 // Re gi s t e r d e f i n i t i o n s f o r GPIO PortD 7 #de f i ne GPIO PORTD AFSEL R ( ( ( v o l a t i l e unsi gned l ong ) 0x40007420 ) ) 8 #de f i ne GPIO PORTD PCTL R ( ( ( v o l a t i l e unsi gned l ong ) 0x4000752C) ) 9 #de f i ne GPIO PORTD DEN R ( ( ( v o l a t i l e unsi gned l ong ) 0x4000751C) ) 10 #de f i ne GPIO PORTD DIR R ( ( ( v o l a t i l e unsi gned l ong ) 0x40007400 ) ) 11 #de f i ne GPIO PORTD LOCK R ( ( ( v o l a t i l e unsi gned l ong ) 0x40007520 ) ) 87 12 #de f i ne GPIO PORTD CR R ( ( ( v o l a t i l e unsi gned l ong ) 0x40007524 ) ) 13 14 // Re gi s t e r d e f i n i t i o n s f o r UART2 module 15 #de f i ne UART2 CTL R ( ( ( v o l a t i l e unsi gned l ong ) 0x4000E030 ) ) 16 #de f i ne UART2 IBRD R ( ( ( v o l a t i l e unsi gned l ong ) 0x4000E024 ) ) 17 #de f i ne UART2 FBRD R ( ( ( v o l a t i l e unsi gned l ong ) 0x4000E028 ) ) 18 #de f i ne UART2 LCRH R ( ( ( v o l a t i l e unsi gned l ong ) 0x4000E02C) ) 19 #de f i ne UART2 CC R ( ( ( v o l a t i l e unsi gned l ong ) 0x4000EFC8) ) 20 #de f i ne UART2 FR R ( ( ( v o l a t i l e unsi gned l ong ) 0x4000E018 ) ) 21 #de f i ne UART2 DR R ( ( ( v o l a t i l e unsi gned l ong ) 0x4000E000 ) ) 22 23 // Macros f o r i n i t i a l i z a t i o n and c onf i gur at i on of UART2 24 #de f i ne UART2 CLK EN 0x00000004 // Enabl e c l oc k f o r UART2 25 #de f i ne GPIO PORTD CLK EN 0x00000008 // Enabl e c l oc k f o r GPIO PORTD 26 27 #de f i ne GPIO PORTD UART2 CFG 0x000000C0 // Di g i t a l enabl e 28 // Act i vat e a l t e r na t e f unc t i on f or PD6 and PD7 29 #de f i ne GPIO PCTL PD6 U2RX 0x01000000 // Conf i gure PD6 as U2RX 30 #de f i ne GPIO PCTL PD7 U2TX 0x10000000 // Conf i gure PD7 as U2TX 31 #de f i ne GPIO PORTD UNLOCK CR 0x4C4F434B // Unlock Commit r e g i s t e r 32 #de f i ne GPIO PORTD CR EN 0x000000FF // Di s abl e wr i t e pr ot e c t i on 33 34 #de f i ne UART CS SysClk 0x00000000 // Use system as UART c l oc k 35 #de f i ne UART CS PIOSC 0x00000005 // Use PIOSC as UART c l oc k 36 #de f i ne UART LCRH WLEN 8 0x00000060 // 8 bi t word l engt h 37 #de f i ne UART LCRH FEN 0x00000010 // Enabl e UART FIFOs 38 #de f i ne UART FR TXFF 0x00000020 // UART Transmit FIFO Ful l 39 #de f i ne UART FR RXFE 0x00000010 // UART Recei ve FIFO Empty 40 #de f i ne UART CTL UARTEN 0x00000001 // Enabl e UART 41 #de f i ne UART LB EN 0x00000080 // Use UART i n Loopback mode 42 43 // Functi on d e f i n i t i o n s 44 unsi gned char UART Rx( voi d ) ; 45 voi d UART Tx( unsi gned char data ) ; 46 voi d UART Tx String ( char pt ) ; 47 voi d UART Rx String ( char bufPt , unsi gned s hor t max) ; 48 49 // I n t i a l i z e and c onf i gur e UART 50 voi d UART Init ( voi d ) { 51 52 // Enabl e c l oc k f o r UART2 and GPIO Port D 53 SYSCTL RCGCUART R |= UART2 CLK EN; // Act i vat e UART2 54 SYSCTL RCGCGPIO R |= GPIO PORTD CLK EN; // Act i vat e Port D 55 56 // Conf i gur at i on to use PD6 and PD7 as UART 57 GPIO PORTD LOCK R = GPIO PORTD UNLOCK CR; // Unlock commit r e g i s t e r 58 GPIO PORTD CR R |= GPIO PORTD CR EN; // Enabl e U2Tx on PD7 88 CHAPTER 10. ASYNCHRONOUS SERIAL INTERFACING (UART) 59 GPIO PORTD DEN R |= GPIO PORTD UART2 CFG; // Enabl e d i g i t a l I /O on PD6 7 60 GPIO PORTD AFSEL R |= GPIO PORTD UART2 CFG; // Enabl e a l t . f unc . on PD67 61 GPIO PORTD PCTL R |= (GPIO PCTL PD6 U2RX | GPIO PCTL PD7 U2TX) ; 62 63 // Conf i gur at i on of UART2 module 64 UART2 CTL R &= UART CTL UARTEN; // Di s abl e UART 65 // IBRD = i nt ( 16 , 000 , 000 / (16 115 , 200) ) = i nt ( 8. 6805) 66 UART2 IBRD R = 8; 67 // FBRD = i nt ( 0. 6805 64 + 0. 5) = 44 68 UART2 FBRD R = 44; 69 // 8bi t word l ength , no par i t y bi t , one stop bi t , FIFOs enabl e 70 UART2 LCRH R = (UART LCRH WLEN 8| UART LCRH FEN) ; 71 UART2 CC R = UART CS SysClk ; // Use system c l oc k as UART c l oc k 72 //UART2 CTL R |= UART LB EN; // Enabl e l oopback mode 73 UART2 CTL R |= UART CTL UARTEN; // Enabl e UART2 74 75 } 76 77 // Wait f o r i nput and r e t ur ns i t s ASCII val ue 78 unsi gned char UART Rx( voi d ) { 79 whi l e ( (UART2 FR R & UART FR RXFE) != 0) ; 80 r et ur n ( ( unsi gned char ) (UART2 DR R & 0xFF) ) ; 81 } 82 83 / Accepts ASCII c har ac t e r s from the s e r i a l port and 84 adds them to a s t r i ng . I t echoes each c har ac t e r as i t 85 i s i nput t ed . / 86 voi d UART Rx String ( char pt , unsi gned s hor t max) { 87 i nt l engt h =0; 88 char c har ac t e r ; 89 90 c har ac t e r = UART Rx( ) ; 91 i f ( l engt h < max) { 92 pt = c har ac t e r ; 93 pt++; 94 l engt h++; 95 UART Tx( c har ac t e r ) ; 96 } 97 98 pt = 0; 99 } 100 101 // Output 8bi t to s e r i a l port 102 voi d UART Tx( unsi gned char data ) { 103 whi l e ( (UART2 FR R & UART FR TXFF) != 0) ; 104 UART2 DR R = data ; 105 } 89 106 107 // Output a c har ac t e r s t r i ng to s e r i a l port 108 voi d UART Tx String ( char pt ) { 109 whi l e ( pt ) { 110 UART Tx( pt ) ; 111 pt++; 112 } 113 } 114 115 i nt main( voi d ) { 116 117 char s t r i ng [ 1 7 ] ; 118 119 UART Init ( ) ; 120 121 // The i nput gi ven us i ng keyboard i s di s pl ayed on hyper t er mi nal 122 // . i . e . , data i s echoed 123 UART Tx String ( Enter Text : ) ; 124 125 whi l e ( 1) { 126 UART Rx String ( s t r i ng , 16) ; 127 } 128 }