The General Purpose Input/Output Port is the simplest interface found on a microcontroller and it may be used as a basic user interface (driving LEDs or monitoring switches), or to monitor and control other devices.
To add flexibility and functionality to a device, especially for a low pin count microcontroller, some pins are multiplexed with different functions. For example, the pin number 35 of a PIC24FJ128GA006 device, depending on the active peripheral, may have one of the following functions: UART1 Request to Send Output, UART1 IrDA® Baud Clock, SPI1 Serial Clock Output, External Interrupt Input 0, or the 6th pin of the PORTF Digital I/O Port.
The number of I/O ports available depends on the device variant. For the exact details you must refer to the device datasheet.
Most of the PIC24F family devices support a feature called Peripheral Pin Select or PPS. Using this feature, the users have the possibility to remap the input and/or output of some digital peripherals to different I/O pins.
I/O Port control registers:
On a PIC24F family device, every I/O Port has four registers directly associated with the operation of the port:
- TRISx: Data Direction Control register;
- PORTx: I/O Port register;
- LATx: Data Latch register;
- ODCx: Open-Drain Control register;
TRISx Data Direction Control register:
The TRISx register controls the direction of each pin in the associated port. If the TRIS bit for an I/O pin is ‘1’, then the pin is an input. If the TRIS bit for an I/O pin is ‘0’, then the pin is an output. This may be a little bit confusing because on other architectures, if the direction control bit is set, than the pin is an output and if the direction control bit is cleared, than the pin is an input, but for Microchip microcontrollers, you may think that ‘1’ is looking like an I (Input) and ‘0’ is looking like an O (Output)
The default value after reset for the TRISx register is 0xFFFF (all pins configured as inputs).
PORTx I/O Port register:
Data on the I/O pins is accessed via a PORTx register. A read of the PORTx register return the value of the I/O pin, while a write to the PORTx register writes the value to the port data latch. If the port is configured as an output (and the multiplexed peripherals are disabled), the write to the data latch is reflected on the PORTx pins.
Many instructions, such as BSET and BCLR, are read-modify-write operations (actually a write on a port implies that the port pins are read, the value is modified and than written back to the port latch register). If some I/O pins in the same port are configured as input, when a read-modify-write operation will be performed on this port register, the value of the input bits will also be written in the port data latch register. After some later time, if the I/O ports will be changed from input to output without updating the associated LATx registers, unexpected value may be output on the pin.
In addition, if read-modify-write instructions are used on the PORTx registers while I/O pins are configured as outputs, unintended I/O behavior may occur at high CPU speeds and high capacitive loading on the I/O pins.
LATx Data Latch register:
The LATx register associated with an I/O pin eliminates the problems that could occur with read-modify-write instructions. A read of the LATx register returns the values held in the port output latches instead of the values on the I/O pins. A read-modify-write operation on the LATx register, associated with an I/O port, avoids the possibility of writing the input pin values into the port latches. A write to the LATx register has the same effect as a write to the PORTx register.
The differences between the PORTx and LATx registers can be summarized as follows:
- A write to the PORTx register writes the data value to the port latch.
- A write to the LATx register writes the data value to the port latch.
- A read of the PORTx register reads the data value on the I/O pin.
- A read of the LATx register reads the data value held in the port latch.
For a better understanding of the differences between the usage of PORTx or LATx, please check the experiment where we show what can happen when the PORTx register is used to change the state of a pin.
ODCx Open-Drain Control register:
The ODCx register controls if a digital output pin is open-drain output or normal output. If the ODC bit for an I/O pin is ‘1’, then the pin is an open drain output. If the ODC bit for an I/O pin is ‘0’, then the pin is a normal output (ODC bit is valid only for an output pin).
On a PIC24F device, the open-drain feature allows a load to be connected to a voltage between a minimum Vss and a maximum Vdd by using external pull-up resistors.
The default value after reset for the ODCx register is 0x0000 (all pins configured as an open-drain output).