Setup for UART Receive

The following procedure is used to receive a byte of data:

  1. Configure the clock input and baud rate as detailed in Clocking and Baud Rate Configuration.
  2. Configure the data width and parity by writing a selection to the MODE[3:0] bits.
  3. Configure the polarity, Stop bit duration and flow control.
  4. Configure the RX interrupt watermark using the RXWM[2:0] bits (UxSTAT[26:24]).
  5. Configure the address detect if needed as detailed in Address Detect.
  6. Set the ON bit (UxCON[15]).
  7. Set the RXEN bit (UxCON[4]).

An RX interrupt will be generated when a byte is received according to the UART Receive Interrupt Select bits setting, RXWM[2:0] (UxSTAT[26:24]). The RXWMx bits can be configured to generate an RX interrupt when the RX buffer contains 1-8 bytes.

Software can then read the data from the UxRXB register. The time, relative to the Stop bit when the RX interrupt is generated, is configurable using the STPMD bit (UxSTAT[22]). By default, an RX interrupt is generated in the middle of the Stop bit. Writing a ‘1’ will move the RX interrupt to the end of the Stop bit.

The RXBF status bit (UxSTAT[16]) can be read by software to determine if the receive buffer is full and a read operation of UxRXB is required to allow reception of additional bytes. Similarly, the RXBE status bit (UxSTAT[17]) can be read with software to determine if the receive buffer is empty.

UART1 Reception with Interrupts

#include<xc.h>
#define FUART 4000000
#define BAUDRATE 9600
#define BRGVAL (((FUART/BAUDRATE)/16)-1)
uint8_t ReceivedChar[10];
uint8_t i=0;
int main(void) {
    // Configure oscillator as needed
    
    // Configure oscillator as needed
    ANSELB=0;
    _U1RXR = 24; // Assign U1RX to RP24
    
    U1CONbits.MODE = 0;         // Asynchronous 8-bit UART
    U1CONbits.BRGS = 0;         // Low-Speed Mode
    U1CONbits.CLKSEL = 0;       // FPB/2 as Baud Clock source
    U1CONbits.STP = 0;          // 1 stop bit
    U1BRG = BRGVAL;             // BRG setting for 9600 baud rate
    U1STATbits.RXWM = 0;        // Interrupt when there is one word or more in the buffer
    _U1RXIE = 1;                // Enable Receive interrupt
    U1CONbits.ON = 1;           // Enable UART
    U1CONbits.RXEN = 1;         // Enable UART RX

    while(1)
    {
    }
    return 0;
}
void __attribute__((interrupt, no_auto_psv)) _U1RXInterrupt(void)
{
    _U1RXIF = 0; // Clear RX interrupt flag
    while(U1STATbits.RXBE == 0)     // Check if RX buffer has data to read
    {
        ReceivedChar[i++] = U1RXB; // Read a character from RX buffer
    }
}