i am new to PIC programming. I am using MPLAB X + XC8 compiler. I have on a breadboard an PIC18F4550 connected to a HD44780 compatible LCD. Digging online i found out a routine to interface the PIC with the LCD controller, works ok on 8MHz internal osc.

LCD is connected to the PIC like this: RB0 = D4 RB1 = D5 RB2 = D6 RB3 = D7 RD5 = RS RD7 = E

In my code, all PORTB is used for Data lanes and from PORTD only RD5 and RD7 are defined for RS and E.

My question: How can i move RS and E pins to PORTB also , so the LCD uses a SINGLE PORT, not 2 ports. . Because if i define for example RS as RB4 and E as RB5 , the code that toggles the DATA lines is like this (PORTB = data_to_send) , so it toggles all PORTB pins , not just RB0..RB3 . How can i address/toggle a pin range (RB0..RB3) of a PORT and not the whole port?


2 Answers 2


There is two methods you can use:

  1. Address individual pins. In XC8 you have such variables as LATBbits.LATB3 which you can set to 1 or 0 to turn an individual pin on or off.
  2. Use bitwise operators and masks. You can "or" and "and" bits together to turn chunks of a port on or off, such as LATB &= 0xF0 will turn off the lower 4 bits. LATB |= 0x03 will then turn the lowest two bits on without changing any other bits.

Like Manjenko said you can use a mask, and this is probably the best option especially in the case of the PIC18 devices since they have a LAT register that will avoid any read-modify-write issue.

If you just want to update the 4 least significant bits with the value of the data variable you can do something like this:

LATB = LATB & 0xF0 | (data & 0x0F);

This will keep the 4 most significant bits and update just the 4 least significant bits.

  • \$\begingroup\$ thanks , it worked like this. but i had no success with E (RB5) , i tried moving it to RB6 or 7 still crappy characters. So i moved them all on PORTD, so i have D4-D7 on RD0-RD3 and i left RS on RD5 and E on RD7, working perfect. \$\endgroup\$ Commented Nov 15, 2014 at 20:12
  • \$\begingroup\$ Are you using the LAT registers to set individual bits like Manjeko suggested? You should use them instead of PORT registers, i.e. LATBbits.LATB5 instead of PORTBbits.RB5 for instance. \$\endgroup\$ Commented Nov 15, 2014 at 20:30
  • \$\begingroup\$ yes, of course, i always use LAT , but the issue with PORTB seems to be related to this PIC structure, i don't have the knowledge to understand what was wrong. Because for PORTD works and for PORTB no... i only set them with TRIS = 0 for output at startup, maybe for PORTB latest pins i must set other property also, cause i think something was disturbing communication of RB5 there... \$\endgroup\$ Commented Nov 15, 2014 at 21:07
  • \$\begingroup\$ Do you have the programmer/debugger connected when you test? Since it uses the same pins it could be the issue. You cannot program it in debug mode if you use these pins. \$\endgroup\$ Commented Nov 15, 2014 at 21:12
  • \$\begingroup\$ yes, i have it connected by ICSP , but it's not the issue, ICSP uses only RB6&7 (so not RB5), but i tried it also with external power and same issue. \$\endgroup\$ Commented Nov 15, 2014 at 21:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.