# On PIC18 series, when should I use LAT register and when PORT?

I'm programming a PIC18F4680 using mikroElektronika's mikroC PRO compiler and I've set the LCD library to use following ports to communicate with LCD:

// LCD module connections
sbit LCD_RS at RB4_bit;
sbit LCD_EN at RB5_bit;
sbit LCD_D4 at RB0_bit;
sbit LCD_D5 at RB1_bit;
sbit LCD_D6 at RB2_bit;
sbit LCD_D7 at RB3_bit;

sbit LCD_RS_Direction at TRISB4_bit;
sbit LCD_EN_Direction at TRISB5_bit;
sbit LCD_D4_Direction at TRISB0_bit;
sbit LCD_D5_Direction at TRISB1_bit;
sbit LCD_D6_Direction at TRISB2_bit;
sbit LCD_D7_Direction at TRISB3_bit;
// End LCD module connections


and the LCD is sometimes displaying garbage. I was told to LATB instead of PORTB registers and after reading the I/O Ports section of the datasheet, it's still not clear to me when I should use PORT and when LAT registers.

• – PetPaulsen Mar 26 '12 at 17:48

Use PORT to read from a pin, and LAT to write to a pin (and TRIS to change the direction).

Some PICs do not have a LAT register, in those case you are forced to use the PORT register to write to a pin, which exposes you to the dreaded Read-Modify-Write (it's not a bug, it's a feature!). Check my explanation in Interfacing a keypad with a microcontroller

LAT is used for writing an output, PORT is for reading an input. TRIS is used to configure the direction; an output (=0) or an input (=1). I remember the tris settings on PIC platforms easily because Output is 0 (O) and Input is 1 (I).

The simplest rule, applicable 99% of the tine on devices which have LATx addresses, is to use LATx (or LATxn) whenever you are writing a port, or reading a value which will be used in computing a value to be written back to a port. Use PORTx (or Rxn) only when you want to determine what outside circuitry is or is not doing to state of the pins.

As a further rule, I would suggest avoiding reading LATx outside its role in the iorwf, andwf, or xorwf instructions (or the |=, &=, and ^= operators in C). If, for example, you want to set the bottom four bits of an IO port match the contents of a register which is known to be blank outside those four bits, the pattern

  LATB &= ~0x0F;  // Clear bottom four bits
LATB |= new_data; // Set appropriate bits


is often safer than the pattern:

  LATB = (LATB & 0xF0) | new_data;


It will cause pins whose old and new value were both "1" to transition momentarily to "0", but it will work correctly even if an interrupt service routine would affect the contents of LATB. If one needs the semantics of the latter statement and interrupts could modify LATB, one must either disable interrupts during the read-modify-write sequence or use some really nasty code to enure that the update happens correctly even if an interrupt strikes during it.

BTW, an alternative formulation with semantics between those of the former and the latter is:

  LATB |= new_data;
LATB &= (0xF0 | new_data);


This version will turn on any "new" bits a few cycles before it turns off any bits which should no longer be high, but it is interrupt-safe provided the interrupt only writes to the upper four bits.