El microcontrolador té cinc ports d'entrades i sortides binàries. No tots els ports estan complets:
| Port | E/S | Rang | Observacions |
| PORTA | 8 | RA0 - RA7 | |
| PORTB | 8 | RB0 - RB7 | |
| PORTC | 8 | RC0 - RC7 | |
| PORTD | 8 | RD0 - RD7 | |
| PORTE | 4 | RE0 - RE3 | RE3 és només d'entrada |
Els ports comparteixen potes del microcontrolador. Això vol dir que no tindrem disponibles els bits dels ports que corresponguin a potes de les que estem emprant una altra funció.
Per a cada port disposem de tres registres. Els registres TRIS (TRISA, TRISB, TRISC, TRISD o TRISE) ens permeten configurar, bit a bit, si volem entrada (bit activat) o sortida (bit desactivat). Els registres PORT (PORTA, PORTB, PORTC, PORTD o PORTE) ens permeten llegir l'estat de l'entrada o escriure el valor de la sortida. Els registres LAT (LATA, LATB, LATC, LATD o LATE) ens permeten llegir o escriure el valor de la sortida. Els registres LAT i PORT es comporten igual a l'hora d'escriure (tots dos actuen sobre la sortida) però diferent a l'hora de llegir (LAT ens dóna el valor de la sortida i PORT el de l'entrada).
Alguns bits dels ports A, B i E fan servir les mateixes potes que les entrades analògiques. Per fer servir les entrades binàries cal que les entrades analògiques estiguin desactivades. El registre ANSEL controla les entrades analògiques de la 0 a la 7 i el registre ANSELH les entrades de la 8 a la 12. Per exemple si activem el bit ANS0 a ANSEL l'entrada analògica AN0 estarà activada i, per tant, l'entrada digital RA0 (que comparteix la mateixa pota) no funcionarà correctament (sempre llegirem 0).
Les entrades analògiques 8 a 12 comparteixen pota amb entrades i sortides binàries del port B. Si no volem fer servir aquestes entrades analògiques hi ha una forma alternativa de configurar-ho. En lloc de posar a 0 el registre ANSELH podem desactivar el bit de configuració PBADEN. Com en la següent línia:
... #pragma config MCLRE = OFF, LPT1OSC = OFF, PBADEN = OFF, CCP2MX = PORTC // CONFIG3H ...
Quan un bit del port B està configurat com a entrada, podem decidir dues maneres de funcionar, amb o sense resistències de pull-up. Sense resistències de pull-up (funcionament per defecte) requereix més complicació de hardware. Si, en canvi, activem les resistències de pull-up podem activar una entrada connectant-la directament al negatiu o, millor, fent-ho a través d'una resistència d'entre 33 Ω i 1 kΩ. Per activar la resistència de pull-up cal activar el bit corresponent al registre WPUB. Per poder controlar individualment les resistències de pull-up cal que el bit 7 del registre INTCON2 (bit RBPU) estigui desactivat; en cas contrari les resistències estaran totes desactivades.
Per exemple, el següent tros de programa configura RB0 com a entrada amb la resistència de pull-up connectada i tot el port D com a sortida:
#include "p18f45k20.h" // Carrega el fitxer d'adreces i paràmetres del PIC 18F45K20 ... TRISD = 0b00000000; // El port D és de sortida ANSELH = 0b00000000; // Les entrades AN8-12 són digitals (AN12 coincideix amb RB0) INTCON2bits.RBPU = 0; // Habilita el control de resistències de pull-up al port B WPUBbits.WPUB0 = 1; // Activa la resistència de pull-up a RB0 TRISBbits.TRISB0 = 1; // RB0 és entrada ...

Aquesta obra d'Oriol Boix està llicenciada sota una llicència no importada Reconeixement-NoComercial-SenseObraDerivada 3.0.