Lecture 10 - UART Basics ------------------------ 10:10 UART - UART = Universal Asynchronous Receiver Transmitter - A peripheral that helps you send bytes from one computer (microcontroller) to another computer (microcontroller) - Communication is serial: one bit at a time - Asynchronous = without the need for additional clock signal A UART signal needs one single wire for transmission and another single wire for reception (and ground) TX -------->-------- RX Computer-1 Computer-2 RX --------<-------- TX - Serial connections are very popular to connect computer systems (and, in fact, even the dominant interconnection mechanism) - Ethernet - SATA - USB In the world of micro-controllers, serial connections are abundant as well - UART - I2C - SPI - In a serial connection, only one bit at a time is transmitted To transmit a byte, we will transmit each bit of the byte sequentially, typically from the LSB to the MSB - The UART peripheral in a microcontroller is a peripheral that assists the microcontroller software to convert between serial format and parallel format. A very common configuration is when a UART peripheral converts from bytes from the software into the serial line format, and back. Software Send a byte | Hardware UART (converts byte to a sequence of bits) computer-1 | --------------------+------------------------------ | Connection (transmit one bit at a time following selected line format) | --------------------+------------------------------ computer-2 | | Hardware UART (receives one bit and reconstructs a byte) | Software Receives a byte - The things we will learn this week include: - How does the serial data format look like? - How can the UART peripheral help? - How to configure it? - How to send a byte? - How to receive a byte? - What software support exists to use a UART (DriverLib)? - Where to look for documentation? - Examples of transmitting and receiving bytes 10:20 UART Line Format The bits of a byte are represented as a sequence of line symbols that are transmitted at a specified speed of X line symbols per second. Furthermore, additional line symbols are prepended and appended to the data bits so that the receiver can recognize the start and the end of symbol sequence. The symbol rate, the number of line symbols per second, is called the baudrate or BAUD. The baudrate is predefined between the transmitter and receiver. For Asynchronous communications, it is important that both the receiver and the transmitter use the same baudrate. The Typical UART Line format looks as follows: - A start symbol (or start bit) - 8 data bit symbols, LSB to MSB - A stop symbol (or stop bit) While the data bit symbols can have any value, the value of the start bit and the stop bit is fixed: the start bit is always '0', and the stop bit is always '1'. These symbols are transmitted at the selected baudrate. For example, at a baudrate of 9600 baud (=9600 symbols per second), each symbol takes 1/9600 second to transmit. A data byte corresponding to the ASCII character 'A' = 0x41 = 01000001 Looks as follows as UART line symbols: 0 1 0 0 0 0 0 1 0 1 | start bit | | | | | | | | data bits | stop bit You could also draw this as a waveform: ---+ +-+ +-+ +-+----- |0|1|0 0 0 0 0|1|0|1 +-+ +-+-+-+-+-+ +-+ Note that the default value on the UART line is '1'. This is necessary so that the receiver UART can detect the start bit. 10:30 Transmitting and Receiving UART symbols with hardware We will now describe to hardware implementation of a UART peripheral. It's not as detailed as the actual UART in the MSP432P4 chip, but a simplified version that helps you to understand the key principle of operation. To transmit a byte in UART line format, we can use a parallel-to-serial register. Such a register is a chain of flip-flops that can be written in parallel, and then shifted out one bit at a time. The speed of the shifting equals the baudrate. The direction of the shifting is towards LSB bits from a register written by software (the 'UART transmitter register') | | | | | | | | V V V V V V V V R7->R6->R5->R4->R3->R2->R1->R0---> to line Of course, the UART peripheral needs additional hardware to insert a start bit and a stop bit before resp. after shifting out all data bits. Receiving a byte in UART line format is a bit more difficult, because we work with ASYNCHRONOUS reception. That means that the receiver does not know when precisely the next UART symbol will start. The receiver DOES know the baudrate and the UART line format, but the receiver does not know the starting point in time. Thus the UART receiver has a shift register, to receive serial bits into a byte, along with some additional hardware to synchronize the receiver baud clock to the transmitter baud clock. Typically this is done by detecting the start bit (falling edge). from line -+>--R7->R6->R5->R4->R3->R2->R1->R0 | | | | | | | | V V V V V V V V bits of a register read by software (the 'UART receiver register') In order to detect bit values as stable as possible, the receiver will sample the value on the UART line at the center of the bit period. ---+ +-+ +-+ +-+----- | | | | | | +-+ +-+-+-+-+-+ +-+ || | | | | | | | | | || || start bit detected. 1/2 of a symbol period later, the receiver knows it must be the center of the symbol window, so sample the bit there. From that position forward, every symbol period, read one bit until 8 bits are received. Of course, this mechanism only works if the receiver uses the same baud settings as the transmitter. If you use the wrong baud setting, the receiver cannot know: one it sees the edge of a start bit, it assumes a new byte will be received. 10:30 Basic software operation of the UART Given the scenario described above, you can now see how the UART operates. The UART peripheral works with two registers, - A transmitter register - A receiver register When the transmitter register is empty, it means that the UART peripheral is ready to transmit a byte. The software will simply write a byte into the transmitter register, and all the rest goes by itself. As soon as the byte is written into the transmitter register, the hardware takes care of the rest. When the transmitter register is not empty, it means that the UART peripheral is currently transmitting a byte. The software cannot write into the transmitter register now, because that would destroy the UART line format. The software must wait. When the receiver register is empty, it means that the UART peripheral has not byte available (or is busy receiving one). The software has to wait until a complete byte is available. When the receiver register is not empty, it means that the UART peripheral has received a byte, and that the software must read the value of that byte. The receiver register must be read before the next UART symbol arrives, because that could overwrite the value in the receiver register. At the lowest level, DriverLib provides 3 functions that support these scenarios: UART_getInterruptStatus Returns the UART1 transmissions status UART_transmitData Writes one byte into the UART transmitter register UART_getInterruptStatus Returns UART1 receive data available status UART_receiveData Reads the contents of the UART receiver register Note that the 'UART_getInterruptStatus' serves a dual purpose. That register has a few flags to indicate that data can be transmitted, or that received data is available for reading. So you can actually think of four functions as follows. For receiving data: bool UARTHasChar() { return (UART_getInterruptStatus (EUSCI_A0_BASE, EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG) == EUSCI_A_UART_RECEIVE_INTERRUPT_FLAG); } uint8_t UARTGetChar() { if (UARTHasChar()) return UART_receiveData(EUSCI_A0_BASE); else return 0; } For sending data: bool UARTCanSend() { return (UART_getInterruptStatus (EUSCI_A0_BASE, EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG) == EUSCI_A_UART_TRANSMIT_INTERRUPT_FLAG); } void UARTPutChar(uint8_t t) { while (!UARTCanSend()) ; UART_transmitData(EUSCI_A0_BASE,t); } 10:40 Configuration of the UART peripheral A real UART peripheral supports a variety of UART line formats - The number of stop bits can be chosen 1 or 2 stop bits - The number of data bits can be chosen 8 or 9 data bits - An additional 'parity bit' can be added EVEN parity ODD parity NO parity NO parity is as discussed above. A data byte is transmitted as b0 b1 b2 b3 b4 b5 b6 b7 ODD parity ensures odd parity. A data byte is transmitted as b0 b1 b2 b3 b4 b5 b6 b7 p with p = b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7 ^ 1 So that the parity of all bits will always equal 1 EVEN parity ensure even parity. A data byte is transmitted as b0 b1 b2 b3 b4 b5 b6 b7 p with p = b0 ^ b1 ^ b2 ^ b3 ^ b4 ^ b5 ^ b6 ^ b7 So that the parity of all bits will always equal 0 Parity bits are used as a simple error checking mechanism It enables a receiver to detect if a transmission error occurred. When the parity scheme is selected, the receiver can compute the expected parity bit and compare it to the received parity. In case of mismatch: raise error. For example, when the baud rate is not correctly configured, and the parity is enabled, than parity errors will happen almost immediately. Note that a parity bit increases the number of UART line symbols needed. As an example, a scheme with 2 stop bits, 8 data bits, even parity, will use 12 UART line symbols per data byte. So at 9600 baud, we will be able to transmit at most 9600 x 8 / 12 / 8 = 800 bytes per second A UART peripheral supports multiple baudrates. The speed of the baudrate generators is programmed by selecting a divisor for the system clock. We will discuss baud rate setting in more detail in the next lecture. But the high level idea is as follows. We start from the system clock, which is 3MHz in our case. Then, we will divide the clock frequency until we get something that is close to the baud rate. For example, let's say that we would want 9600 baud. Then we would need to divide the clock frequency by N = 3000000 / 9600 = 312.5 Of course, dividing a clock by a fractional rate is not easy, and the UART peripheral has special-purpose hardware for that. Setting the baud rate on a UART peripheral means that you need to program the special-purpose clock divider hardware. We will discuss on Wednesday how this is done. 10:50 Quick Demo Run the starter code for Lab 2 with MobaXterm. 10:55 Conclusions - UART = serial data transmission - Major concepts: Baud Stop Bit, Start Bit Parity Bit - Basic UART hardware - Basic UART software operation Receiving and Transmitting a character