Skip to content

GPIO - TRIS, PORT and LAT

This page covers how to use TRIS, PORT, and LAT together in real code and UNEXPO labs. It builds on the ports guide and First LED — they come before this page in the sidebar and study path.

GPIO (General Purpose Input/Output) means pins your program configures as digital inputs or outputs. On the PIC18F4550 you do not wire each pin separately to the CPU — you control ports: groups of 8 pins (A, B, C, D, E) through three SFRs per port.

Each pin has a fixed hardware name:

PinPortBit in TRISx / LATx / PORTx
RB0Bbit 0
RB3Bbit 3
RD7Dbit 7

Course rule: bit 0 = pin number 0. BCF TRISB, 0 affects only RB0; TRISB bits 1–7 do not change (Architecture — SFR).

RegisterWrite?Purpose
TRISxYesPin direction: 1 = input, 0 = output
LATxYesOutput value in the internal latch
PORTxReadActual pin level (inputs, switches)

Do not swap roles: TRIS first, then LAT for outputs or PORT to read inputs.

Start / init_gpio
↓ TRISx — define inputs and outputs
↓ LATx — initial output state (LED off, etc.)
main loop
↓ PORTx — read switches / buttons
↓ LATx — update LEDs / actuators
↓ GOTO loop

In sandwich style, init_gpio is usually a subroutine above; programa: calls CALL init_gpio and enters the loop.

Config bits (PBADEN = OFF, LVP = OFF…) prepare hardware at power-on. GPIO registers (TRISB, LATB…) are configured while your code runs. If the LED does not respond, check both layers: crystal/FOSC and BCF TRISB, 0.

LED circuit on RB0 with current-limiting resistor
Digital output: TRISB,0 = 0 (output) and LATB,0 = 1 turn on the LED on RB0. — LED lab — UNEXPO

Registers per port — TRIS, PORT, and LAT

Section titled “Registers per port — TRIS, PORT, and LAT”
PortPinsTRISPORTLATCourse notes
ARA0–RA5TRISAPORTALATARA4 not analog; several pins can be ANx
BRB0–RB7TRISBPORTBLATBRB0 = INT0; RB4–RB7 = change interrupt
CRC0–RC7TRISCPORTCLATCRC6/RC7 = UART (TX/RX)
DRD0–RD7TRISDPORTDLATDLCD in labs
ERE0–RE2TRISEPORTELATEAnalog inputs RE0–RE2

All three registers share bit numbering: bit 3 of TRISB, PORTB, and LATB is always pin RB3.

Before reading or writing, declare each pin as input or output.

One pin at a time (best while learning):

BCF TRISB, 0 ; RB0 → output (bit = 0)
BSF TRISB, 3 ; RB3 → input (bit = 1)

Whole port at once (Practice 1 — PORTB and PORTD as inputs):

MOVLW B'11111111' ; all bits = 1 → all inputs
MOVWF TRISB
MOVWF TRISD

In TRISx, 1 = input and 0 = output. If TRISB = 0xFF, all of PORTB is input — classic partial exam question.

More exercises in Set direction with TRIS.

To drive an LED, relay, or digital line, write LATx, not PORTx:

CLRF LATB ; clear all PORTB outputs
BCF TRISB, 0 ; RB0 output
BSF LATB, 0 ; RB0 high → LED ON
BCF LATB, 0 ; RB0 low → LED OFF

BSF/BCF on LATB touch one bit only — useful when inputs and outputs share a port (Bits and hex — masks).

Practical guide: Write outputs with LAT and First LED tutorial.

For switches, buttons, or digital sensors, read PORTx:

BSF TRISB, 3 ; RB3 input
BTFSS PORTB, 3 ; skip if RB3 = 1 (released, with pull-up)
GOTO button_pressed ; jump → destination button_pressed:
; RB3 = 1 — button not pressed ...
GOTO done_read
button_pressed:
; RB3 = 0 — button pressed ...
done_read:

BTFSS PORTB, n / BTFSC PORTB, n are the most common course pattern. You can also MOVF PORTB, W and mask the bit (Bits and hex).

Practical guide: Read inputs with PORT.

ActionCorrect registerTypical mistake
Turn on LED on RB0BSF LATB, 0BSF PORTB, 0
Read button on RB3BTFSS PORTB, 3BTFSS LATB, 3
Turn off all of PORTCCLRF LATCCLRF PORTC

On pure outputs, writing PORTx sometimes “works” because it shares hardware with the latch, but in the course and datasheet the correct practice is LATx to write and PORTx to read.

You want RB0–RB3 as outputs and RB4–RB7 as inputs:

MOVLW B'11110000' ; bits 7..4 = 1 (input), 3..0 = 0 (output)
MOVWF TRISB

Equivalent pin by pin:

BCF TRISB, 0
BCF TRISB, 1
BCF TRISB, 2
BCF TRISB, 3
BSF TRISB, 4
BSF TRISB, 5
BSF TRISB, 6
BSF TRISB, 7

For TRIS, design the mask inverted vs what you want as output: output = 0, input = 1.

Several PORTA/PORTB pins start as analog inputs if PBADEN = ON in config bits. For course digital GPIO use PBADEN = OFF in the CONFIG block (Config bits — PBADEN).

If you mix ADC and digital in one lab, set ADCON1 to declare which pins are analog and which digital — otherwise PORTx may read nonsense even when TRISx is correct.

Minimal fragment linked to Assembly — LED example:

LIST P=18F4550
#include <P18F4550.INC>
CONFIG FOSC = HS, WDT = OFF, LVP = OFF, PBADEN = OFF
ORG 0x0000
GOTO programa ; jump to main
init_gpio:
CLRF LATB
BCF TRISB, 0 ; RB0 output
RETURN
programa:
CALL init_gpio
loop:
BSF LATB, 0 ; LED ON
GOTO loop ; jump → destination loop: (above)
END

Flow: config bits (hardware at power-on) → TRIS (direction) → LAT (output state) → simulate in Proteus with the .HEX from MPLAB.

MistakeSymptomFix
Write PORTx instead of LATxErratic output or odd readsUse BSF/BCF/CLRF on LATx
Skip TRISx setupPin does not behave as expectedAlways TRIS before LAT/PORT
PBADEN = ON without ADCON1Digital GPIO “dead” on RA/RBPBADEN = OFF or configure ADCON1
LED without resistorOverloaded pin220 Ω or 330 Ω in series
Mix bit and pin“Set bit 3 but watch RB0”Bit n = pin Rn on the same port

Practica · Laboratory

UNEXPO Practice 1

PORTB and PORTD as inputs (operand switches). PORTC and PORTE as outputs (result LEDs). RA0 as a button to change operation. Implement add, subtract, multiply, OR, AND, XOR, complement, rotate, and software division. Before the lab, review the ALU guide if you use the PIC ALU.

When a pin is an input with a push button, you need pull-up and debounce. That is Buttons, pull-up, and debounce.

What does TRISB = 0xFF mean?

All of PORTB configured as input (every TRIS bit is 1).

Why write the LED on LATB and read the button on PORTB?

LATB controls the desired output of the latch; PORTB reflects the actual level on the pin — required for inputs with pull-up or external wiring.

What happens if you forget BCF TRISB, 0 before BSF LATB, 0?

RB0 may still be an input; the latch changes but the pin does not drive the LED correctly.

Ejercicio · Parcial

Trace the flow

In Proteus, change BSF LATB, 0 to BSF PORTB, 0 with RB0 as output. Does the LED behave the same? Note why the course prefers LATB.

Interactive exam

GPIO and ports

Based on: Clase Tema 2 y 3 (1).pdf

0 of 0 answered

TRISB = 0xFF means port B is...
What is the main difference between PORTB and LATB?
To turn on an LED on RB0 you should write to...
To read a button on RB3 you should use...
BCF TRISB, 0 means RB0 is...
CLRF LATB before turning on LEDs is used to...
PBADEN = ON without configuring ADCON1 can cause...
MOVLW B'11110000' + MOVWF TRISB configures RB4-RB7 as...
Bit 3 of LATB corresponds to pin...
Before BSF LATB, 0 you must make sure...