Difference between revisions of "Embedded System Tutorial UART"
From Embedded Systems Learning Academy
(→UART Pins) |
|||
(17 intermediate revisions by 4 users not shown) | |||
Line 1: | Line 1: | ||
+ | Socialledge is moving to two portals. | ||
+ | * The Wiki will remain here for general references about the SJ-One board, and to document student reports. | ||
+ | * The bookstack will now be used for SJSU assignments | ||
+ | |||
+ | [http://books.socialledge.com/books/embedded-drivers-real-time-operating-systems/chapter/lesson-uart This article has been moved here] | ||
+ | |||
+ | <!-- | ||
== Introduction == | == Introduction == | ||
The objective of this lesson is to understand UART, and use two boards and setup UART communication between them. | The objective of this lesson is to understand UART, and use two boards and setup UART communication between them. | ||
− | '''UART''' stands for '''U'''niversal '''A'''synchronous '''R'''eceiver '''T'''ransmitter. There is one wire for transmitting data, | + | '''UART''' stands for '''U'''niversal '''A'''synchronous '''R'''eceiver '''T'''ransmitter. There is one wire for transmitting data, and one wire to receive data. A common parameter is the baud rate known as "bps" which stands for '''b'''its '''p'''er '''s'''econd. If a transmitter is configured with 9600bps, then the receiver must be listening on the other end at the same speed. |
− | UART is a serial communication, so bits must travel on a single wire. If you wish to send a '''char''' over UART, the char is enclosed within a '''start''' and a '''stop''' bit, so to send 8-bits of '''char''' data, it would require 2-bit overhead; this 10-bit of information is called a '''UART frame'''. Let's take a look at how the character 'A' is sent over UART. In ASCII table, the character 'A' has the value of 65, which in binary is: 0100. | + | UART is a serial communication, so bits must travel on a single wire. If you wish to send a '''char''' over UART, the char is enclosed within a '''start''' and a '''stop''' bit, so to send 8-bits of '''char''' data, it would require 2-bit overhead; this 10-bit of information is called a '''UART frame'''. Let's take a look at how the character 'A' is sent over UART. In ASCII table, the character 'A' has the value of 65, which in binary is: 0100-0001. If you inform your UART hardware that you wish to send this data at 9600bps, here is how the frame would appear on an oscilloscope : |
[[File:uart_tutorial_frame.jpg|center|frame|UART Frame of 'A']] | [[File:uart_tutorial_frame.jpg|center|frame|UART Frame of 'A']] | ||
A micrcontroller can have multiple UARTs in its hardware, and usually UART0 is interfaced to a "USB to serial" converter chip which is then connected to your computer. In this exercise, you will write a driver for UART-2 and attempt to communicate between two boards. | A micrcontroller can have multiple UARTs in its hardware, and usually UART0 is interfaced to a "USB to serial" converter chip which is then connected to your computer. In this exercise, you will write a driver for UART-2 and attempt to communicate between two boards. | ||
+ | |||
+ | I encourage you to fully read this article first, and here is a video about the UART0 tutorial. This is a FAST PACED video, so learn to pause the video and look over your LPC user manual frequently :) '''Note that I forgot to configure the PINSEL registers, which are covered by this tutorial below.''' | ||
+ | * [https://www.youtube.com/watch?v=RU_NUPprx2Y UART Driver Video] | ||
<BR/> | <BR/> | ||
+ | |||
== UART Pins == | == UART Pins == | ||
Before you write a UART software driver, you need to understand the physical constraints and identify the UART pins on your processor. A GPIO (general purpose input output) is a multi-purpose pin, and certain pins are used for certain functions. For example, P0.0 and P0.1 on your LPC17xx processor can be used for an LED (output), a switch (input), or as UART transmitter and receive signals. We will configure the microcontroller's internal MUX (multiplexor) to connect internal UART to external pins. | Before you write a UART software driver, you need to understand the physical constraints and identify the UART pins on your processor. A GPIO (general purpose input output) is a multi-purpose pin, and certain pins are used for certain functions. For example, P0.0 and P0.1 on your LPC17xx processor can be used for an LED (output), a switch (input), or as UART transmitter and receive signals. We will configure the microcontroller's internal MUX (multiplexor) to connect internal UART to external pins. | ||
− | [[File:tutorial_uart_pinsel.png| | + | [[File:tutorial_uart_pinsel.png|center|Find RXD2 and TXD2 of UART2]] |
+ | <BR/> | ||
+ | [[File:tutorial_gpio_mux.png|center|Example MUX that we need to configure for a PIN selection]] | ||
<BR/> | <BR/> | ||
Line 53: | Line 66: | ||
LPC_UART0->LCR = (1 << 7); // Enable DLAB | LPC_UART0->LCR = (1 << 7); // Enable DLAB | ||
+ | /* See the formula picture to get more info. | ||
+ | * Default values of fractional dividers simplifies the equation | ||
+ | * Warning: You need to set DLM/DLL correctly, but if divider is small enough, it will fit inside DLL | ||
+ | */ | ||
LPC_UART0->DLM = 0; | LPC_UART0->DLM = 0; | ||
− | |||
− | |||
LPC_UART0->DLL = CPU_CLOCK / (16 * 9600) + 0.5); | LPC_UART0->DLL = CPU_CLOCK / (16 * 9600) + 0.5); | ||
+ | |||
LPC_UART0->LCR = 3; // 8-bit data | LPC_UART0->LCR = 3; // 8-bit data | ||
} | } | ||
Line 79: | Line 95: | ||
== Advanced Design == | == Advanced Design == | ||
What you've done so far is wrote a polling UART driver. If you used 9600bps, and sent 1000 characters, your processor would basically enter a "busy-wait" loop and spend 1040ms to send 1000 bytes of data. You can enhance this behavior by allowing your <code>uart_putchar()</code> function to enter data to a queue, and return immediately, and you can use the "THRE" or "Transmitter Holding Register Empty" interrupt indicator to remove your busy-wait loop while you wait for a character to be sent. | What you've done so far is wrote a polling UART driver. If you used 9600bps, and sent 1000 characters, your processor would basically enter a "busy-wait" loop and spend 1040ms to send 1000 bytes of data. You can enhance this behavior by allowing your <code>uart_putchar()</code> function to enter data to a queue, and return immediately, and you can use the "THRE" or "Transmitter Holding Register Empty" interrupt indicator to remove your busy-wait loop while you wait for a character to be sent. | ||
+ | |||
+ | == Assignment == | ||
+ | * <b>Assignment Outline</b> | ||
+ | *: Form 2 people teams for this assignment. | ||
+ | *: Write a driver for UART2 or UART3 | ||
+ | *: Do not use the pre-built driver or Uart2/3 class | ||
+ | *: Connect your UART to your partner's UART (to his board) | ||
+ | *: Prove that you can send/receive data across multiple boards. | ||
+ | *: Upload Logic Analyzer Screenshot for the UART Frame. | ||
+ | * <b>Extra Credit</b>: | ||
+ | *: Use Uart interrupt to queue the received data to avoid polling. You just need to enable UART RX interrupt and then hookup an interrupt callback to do the receive. | ||
+ | * <b>Steps</b> | ||
+ | *: Locate the physical pins for a UART that is not already used by your board | ||
+ | *: Configure the PINSEL to use the pins for UART Rx/Tx | ||
+ | *: Initialize your UART at any baud rate | ||
+ | *: Write uart_putchar(char) and uart_getchar() functions | ||
+ | *: Interface your UART with someone else's board, and test the communication. | ||
+ | --> |
Latest revision as of 20:05, 25 January 2019
Socialledge is moving to two portals.
- The Wiki will remain here for general references about the SJ-One board, and to document student reports.
- The bookstack will now be used for SJSU assignments
This article has been moved here