CCS News


Tuesday 31 August, 2021

Almost every new PIC® microcontroller Microchip has released in the last few years has a peripheral called the Peripheral Pin Select (PPS) peripheral. This peripheral is used to assign what pins are used as the peripheral pins for most digital peripheral. This means instead of a specific pin or pins that has to be used with a peripheral you can choose the pin or pins to use with it. This is very useful on low pin count devices were a single pin would have had multiple peripheral functions on a single pin causing you to choose which peripheral to use. The way the PPS peripheral works for peripheral pins that are outputs, the UART TX pin for example, the peripheral is assigned to the pins, and for peripheral pins that are inputs, the UART RX pin for example, the pin is assigned to the peripheral. Because of this it's possible to assign multiple pins to the same output peripheral, but only one pin can be assigned to an input peripheral.

To assign a pin as a peripheral pin the CCS C Compiler has several methods to do this. The primary method is the #pin_select directive. The #pin_select directive is a preprocessor directive used to assign pins at compile time. The format for the #pin_select directive is as follows:

#pin_select xx=yy

With xx being the peripheral to assign the pin to, see the PIN_SELECT section of the device's header file for a list of the peripherals pins can be assigned to, and yy being one of the pin defines in the device's header file. The following is an example of how to assign the UART1 TX and RX pins using the #pin_select directive:

#pin_select U1TX=PIN_C6
#pin_select U1RX=PIN_C7

However not all pins can be assigned as a peripheral pin, to determine which can be assigned under the PIN_SELECT section of the device's header is a list of pins that can be assigned as peripheral pins. Additionally not all valid pins can be assigned to every peripheral, some device only allow certain port pins to be assigned to a specific peripheral were as some other devices only allow some pins to be assigned as input peripheral pins. This is device dependent and the device's data sheet should be checked carefully when laying out the peripheral pins for device with a PPS peripheral. The #pin_select directive does have checks to make sure a pin can be assigned to a peripheral, and will generate a compiler error if a pin can't be assigned to a peripheral or if the pin isn't a remappable peripheral pin.

Another method the CCS C Compiler has for assigning pins as peripheral pins is the pin_select() function. The pin_select() function can be used to assign pins at run time. This is useful in cases were more then one pin needs to be assigned to a single output peripheral, if a single pin needs to be used by multiple peripherals or if the pins assignments need to changed, for example, in a case were the code needs to support multiple hardware configurations. The format the pin_select() directive is as follows:

pin_select("xx", yy, aa, bb);

With xx being the same peripheral names used by #pin_select and yy being one of the pin defines in the device's header file. Additionally aa and bb are optional parameters used to specify whether to do or not to do the unlock and lock procedures, TRUE does the procedure and FALSE doesn't to the procedure. With aa specifying the unlock procedure and bb specifying the lock procedure. When the aa and bb parameters are not specified in the function call the lock and unlock procedures are both performed by default. These optional parameters are most useful when using the pin_select() function to assign multiple peripheral pins sequentially. For example, the following is an example of of how to assign the UART1 TX and RX pins at run time:

pin_select("U1TX", PIN_C6, TRUE, FALSE);
pin_select("U1RX", PIN_C7, FALSE, TRUE);

Another useful feature of the pin_select() function is that it can be used to unassign the peripheral pins. The format of the function call depends on the whether unassignment is for an output peripheral or an input peripheral pin. To unassign an output peripheral pin the following format is used:

pin_select("NULL", yy);

With yy being the one of the pin defines in the device's header file. To unassign an input peripheral pin the following format is used:

pin_select("xx", FALSE);

With xx being same peripheral names used by #pin_select. For example, the following is an example of unassigning the previously assigned UART1 TX an RX pins:

pin_select("NULL", PIN_C6, TRUE, FALSE);
pin_select("U1RX", FALSE, TRUE);

The final method has for assigning the peripheral pins is some for the #use directive can make the peripheral pin assignments, the #use pwm() directive, for example. For #use directive that this is supported with the format is similar to the following, see the help file entry for the #use directive for the exact format:

#use pwm(CCP1, output=PIN_B0)

The above will make the assignment of PIN_B0 as the CCP1 output pin. This method is currently not supported by all of the #use directives, currently only the #use pwm() and #use capture() directives support this feature. For the other #use directives #pin_select should be used to assign the peripheral pins before the #use directive line. The #use rs232() is an example were the pins should be assigned using the #pin select directive before the #use rs232() line if the hardware UART pins are to be used on a PPS device were the UART pins are remappable peripheral pins. Without the assignments the compiler will implement a software RS232 instead. For example, the following will assign the UART1 TX and RX pins and setup the RS232 to use the hardware UART peripheral:

#pin_select U1TX=PIN_C6
#pin_select U1RX=PIN_C7

#use rs232(xmit=PIN_C6, rcv=PIN_C7, baud=115200, stream=U1_STREAM)

Like us on Facebook. Follow us on Twitter.

About CCS:

CCS is a leading worldwide supplier of embedded software development tools that enable companies to develop premium products based on Microchip PIC® MCU and dsPIC® DSC devices. Complete proven tool chains from CCS include a code optimizing C compiler, application specific hardware platforms and software development kits. CCS' products accelerate development of energy saving industrial automation, wireless and wired communication, automotive, medical device and consumer product applications. Established in 1992, CCS is a Microchip Premier 3rd Party Partner. For more information, please visit

PIC® MCU, MPLAB® IDE, MPLAB® ICD2, MPLAB® ICD3 and dsPIC® are registered trademarks of Microchip Technology Inc. in the U.S. and other countries.