10.4 UART receiver
The UART receiver functional block diagram is shown in Fig. 10-5. The heart of the receiver is the receive shift register UxRSR where a serial sequence is converted to a parallel word (9-bit word). After sampling the UxRX pin for the STOP bit, the received data in UxRSR are transferred to the receive FIFO buffer, if it is empty.
Fig. 10-5 UART receiver functional block diagram.
The data on the UxRX pin are sampled three times by a majority detect circuit to determine if a high or a low level is present at the UxRX pin.
The UxRSR register is nor mapped in data memory, so it is not available to the user.
The FIFO receive data buffer consists of four 9-bit wide memory locations. The access to the contents of the receive FIFO buffer is via the UxRXREG read-only register. It is possible for 4 words of data to be received and transferred to the FIFO buffer and a fifth word to begin shifting data to the UxRSR register before a buffer overrun occurs. When the FIFO is full (four characters) and a fifth character is fully received into the UxRSR register, the overrun error bit OERR (UxSTA<1>) will be set. The word in UxRSR will be kept, but further transfers to the receive FIFO are inhibited as long as the OERR bit is set. The user must clear the OERR bit in software to allow further data to be received. Clearing the OERR bit, clears the receive FIFO buffer.
The data in the receive FIFO should be read prior to clearing the OERR bit. The FIFO is reset when OERR is cleared, which causes data in the buffer to be lost.
The parity error bit PERR (UxSTA<3>) is set if a parity error has been detected in the received data (the last word in the receive FIFO buffer), i.e. the total number of ones in the data is incorrect (odd for EVEN parity mode or even for ODD parity mode). The PERR bit is irrelevant in the 9-bit mode. For the 8-bit mode, prior to reading the data from the receive FIFO, the FERR and PERR flags should be checked to ensure that the received data are correct.
10.4.1 Receive interrupt
The URXISEL<1:0> (UxSTA<7:6>) control bit determines when the UART receiver generates an interrupt. The UART receive interrupt flag (UxRXIF) is located in the corresponding interrupt flag status, IFS register.
- If URXISEL<1:0> = 00 or 01, an interrupt is generated each time a data word is tranferred from the receive shift register to the receive FIFO buffer. There may be one or more characters in the receive FIFO buffer.
- If URXISEL<1:0> = 10, an interrupt is generated when a word is transferred from the receive shift register to the receive FIFO buffer and as a result, the receive buffer contains 3 or 4 characters.
- If URXISEL<1:0> = 11, an interrupt is generated when a word is transferred from the receive shift register to the receive FIFO buffer and as a result, the receive buffer contains 4 characters, i.e. becomes full.
Switching between the three interrupt modes during operation of the UART module is possible.
The URXDA bit (UxSTA<0>) indicates whether the receive FIFO buffer is empty. This bit is set as long as there is at least one character to be read from the receive buffer. URXDA is a read only bit.
The URXDA and UxRXIF flag bits indicate the status of the UxRXREG register. The RIDLE bit (UxSTA<4>) shows the state of the shift register UxRSR. The RIDLE status bit is a read only bit, which is set when the receiver is IDLE (i.e. the UxRSR register is empty and there is no current data reception). No interrupt logic is tied to this bit, so the user has to poll this bit in order to determine if the UxRSR is IDLE.
10.4.2 Setup for UART reception
When setting up a reception, the following steps should be undertaken:
- Initialize the UxBRG register for the appropriate baud rate.
- Set the number of data bits, number of STOP bits, and parity selection by writing to the PDSEL<1:0> (UxMODE<2:1>) and STSEL (UxMODE<0>) bits.
- If receive interrupts are desired, set the UxTXIE control bit in the corresponding interrupt enable control register (IEC). Specify the interrupt priority using the UxRXIP<2:0> control bits in the corresponding interrupt priority control register (IPC). Select the transmit interrupt mode by writing the URXISEL (UxMODE<15>) bit.
- Enable the UART module by setting the UARTEN (UxMODE<15>) bit.
- Receive interrupts will depend on the URXISEL<1:0> control bit settings. If receive interrupts are not enabled, the user can poll the URXDA bit to check the contents of the receive FIFO buffer. The UxRXIF bit should be cleared during initialization.
- Finally, read data from the receive FIFO buffer via the UxRXREG register. If 8-bit mode is used, read a byte (8-bits). If 9-bit mode has been selected, read a word (16-bits).
Fig. 10.6 shows an example of serial data reception using the UART transmitter. The waveforms for two 8-bit bytes are shown. Fig. 10-7 shows the reception with a receive overrun of the receive FIFO buffer
Fig. 10-6 Example of serial data reception of two 8-bit bytes
Fig. 10-7 Example of serial data reception with an overrun of the receive FIFO buffer
The UART module is often used for muli-processor communication. In the multi-processor communication typical communication protocols are: data bytes and address/control bytes. A common schematic is to use a 9th data bit to identify whether a data byte is address or data information. If the 9th bit is set, the data is processed as address or control information. If the 9th bit is cleared, the received data word is processed as data associated with the previous address/control byte.
A common multi-processor protocol operates as follows:
- The master device transmits a data word with the 9th bit set. The data word contains the address of a slave device.
- The slave devices in the communication chain receive the address word and check the slave address value.
- The slave device that was addressed will receive and process subsequent data bytes sent by the master device. All other slave devices will discard subsequent data bytes until a new address word (9th bit set) is received.
The UART receiver can be configured to operate in the address detection mode by setting the ADDEN (UxSTA<5>) control bit. In this mode, the receiver will ignore data words with the 9th bit cleared. This reduces the number of interrupts of the UART module, since data words with the 9th bit cleard are not buffered.
To operate in the address detection mode, the UART must be configured for 9-bit data. The ADDEN bit has no effect when the receiver is configured in 8-bit data mode.
The setup procedure for 9-bit transmission is identical to the 8-bit transmit modes, except that PDSEL<1:9> (UxMODE<2:1>) should be set to '11'.
The setup procedure for 9-bit reception is similar to the 8-bit receive modes, except that PDSEL<1:0> (UxMODE<2:1>) should be set to '11'. The receive interrupt mode should be configured by setting the URXISEL<1:0> (UxSTA<7:6>) control bits.
If the address detect mode is enabled, the URXISEL<1:0> control bits should be configured so that an interrupt will be generated after every received word, i.e. they should be set to '00' or '11'. Each received data word must be checked in software for an address match immediately after reception.
The procedure for using the address detect mode is as follows:
- Set the ADDEN (UxSTA<5>) bit to enable address detect. Ensure that the URXISEL control bits are configured to generate an interrupt after rach received word.
- Check each 8-bit address by reading the UxRXREG register, to determine if the device is being addressed.
- If this device has not been addressed, then discard the received word.
- 4. If the device has been addressed, clear the ADDEN bit to allow subsequent data bytes to be read into the receive FIFO buffer and interrupt the CPU. If a long data packet is expected, then the receive interrupt mode could be changed to buffer more than one data byte between interrupts by setting control bits URXISEL<1:0> (UxSTA<7:6>) to '10' or '11'.
- When the last data byte has been received, set the ADDEN bit so that only address bytes will be received. Also, ensure that the URXISEL control bits are configured to generate interrupt after each received word.
Fig. 10-8 Example of data reception in the address detect mode (ADDEN=1)
The receiver will count and expect a certain number of bit times based on the values programmed in the PDSEL (UxMODE<2:1>) and STSEL (UxMODE<0>) bits. If more than 13 bits at the low logic level occur, the BREAK character has been received. After 13 bits at the low logic level, a STOP bit has to be detected. Then, on the basis of the set FERR flag one can conclude that a BREAK character has been transmitted. If the STOP bit has not been received, the RIDLE status bit is at the low logic level, i.e. the receiver had not detected the end of the message,irrespective of the FERR flag.
This example shows the use of the specialized UART library of the mikroPascal compiler for dsPIC devices which greatly facilitates the initiaization of the UART module, writing, and reading data to and from the transmitter and receiver of the UART module, respectively. The example also shows the interconnection of the UART module and the RS-232 transiever and the connection of the UART module to the serial port of a PC.
Fig. 10-9 Connection of the UART module to the serial port of a PC via the RS-232 transiever.
var text, delimiter : string;
test : word;
Uart1_Init(9600); //Initialization of UART module on 9600Kbps
delimiter := 'stop'; //Delimiter is word 'stop'
while TRUE do
if Uart1_Data_Ready() = 1 then //If data are received
Uart1_Read_Text(text, delimiter); //Only if STOP is received
Uart1_Write_Text(text); //Message is returned (echo)
The program initializes the UART module in the receive and transmit 8-bit format mode, without parity, and with one stop bit. If another format is to be initialized, the procedure Uart1_Init_Advanced instead of Uart1_Init must be used. In this way it is possible to setup 9-bit data or perhaps 8-bit data with an EVEN or ODD parity bit. Also it is possible to select one or two STOP bits. The procedure Uart1_Data_Ready the value of the status bit URXDA (U1STA<0>) is read and the presence of data in the receive FIFO buffer is checked. The procedures Uart1_Write, Uart1_Write_Char, and Uart1_Write_Text data, ASCII character and text are sent respectively via the transmitter of the UART module. Data reception, ASCII character and text is realized by the procedures Uart1_Read, Uart1_Read_Char, and Uart1_Read_Text, respectively. The UART module disable is performed by the procedure Uart1_Disable (clear the UARTEN control bit); the UART module enable is performed by the procedure Uart1_Enable (set the UARTEN control bit).