Jump to content


View Other Content



Search Articles



Recent Comments


- - - - -

PIC18 RS-232 / Serial Communication


Make sure you have a copy of the datasheet for your PIC. Here's a link to the PIC18F4550 datasheet.

The PIC18F4550 has one EUSART or Enhanced Universal Synchronous Asynchronous Receiver Transmitter module. The enhanced USART has several features that normal USART modules do not have; perhaps most notably, it has automatic baud rate detection (ABD). ABD is only available in asynchronous mode and using it disables the ability to transmit data. If your PIC microcontroller only receives data, ABD can be useful, as a baud rate does not have to be specified and the PIC microcontroller will automatically detect what baud rate the external device, such as a PC, is using.

The EUSART module can operate in asynchronous or synchronous mode. I'll be configuring the EUSART module to operate in asynchronous mode.

There are three registers associated with the EUSART module:
  • TXSTA: Transmit Status and Control
  • RCSTA: Receive Status and Control
  • BAUDCON: Baud Rate Control
  • SPBRGH: Baud Rate Generator Register High Byte
  • SPBRG: Baud Rate Generator Register Low Byte
  • TX:
  • RX:
We'll first configure the TXSTA register:

TXSTAbits.TX9 = 0;  // 8-bit transmission
TXSTAbits.TXEN = 1; // Transmit enabled
TXSTAbits.SYNC = 0; // Asynchronous mode
TXSTAbits.BRGH = 1; // High speed

Now for the RCSTA register:

RCSTAbits.SPEN = 1; // Enable serial port - configures RX/DT and TX/CK pins as serial port pins.
RCSTAbits.RX9 = 0;  // 8-bit reception
RCSTAbits.CREN = 1; // Enable receiver

Finally, the BAUDCON register:

BAUDCONbits.BRG16 = 1;

Now we have to configure the baud rate generator.

The formulas for calculating the baud rate are given in Table 20-1:

Posted Image

I'm using the UART module in asynchronous high speed mode (SYNC = 0, BRGH = 1), so I need to use the second formula. Rearranging a bit, we can solve for the value we need to put into SPBRGH:SPBRG (n): dependent on the oscillator frequency and desired baud rate.









The frequency of the oscillator on my board (Fosc) is 48 MHz, and I'll choose a baud rate (transmission speed) of 115200. Plugging these numbers into the above equation, the value for SPBRGH:SPBRG can be found:



So, the value "25" will need to be written to the SPBRGH:SPBRG registers.

Note: You may find the PIC18 interrupts tutorial helpful.

Example program

#include "p18f4550.h"

/***************************
*   Device configuration   *
***************************/
#pragma config FOSC = HSPLL_HS	// Using 20 MHz crystal with PLL
#pragma config PLLDIV = 5     	// Divide by 5 to provide the 96 MHz PLL with 4 MHz input
#pragma config CPUDIV = OSC1_PLL2 // Divide 96 MHz PLL output by 2 to get 48 MHz system clock
#pragma config FCMEN = OFF // Disable Fail-Safe Clock Monitor
#pragma config IESO = OFF  // Disable Oscillator Switchover mode
#pragma config PWRT = OFF  // Disable Power-up timer
#pragma config BOR = OFF   // Disable Brown-out reset
#pragma config WDT = OFF   // Disable Watchdog timer
#pragma config MCLRE = ON  // Enable MCLR Enable
#pragma config LVP = OFF   // Disable low voltage ICSP
#pragma config ICPRT = OFF // Disable dedicated programming port (only on 44-pin devices)
#pragma config CP0 = OFF   // Disable code protection

// Function declarations
void config(void);

void main (void)
{
    config();
    
    while(1)
    {
   	 // program loop
    }    
}

void config (void)
{
    // USART configuration
    TXSTAbits.TX9 = 0;  // 8-bit transmission
    TXSTAbits.TXEN = 1; // transmit enabled
    TXSTAbits.SYNC = 0; // asynchronous mode
    TXSTAbits.BRGH = 1; // high speed
    RCSTAbits.SPEN = 1; // enable serial port - configures RX/DT and TX/CK pins as serial port pins
    RCSTAbits.RX9 = 0;  // 8-bit reception
    RCSTAbits.CREN = 1; // enable receiver
    BAUDCONbits.BRG16 = 0; // 8-bit baud rate generator
    SPBRG = 25; // write the decimal value 25 to the baud rate generator - value calculated using formula from table 20-1 in the PIC18F4550 datasheet
    
    TRISCbits.RC6 = 1;
    TRISCbits.RC7 = 1;
    
    // interrupts / USART interrupts configuration
    RCONbits.IPEN = 0;   // disable interrupt priority
    INTCONbits.GIE = 1;  // enable interrupts
    INTCONbits.PEIE = 1; // enable peripheral interrupts.
    PIE1bits.RCIE = 1; // enable USART receive interrupt
}

// start ISR code
#pragma code isr = 0x08 // store the below code at address 0x08
#pragma interrupt isr

void isr (void)
{
    if(PIR1bits.RCIF == 1) // if the USART receive interrupt flag has been set
    {
   	 if(PIR1bits.TXIF == 1) // check if the TXREG is empty
   	 {
   		 TXREG = RCREG; // echo received data back to sender
   	 }
    }    
}

#pragma code // return to the default code section
// end ISR code



0 Comments


or Sign In