PIC UART Print Guide: Replacing Serial.println() With printf() (XC8 + MCC, With Debug Tips)

Use printf() from <stdio.h> within MPLAB’s XC8 environment. This brief shows how to print data from a PIC16F13145 Curiosity Board to MPLAB’s terminal window.

At a Glance

  • Enable the UART from MCC (graphical configuration examples included)
  • Assign UART I/O pins
  • Redirect the printf() stream to the UART
  • Send data from main
void main(void){

    SYSTEM_Initialize();     // MCC generated code
    
    while(1){
        printf("Hello World!\r\n");
    }
}

Last updated: 01 December, 2025

Figure 1: The COM4 connection is active and Hello World! is printing in the terminal window.

Tech Tip: Don’t forget to assign pins to the UART. This should be one of the first places you look if things are not operating correctly. Personally, I like to add these LED logic probes to the TX and RX pins. This provides visual feedback to simplify the troubleshooting process.

How to Configure the UART

Figure 2 presents the graphical configuration:

  • The UART has been added to the application builder.

  • The baud rate is set for 9600.

  • The printf() stream is redirected to the UART (blue slider).

Once the MCC .h and .c files are generated, we are ready to print to the serial port using code like this:

    printf("Hello World!");

Figure 2: Configuration of the UART baud rate as well as redirect of printf to the UART.

Where is the MCC documentation?

MPLAB’s MCC tool constructs lightweight peripheral wrappers. These standardized methods may then be called from main(). The detailed documentation is found by clicking on the question mark in the project resource section (upper-left corner of Figure 3).

A related example is the millisecond callback described in this article.

Figure 3: Click on the question mark to locate the MCC peripheral wrapper documentation.

Tech Tip: Don’t touch the MCC-generated files. Instead, call the wrappers from main. This way your code will not be clobbered by MCC on the next microcontroller reconfiguration.

Later as you gain experience, you can move the register configuration from MCC into main. Advanced programmers often remove the MCC abstraction and configure the peripherals directly. They often program directly from the datasheet information.

Parting Thoughts

The printf() function is big and slow for microcontroller use. A lookup table that writes directly to the UART hardware within a tight loop is faster and uses less flash memory. However, as a first-time user, printf() is a good place to start as you can leverage decades of C tutorials and online debuggers. Efficiency can come later.

Best wishes,

APDahlen

Related Articles by this Author

If you enjoyed this article, you may also find these related articles helpful:

About This Author

Aaron Dahlen, LCDR USCG (Ret.), serves as an application engineer at DigiKey. He has a unique electronics and automation foundation built over a 27-year military career as a technician and engineer which was further enhanced by 12 years of teaching (interwoven). With an MSEE degree from Minnesota State University, Mankato, Dahlen has taught in an ABET-accredited EE program, served as the program coordinator for an EET program, and taught component-level repair to military electronics technicians.

Dahlen has returned to his Northern Minnesota home, completing a decades-long journey that began as a search for capacitors. Read his story here.