For this tutorial you’ll need the following:
- A PIC24 hardware platform – such as our picoTRONICS24 or nanoTRONICS24 microcontroller development boards
- Microchip’s FREE MPLAB X IDE – make sure you’ve got the latest version – they are updating it all the time
- Microchip’s FREE C30 or XC16 C Compiler – also make sure you have the latest version
- We also assume you have working knowledge of C/C++ – if you don’t have this there a many good C/C++ tutorials availible on the internet.
Peripheral Pin Select – PPS – Basics
Most microcontrollers provide the programmer with a selection of peripherals, such as UART, SPI, I2C, USB etc, that they can use in their programs. These peripherals are implemented natively in the microcontrollers hardware, meaning the programmer doesn’t need to worry about implementing them, they simply need to control them. Most microcontrollers fix these peripherals to particular pins on the microcontroller, leaving the programmer with limited flexibility and locking them into a particular hardware design at board design time.
Microchips PIC24F series of microcontrollers, include a feature called Peripheral Pin Select (PPS) that allows the programmer to assign many of the peripherals offered by the microcontroller to pins at run-time. This is an incredibly handy and powerful feature that we, at Modtronics, use a lot. Not only does it mean that you’re not locked into your hardware design when you build your board it also allows the programmer the flexibility to share the same pins amongst different peripherals in their program.
At first this may sound like a complicated feature that would be difficult to use, but it actually turns out to be relatively simple.
What Pins & Peripherals Support PPS?
As we mentioned in our previous tutorial, on IO pins, any pins with the prefix RP (eg RP0 & RP1 etc) supports PPS. As you can see in the pin diagram below, for the PIC24FJ64GB004, a significant number of pins support this functionality.
Most of the major digital peripherals on the PIC24F series of microcontrollers can be assigned by PPS. This includes:
- External Interrupts and
- Output Compare
Setting up PPS – Example Code
So, what do you need to do to setup PPS for your application? Well luckily it is actually quite simple. Broadly the main steps you need to follow are:
- Configure the data direction register (TRISx) for your chosen pin to the correct value. For example, for the UART TX pin the relevant TRISx bit will need to set to an output.
- “Unlock” the PPS functionality on the microcontroller
- Set the relevant PPS configuration
- “Relock” the PPS functionality;
- And you’re done! Easy as 1,2,3,4…
This is probably best illustrated with a worked example. For this example we’ll setup UART1 to be connected to the following pins:
- UART TX -> Pin RB3
- UART RX -> Pin RB7
Setting Up the TRISx bits
The first step in this process is to setup up the TRISx bits correctly. The following code snippet is responsible for configuring these:
inline void configurePortPins( void )
// Turn off analogue functions on all pins
AD1PCFG = 0xFFFF;
// Configure UART TRISx bits
TRISBbits.TRISB3 = 0; // Configure the TX pin (RB3)
TRISBbits.TRISB7 = 1; // Configure the RX pin (RB7)
Once these have been successfully configured, the next step in the process is to assign the peripheral to the pin using the PPS functionality. The following code snipped is responsible for configuring this:
inline void configurePPS( void )
PPSUnLock; // Unlock the PPS functionality
// Configure UART PPS pins
// Assign the Uart RX function to the correct pin
iPPSInput( IN_FN_PPS_U1RX, IN_PIN_PPS_RP7 );
// Assign the Uart Tx function to the correct pin
iPPSOutput( OUT_PIN_PPS_RP3, OUT_FN_PPS_U1TX );
PPSLock; // Lock the PPS functionality
With this complete the UART1 peripheral is now correctly assigned to the nominated pins and our job is done! As you can see it is very simple task.