Interfacing LCD with PIC Microcontroller – MPLAB XC8

16x2 Character LCD

Interfacing LCD with PIC Microcontroller – MPLAB XC8

In this tutorial we will see How to Interface a 16×2 character LCD module with PIC 16F877A Microcontroller using MPLAB X IDE and MPLAB XC8 C Compiler. 16×2 Character LCD is a very basic and low cost LCD module which is commonly used in electronic products and projects. 16×2 means it contains 2 rows that can display 16 characters. Its other variants such as 16×1 and 16×4 are also available in the market. In these displays, each character is displayed using 5×8 or 5×10 dot matrix.

For controlling LCD using MPLAB XC8 compiler we need to know the hardware of LCD. These LCDs commonly uses HD44780 compliant controllers. So we need to learn HD44780 Dot Matrix LCD Controller’s Datasheet. Don’t worry we already developed an LCD library including commonly used functions, so you can use it without any hardware knowledge of LCD.

16x2 LCD Pin Diagram

16×2 LCD Pin Diagram

First two pins GND and VCC (VSS and VDD) are for providing power to LCD display. 3ed pin VEE is used to control the contrast of the LCD display. A 10KΩ preset whose fixed ends connected to VDD, VSS and variable end connected to VEE can be used to control contrast of the LCD. A microcontroller or microprocessor need to send 2 types of information for operating this LCD Module, Data Information and Command Information. Data Information is the ASCII value of the characters to be displayed in the LCD screen and Command Information determines other operations such as position to be displayed, clear screen, shift etc. Data and Command Information are send to LCD through same data lines (DB0 – DB7) which are multiplexed using RS (Register Select) pin of LCD. When RS is HIGH LCD treats DB0 – DB7 data pins information as Data to be displayed and when it is LOW LCD treats it as Command Information. Enable (E) input of the LCD is used to give Data Strobe. HIGH (5V) Voltage Level in the Enable (E) pin tells the LCD that DB0 – DB7 contains valid information. The input signal R/W (Read or Write) determines whether data is written to or read from the LCD. In normal cases we need only writing hence it is tied to GROUND in circuit shown below.

The interface between this LCD and Microcontroller can be 8 bit or 4 bit and the difference between them is in how the data or commands are send to LCD. In the 8 bit mode, 8 bit data and commands are send through the data lines DB0 – DB7 and data strobe is given through E input of the LCD. But 4 bit mode uses only 4 data lines. In this 8 bit data and commands are splitted into 2 parts (4 bits each) and are sent sequentially through data lines DB4 – DB7 with its own data strobe through E input. The idea of 4 bit communication is introduced to save pins of a microcontroller. You may think that 4 bit mode will be slower than 8 bit. But the speed difference is only minimal. As LCDs are slow speed devices, the tiny speed difference between these modes is not significant. Just remember that microcontroller is operating at high speed in the range of MHz and we are viewing LCD with our eyes. Due to Persistence of Vision of our eyes we will not even feel the speed difference.


Hope that you got rough idea about how this LCD Module works. Actually you need to read the datasheet of HD44780 LCD driver used in this LCD Module to write a MPLAB XC8 program for PIC. But we solved this problem by creating a header file lcd.h which includes all the commonly used functions using 4 bit mode. Just include it and enjoy.

Circuit Diagram

Interfacing LCD with PIC Microcontroller - Circuit Diagram

Interfacing LCD with PIC Microcontroller – Circuit Diagram

LCD Library

  • Lcd_Init() : This function will initialize the LCD Module connected to the following defined pins.
#define RS RD2
#define EN RD3
#define D4 RD4
#define D5 RD5
#define D6 RD6
#define D7 RD7

These connections must be defined for the proper working of LCD.

  • Lcd_Clear() : To clear the display.
  • Lcd_Set_Cursor(int row, int column) : This function is used to set row and column of the cursor on the LCD screen. By using this function we can change the position of the character or string displayed by following functions.
  • Lcd_Write_Char(char) : To write a character to LCD on the current position.
  • Lcd_Write_String(char *string) : To write string to LCD on the current position.
  • Lcd_Shift_Right() : To shift contents on the LCD screen Right once without changing the data in the Display RAM.
  • Lcd_Shift_Left() : To shift contents on the LCD screen Left once without changing the data in the Display RAM.

Note : The Pins to which LCD is connecting should be configured as Output Pins by writing to TRIS Register.

MPLAB XC8 Code

#define _XTAL_FREQ 8000000

#define RS RD2
#define EN RD3
#define D4 RD4
#define D5 RD5
#define D6 RD6
#define D7 RD7

#include <xc.h>
#include "lcd.h";

// BEGIN CONFIG
#pragma config FOSC = HS // Oscillator Selection bits (HS oscillator)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT enabled)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = ON // Brown-out Reset Enable bit (BOR enabled)
#pragma config LVP = OFF // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3 is digital I/O, HV on MCLR must be used for programming)
#pragma config CPD = OFF // Data EEPROM Memory Code Protection bit (Data EEPROM code protection off)
#pragma config WRT = OFF // Flash Program Memory Write Enable bits (Write protection off; all program memory may be written to by EECON control)
#pragma config CP = OFF // Flash Program Memory Code Protection bit (Code protection off)
//END CONFIG

int main()
{
    unsigned int a;
    TRISD = 0x00;
    Lcd_Init();
    while(1)
    {
        Lcd_Clear();
        Lcd_Set_Cursor(1,1);
        Lcd_Write_String("LCD Library for");
        Lcd_Set_Cursor(2,1);
        Lcd_Write_String("MPLAB XC8");
        __delay_ms(2000);
        Lcd_Clear();
        Lcd_Set_Cursor(1,1);
        Lcd_Write_String("Developed By");
        Lcd_Set_Cursor(2,1);
        Lcd_Write_String("electroSome");
        __delay_ms(2000);
        Lcd_Clear();
        Lcd_Set_Cursor(1,1);
        Lcd_Write_String("www.electroSome.com");

        for(a=0;a<15;a++)
        {
            __delay_ms(300);
            Lcd_Shift_Left();
        }

        for(a=0;a<15;a++)
        {
            __delay_ms(300);
            Lcd_Shift_Right();
        }

        Lcd_Clear();
        Lcd_Set_Cursor(2,1);
        Lcd_Write_Char('e');
        Lcd_Write_Char('S');
        __delay_ms(2000);
    }
    return 0;
}

sprintf() to Format Outputs

sprintf() can be used to write formatted string to a variable. It can be used with this LCD library to format displayed texts. This enables us to display integers and floating point numbers on the LCD very easily.



Syntax :

sprintf(char * str, const char * format, ...);

Where,

  • str is the pointer to the buffer to which the resulting string is to be stored.
  • format is a constant string or null terminated array of characters. Formatting is done in accordance with this argument.
  • … (additional arguments) indicate a list of additional arguments that may required for this function depending up on the format string. Each additional argument contains a value that to be replace a format specifier in the format string.

Format Specifiers

The generic form of format is %nt. where n is optional which may be 1 – 9 to specify number of characters to be outputted or 01 – 09 to indicate leading zeros or 1.1 to 9.9 for floating point and %w formats. t is the type which may be one of the following.

t Type
c Character
s Sting or Character
u Unsigned Integer
d Signed Integer
Lu Long Unsigned Integer
Ld Long Signed Integer
x Hex Integer – lower case
X Hex Integer – upper case
Lx Hex Long Integer – lower case
LX Hex Long Integer – upper case
f Float with truncated decimal
g Float with rounded decimal
e Float in exponential format
w Unsigned Integer with decimal place inserted. Specify two numbers for n. The first is a total field width. The second is the desired number of decimal places.

 Example :

....
float f = 1.414;
int a = 56;
char s[20];
....
....
sprintf(s, "Float = %f", f);
Lcd_Set_Cursor(1,1);
Lcd_Write_String(s);
sprintf(s, "Integer = %d", a);
Lcd_Set_Cursor(2,1);
Lcd_Write_String(s);

This code will make following output on the LCD.

Display Integer and Floating Point Number on LCD

Display Integer and Floating Point Number on LCD

Please go to this page for more details about formatting.



Download Here

If you have and doubts, just comment below. You can download the entire project files here…

Want to See the Output ?

Buy Here

  • Sale
    Out of stock
    16x2 Green Character LCD Module16x2 Blue Character LCD Module

    16×2 Character LCD Module

    0 out of 5

    16×2 Character LCD is a very basic and low cost LCD module which is commonly used in electronic devices and projects. 16×2 means it contains 2 rows that can display 16 characters. In these displays, each character is displayed using 5×8 or 5×10 dot matrix.  This module can display ASCII characters, special characters and even custom characters. It uses HD44780 compatible controller for its operation. Two variants of this LCD modules are available, one having BLACK characters on GREEN and other having WHITE characters on BLUE.

    150.00165.00 149.00159.00
  • -31%
    PIC 16F877APIC 16F877A

    PIC 16F877A Microcontroller

    0 out of 5

    This powerful (200 nanosecond instruction execution) yet easy-to-program (only 35 single word instructions) CMOS FLASH-based 8-bit microcontroller packs Microchip's powerful PIC architecture into an 40- or 44-pin package and is upwards compatible with the PIC16C5X, PIC12CXXX and PIC16C7X devices. The PIC16F877A features 256 bytes of EEPROM data memory, self programming, an ICD, 2 Comparators, 8 channels of 10-bit Analog-to-Digital (A/D) converter, 2 capture/compare/PWM functions, the synchronous serial port can be configured as either 3-wire Serial Peripheral Interface (SPI™) or the 2-wire Inter-Integrated Circuit (I²C™) bus and a Universal Asynchronous Receiver Transmitter (USART). All of these features make it ideal for more advanced level A/D applications in automotive, industrial, appliances and consumer applications.

    200.00 139.00
  • -21%
    Out of stock
    USB PIC ProgrammerPICKit2 Clone

    USB PIC Programmer PICkit 2

    0 out of 5

    The PICkit 2 programmer is a development tool with a easy to use interface for programming and debugging Microchip’s flash families of micro-controllers. The windows programming interface supports all commonly available PIC microcontrollers. With Microchip’s powerful MPLAB Integrated Development Environment (IDE) the PICkit 2 enables in circuit debugging on most PIC microcontrollers.

    1,170.00 929.00

Share this post

  • curiousgeorge

    Hi, I am using PIC16F883 on PICDEM 2 demo board. I have used your code but changed the pin outs to suit the pic16f and demo board. I am curious if using 20mhz external oscillator is timings will need to be adjusted in the code provided

  • gabriel

    hey, i’ve donwloaded your code, but it is not compile! build error. can you help me?

  • Are you sure that you are using MPLAB XC8 compiler.. ??

    Make sure that your compiler is working fine…
    Above projects files are tested and it is 100% working.

  • Roy

    I Just completed this project and it works fine. I would like to use a 20×4 display in this project. Do you have a routine that adapts your code to a 20×4 LCD?

  • Thanks for the feedback….
    I am not sure about 20×4 LCD, just try using above library… it might work if the LCD controller is compatible..

  • Roy

    Thanks Ligo for your prompt reply. The 20X4 is actually two 40×2 that must be manipulated so that the First, second, third, and fourth line wrap and write correctly. It will require additional coding that is beyond my capabilities at this time. Have a look at the specs on a J204A LCD.

  • It is a clone of HD44780, so the above library will work… You may need to make little modifications in the library, to display in correct positions..

  • Roy

    Yes Ligo, that is the problem, the positions specified within the library. I am afraid that at this point in time my skills in writing code are not up to the task. Could you provide some suggestions or ideas. Thank You.

  • Check and edit the function for setting cursor position in the header file..

  • Eduardo

    Hello Dear Ligo,

    This library is flexible . this is great feature . I have been looking for it long time.

    First of all , this library is working perfectly on 16×2

    But unfortunately this library isn’t working on 20×4

    Please help me.

  • If your LCD controller is compatible with HD44780U, that LCD will work… but you may face some issue with display locations..

  • Marshall

    I can’t get the file lcd.h I can’t extract it. Can you help me?

  • Marshall

    Or should I say where do I get the file lcd.h ?

  • Download above zip file and.. unzip it..

  • Which operating system you are using ?
    In windows, just right click and extract it..

  • Sandro Sarchimelidze

    Thank you for your code. But I get compile error because of delays in lcd.h file. I included but they are only for C18 compiler. What should I do? I’m new in programming so how you can use __delay_ms() without include file? Thanks in advance

  • Hello, the above library is for XC8 compiler.. not for XC18.. they are different..

  • shez

    hi, thank you for this, it is very usefull and it works great, can you tell me how I can display a integer. thank you

  • Henrique

    Thank you so much for sharing this.

    I am a beginner.

    How can i print variables with this library?

    And in my Mplab works but with 359 error:

    “ADCwithLCDmain.c:267: warning: (359) illegal conversion between pointer types

    pointer to const unsigned char -> pointer to unsigned char”.

    Thanks one mor time!

  • It is a warning … not error..
    for pring integer and floating point variables you can use sprintf() function.

  • krishna

    i need program to controlling a toy car motor , by using mircocontraller ….so what gained of softward i can you’s

  • Sorry, I don’t understand your question.
    Please use our forums, https://electrosome.com/forums for asking doubts not reated to above article.

  • Edson Archela

    Hi, I test the program but it appears only blank squares on the bottom line. The changes I made are minor: the crystal, to 20MHz; and the port to B. What could be wrong?

  • m123

    Excellent work! Routines work great.

    My knowledge of C is lacking and I don’t understand the following results.

    I guess I dont understand what you are testing in the variable ‘a’

    Line taken from Lcd_Init………

    Lcd_Port(0x0C)

    void Lcd_Port(char a)
    {
    if(a & 1) <—- evaluates FALSE in simulator
    D4 = 1;
    else
    D4 = 0;

    if(a & 2) <—— evaluates FALSE in simulator
    D5 = 1;
    else
    D5 = 0;

    if(a & 4) <——- evaluates TRUE in simulator
    D6 = 1;
    else
    D6 = 0;

    if(a & 8) <—— evaluates TRUE in simulator
    D7 = 1;
    else
    D7 = 0;
    }

  • Don’t forget to make that changes in program too.
    Make sure that the connections are correct and the PIC program is running fine..
    Try adjusting the contrast adjusting preset.

  • It is just to send lcd data to corresponding defined pins…
    It just ANDing “a” and “value”….
    Try to understand it .. just after converting both “a” and “value” to binary.

  • m123

    Thank you for your reply. The key word for me in your response is BOTH.
    Now I see how this routine is just testing to see which bits are set in ‘a’ and sets the corresponding ones for the LCD!

  • Edson Archela

    It was the pic, some burned port. Changed for a new one and work perfectly. Thanks

  • khalil louhichi

    HI ,all Can someone help me for programing this circuit with MPLAB XC8 ,on use the pic18f2550 , thanks

  • Piyush Ramani

    lcd.h code where?

  • Piyush Ramani

    Please provide lcd.h header file code

  • Khalil Louhichi

    HI all ,Can someone help me for programing this circuit with MPLAB XC8 ,on use the pic18f2550 , thanks

  • Rahul Carnalious Snal

    Thanks !!!! It’s a great help !!! 🙂 (Y)

  • Rahul Carnalious Snal

    replace the following portion of code in lcd.h and save. then build.

    problem will be solved…….

    void Lcd_Write_String(const char *a)
    {
    int i;
    for(i=0;a[i]!=”;i++)
    Lcd_Write_Char(a[i]);
    }

  • Please use our forums (https://electrosome.com/forums) for posting doubts not related to above topic.

  • You can download it above.

  • Piyush Ramani

    Thank you sir…

  • Pawel Cuper

    This entire code stops working as soon as I change the properties to Pic18F4520.
    Why?

  • What properties. ?

  • shez

    hi, please can you tell me how to make this library work with the PIC18f4520, Nothing happens at the moment I have managed to fix the errors.
    Thanks

  • Deprecated warning can be solved by using like PORTDbits.RD3
    and for using 8×2 LCD you might need to modify Set Cursor functions.. by changing address values.

  • Piyush

    any one can explain set cursor portion how to select temp value 0x80 and 0xc0 for 2 nd line.

  • Check the datasheet of the controller HD44780, you can see it.

  • watchaphong

    Dear Ligo George

    After build project i found error “can’t open include file “lcd.h”: No such file or directory”.why my compiler don’t have libraly file “lcd.h”. How can i get it from?

    Thank you

  • Please read the tutorial carefully. You should download the header file “lcd.h”

  • Watchapong HipHip

    OK, i got it. thank you for your tutorial.

  • Mart1n

    Hi, when im trying to use the formatting code for the LCD im getting the error “function declared implicit int” in the lines ” sprintf(a, “Float = %f”, f);” and ” sprintf(a, “Integer = %d”, s);”

    Also, this would work with a 18F45J50?

    Thanks a lot Ligo George

  • Mart1n

    #define _XTAL_FREQ 8000000

    #define RS RD2

    #define EN RD3

    #define D4 RD4

    #define D5 RD5

    #define D6 RD6

    #define D7 RD7

    #include

    #include “lcd.h”

    int main()

    {

    TRISD = 0x00;

    Lcd_Init();

    while(1)

    {

    Lcd_Clear();

    float f = 1.414;

    int s = 56;

    char a[20];

    sprintf(a, “Float = %f”, f);

    Lcd_Set_Cursor(1,1);

    Lcd_Write_String(a);

    sprintf(a, “Integer = %d”, s);

    Lcd_Set_Cursor(2,1);

    Lcd_Write_String(a);

    }}

  • Mart1n

    Would the LCD formatting work with 18F45J50? Thanks a lot Ligo

  • Ammar Yasir

    from where it can be downloaded Ligo ???

  • It should work. Better to change all port registers to LAT register in all output operations.

  • Don’t you see the download link above ?

  • Alex Chiang

    Hey I am using PIC16F887. When I use your code, I change all PORTD to PORTA for the data lines (D7~D4) and PORTB (EN, RW,RS) for the command lines. However it does not work. Can you help me with it?

    Below is a picture of what I get on the LCD screen.

  • Mauricio Ocón

    did you changed the TRIS and clock configurations? I used the same micro (with PORTD) and worked fine. This is my config

    // CONFIG1
    #pragma config FOSC = INTRC_NOCLKOUT
    #pragma config WDTE = OFF
    #pragma config PWRTE = OFF
    #pragma config MCLRE = ON
    #pragma config CP = OFF
    #pragma config CPD = OFF
    #pragma config BOREN = ON
    #pragma config IESO = OFF
    #pragma config FCMEN = OFF
    #pragma config LVP = OFF

    // CONFIG2
    #pragma config BOR4V = BOR40V
    #pragma config WRT = OFF

  • GB Ward

    Was also able to get this working well with a PIC16F684. Thanks for the library Electrosome! This makes things really easy!

    Specs:
    PIC16F684
    Display connected to PORTC
    No external crystal, using internal oscillator at 4Mhz.

    Notes:
    Initially didn’t work for me, I believe I was having some problems because ADCON0 and CMCON0 weren’t setup for my PIC. No changes to LCD.h necessary at all. sprintf(); will not work on this microprocessor because it requires too much space. See my second post for how to use atoi(); instead to convert integers to char.

    IMPORTANT CODE CHANGES FOR MY SETUP:
    #define _XTAL_FREQ 4000000

    #define RS RC5
    #define EN RC4
    #define D4 RC0
    #define D5 RC1
    #define D6 RC2
    #define D7 RC3


    //Replace CONFIG with
    #pragma config FOSC = INTOSCIO
    #pragma config WDTE = OFF
    #pragma config PWRTE = OFF
    #pragma config MCLRE = OFF
    #pragma config CP = OFF
    #pragma config CPD = OFF
    #pragma config BOREN = OFF
    #pragma config IESO = OFF
    #pragma config FCMEN = OFF

    //PORTS SETUP
    TRISC = 0x00; //PORTC outputs
    TRISA = 0; //PORTA unused
    PORTC = 0; //PORTC intially low
    PORTA = 0; //PORTA initally low
    CMCON0=7; //Comparators off, and all pins I/O
    ANSEL=0; //Select no A/D
    ADCON0=0; //ADC off.

    Hopes this helps or inspires somebody.

  • GB Ward

    CONVERTING AN INT WITH ATOI

    If your processor won’t handle sprintf(); or it’s using up too much space, and you just only need to print an int, try the atoi(); function. It’s available in the XC8 Complier library, see page 369.

    Requires:
    #include

    Sample Code:

    int j = 14; //declare int and put 14 in it.

    char buffer[17]; //Allow 16char + one null for 16 character display
    itoa(buffer, j, 10); //convert int j to ASCII, base 10. Load into char buffer[];
    Lcd_Set_Cursor(2,1);
    Lcd_Write_String(buffer);

    This code will write the number value of j, in this case 14, on the display on the second line. Helpful if you are building a simple counter or wanting to print the result of some int manipulation.

  • Luca

    I can not find the lcd.h file. it has been removed?

  • PORTA is the analog port. Set all pins to Digital by writing to appropriate registers. Also disable other functions like comparator.

  • Dear GB Ward,
    Thanks for the feedback.

  • No, you can download it above. It is the zipped project folder.

  • Efrain Torres

    Hi,
    I would like to use a less costly micro such as PIC16F57 with a 16X2 LCD. Is this code work for the mentioned micro or what considerations I should take?

  • Yes, you can use the above header file for that.

  • Mahesh Fernando

    Hi, Your code work perfect. I am trying to understand the code. Not clear how following statements work. 1) temp = 0x80 + b – 1; 2) temp = 0xC0 + b – 1; 3) for(i=0;a[i]!=”;i++). Please explain. Thanks.

  • Mike

    How can I create or make a custom character an print it into the LCD??

  • Mike

    How can I create or make a custom character and print it into the LCD?

  • Kevin Ponce

    Hi, I´m trying this code in Mplab, but when i generate the .hex I can´t run it in PIC Simulator it shows me this message: “Invalid program file in Hex Format contains error. Line number 197: Invalid data byte in the record. ” Can You tell me why?

  • You have to read the LCD Controller datasheet (HD44870) for that.

  • Above code is 100% working. I don’t know PIC Simulator. You can try using Proteus.

  • ahmed ammar

    Ligo George ,

    how are you? i am looking for a a circuit diagram which consist of pic18F4520 and the sensor, the target of this circuit that I need when it is below 6 meters the sensor give a signal to the pic to make yellow led is flashing, while when the sensor reach exactly to 6 meters the pic give a signal to switch off yellow led and make green led is on, if the sensor exceed 6 meters the red led is on and giving sound to the buzzer.
    if you do not mind could you help me in that please with the code using Proteus program.
    Regads,
    Ahmed

  • ahmed ammar

    Ligo George ,

    how are you? i am looking for a a circuit diagram which consist of pic18F4520 and the sensor, the target of this circuit that I need when it is below 6 meters the sensor give a signal to the pic to make yellow led is flashing, while when the sensor reach exactly to 6 meters the pic give a signal to switch off yellow led and make green led is on, if the sensor exceed 6 meters the red led is on and giving sound to the buzzer.
    if you do not mind could you help me in that please with the code using Proteus program.
    Regads,
    Ahmed

  • Electo

    Hi,

    thanks for your code.
    I use it on picdem2plus demoboard with a Pic18F452 and XC8 and it works (after pin modifications).
    But I have warnings for each time I call Lcd_Write_String() function, here is the warning:
    “Warning [359] illegal conversion between pointer types
    pointer to const unsigned char -> pointer to unsigned char”
    Now on my program I call 34 times this function, but I use it one more time the programmin delay is long and after powering the board nothing on the LCD.
    Any one can help?

  • Omoniyi Omotoso

    Hi, thanks for this great tutorial, please how can i correctly
    set cursor, shift left and right on a 20×4 LCD display with this same
    library. I have tried it but it is not working as it should. Thanks in advance

  • Sorry, your question is outside the scope of above article. Please use our forums ( https://electrosome.com/forums ) for such questions.

  • Warning is not a problem. If you want to remove it, just add const prefix to each string argument in the function definition.

    It seems like you have used more than 70% of the PIC ram by using strings, it might be the problem. Reduce strings or replace PIC with a higher one.

  • Check your LCD datasheet. You might need to make minor changes in the address in library.

  • prathap gangadhar

    hello sir, how to give password to lock and unlocking in LCD display, please send me the code sir

  • Legit

    Hi Ligo,
    Could you please send me the link to download the MPLab XC8 Compiler to execute the above program? I’m not able to find a reliable link.
    Thanks in advance. 🙂

  • akmal 94

    #include

    how to get this file header pls help

  • akmal 94

    picc.exe –pass1 –errformat=”Error at file %%f line %%l column %%c: (%%n) %%s” –warnformat=”Warning at file %%f line %%l column %%c: (%%n) %%s” –msgformat=”Message at file %%f line %%l column %%c: (%%n) %%s” -D_XTAL_FREQ=1000000 -G –chip=16F877A -O”main.p1″ “../main.c”

    HI-TECH C Compiler for PIC10/12/16 MCUs (Lite Mode) V9.82

    Copyright (C) 2011 Microchip Technology Inc.

    (1273) Omniscient Code Generation not available in Lite mode (warning)

    Warning at file ../main.c line 11 column 26: (111) redefining preprocessor macro “_XTAL_FREQ” ((null): 0)

    Error at file ../main.c line 20 column 15: (141) can’t open include file “xc.h”: No such file or directory

    make: *** [main.p1] Error 1

    Error code 2

  • akmal 94

    need help pls

  • It is there by default for XC8 compiler.

  • Above code is for XC8 compiler .. not for Hi-Tech C… Just change the header file xc.h to htc.h.

  • b0rg

    hi, Im trying to compile your code with MPLAB XC8, but I’m having problems with delay functions. I use the same crystal together with pf184550 but for some reason when i compile it says that the “in-line delay argument too large”, when i lover it from 2000 to 90 it passes that error. Why is that happening. Thanks

  • That is due to delay limit. You need to make another used defined function, something like this :

    void Delay10(unsigned a)
    {
    for(;a>0;a–)
    {
    __delay_ms(10)
    }
    }

  • sampath

    thank you very much GB ward it worked

  • Boris

    Thanks bro you literally saved me days of hacking, tacking and patching to get my own working code.

  • Thanks for the feedback.

  • Ghislain

    Hello, I’m trying since 3 week to display a 2×16 LCD but it is not working. I use the PIC16F1937 MCU. can you please help me? please!!!

  • Ali Alaa

    Thanks alot man, your code is neat, straight forward and flawless; it was very helpful

  • Please give the details of the problem you are facing. What is the current output ? Put photos and code here.

  • Thanks for the feedback.

  • Jaguar paw

    Please please please!! can some one help I cannot get it to work.
    I only get the top row showing blocks as if I am only applying power.
    I am using the pic16f690.

    I have made the following changes and connections

    #define RS RC0
    #define EN RC1
    #define D4 RC2
    #define D5 RC3
    #define D6 RC4
    #define D7 RC5

    also I have TRISC 0x00

    I am using the internal clock and as far as I know I have emended the code accordingly

    lcd.h

    #include
    //LCD Header for 4 bit Data -MPLABX/XC8
    #define _XTAL_FREQ 8000000
    #define RS RC0
    #define EN RC1
    #define D4 RC2
    #define D5 RC3
    #define D6 RC4
    #define D7 RC5
    char temp,z,y;
    int i;
    void Lcd_Port(char a)
    {
    if(a & 1)
    D4 = 1;
    else
    D4 = 0;

    if(a & 2)
    D5 = 1;
    else
    D5 = 0;

    if(a & 4)
    D6 = 1;
    else
    D6 = 0;

    if(a & 8)
    D7 = 1;
    else
    D7 = 0;
    }
    void Lcd_Cmd(char a)
    {
    RS = 0; // D0 to D7 interpreted as Command

    Lcd_Port(a);
    EN = 1; // LCD Enable
    __delay_ms(4);
    EN = 0; // LCD Disable
    }

    Lcd_Clear()
    {
    Lcd_Cmd(0);
    Lcd_Cmd(1);
    }

    void Lcd_Set_Cursor(char a, char b)
    {
    char temp,z,y;
    if(a == 1)
    {
    temp = 0x80 + b – 1;
    z = temp>>4;
    y = temp & 0x0F;
    Lcd_Cmd(z);
    Lcd_Cmd(y);
    }
    else if(a == 2)
    {
    temp = 0xC0 + b – 1;
    z = temp>>4;
    y = temp & 0x0F;
    Lcd_Cmd(z);
    Lcd_Cmd(y);
    }
    }

    void Lcd_Init()
    {
    Lcd_Port(0x00);
    __delay_ms(20);
    Lcd_Cmd(0x03);
    __delay_ms(5);
    Lcd_Cmd(0x03);
    __delay_ms(11);
    Lcd_Cmd(0x03);

    Lcd_Cmd(0x02);
    Lcd_Cmd(0x02);
    Lcd_Cmd(0x08);
    Lcd_Cmd(0x00);
    Lcd_Cmd(0x0C);
    Lcd_Cmd(0x00);
    Lcd_Cmd(0x06);
    }

    void Lcd_Write_Char(char a)
    {
    char temp,y;
    temp = a&0x0F;
    y = a&0xF0;
    RS = 1; // D to D7 interpreted as DATA
    Lcd_Port(y>>4); //Data transfer
    EN = 1;
    __delay_us(40);
    EN = 0;
    Lcd_Port(temp);
    EN = 1;
    __delay_us(40);
    EN = 0;
    }

    void Lcd_Write_String(char *a)
    {
    int i;
    for(i=0;a[i]!=”;i++)
    Lcd_Write_Char(a[i]);
    }

    void Lcd_Shift_Right()
    {
    Lcd_Cmd(0x01);
    Lcd_Cmd(0x0C);
    }

    void Lcd_Shift_Left()
    {
    Lcd_Cmd(0x01);
    Lcd_Cmd(0x08);
    }

    main.c
    #define _XTAL_FREQ 8000000

    #define RS RC0
    #define EN RC1
    #define D4 RC2
    #define D5 RC3
    #define D6 RC4
    #define D7 RC5
    // BEGIN CONFIG

    #pragma config FOSC = INTRCCLK // Oscillator Selection bits (INTOSC oscillator: CLKOUT function on RA4/OSC2/CLKOUT pin, I/O function on RA5/OSC1/CLKIN)
    #pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
    #pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
    #pragma config MCLRE = ON // MCLR Pin Function Select bit (MCLR pin function is MCLR)
    #pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
    #pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
    #pragma config BOREN = ON // Brown-out Reset Selection bits (BOR enabled)
    #pragma config IESO = ON // Internal External Switchover bit (Internal External Switchover mode is enabled)
    #pragma config FCMEN = ON // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is enabled)

    //END CONFIG
    #include

    #include “lcd.h”;

    void main()
    {
    unsigned int a;
    TRISC0 = 0x00;
    TRISC1 = 0x00;
    TRISC2 = 0x00;
    TRISC3 = 0x00;
    TRISC4 = 0x00;
    TRISC5 = 0x00;
    Lcd_Init();
    while(1)
    {
    Lcd_Clear();
    Lcd_Set_Cursor(1,1);
    Lcd_Write_String(“LCD Library fr”);
    __delay_ms(290);
    //Lcd_Set_Cursor(2,1);
    //Lcd_Write_String(“MPLAB XC8”);
    //__delay_ms(100);
    //Lcd_Clear();
    //Lcd_Set_Cursor(1,1);
    //Lcd_Write_String(“WWW.ALSELECTRO.COM”);
    //__delay_ms(100);
    //Lcd_Clear();
    //Lcd_Set_Cursor(1,1);
    //Lcd_Write_String(“Saravana Electronics”);
    }
    /* for(a=0;a<15;a++)
    {
    __delay_ms(10);
    Lcd_Shift_Left();
    }

    for(a=0;a<15;a++)
    {
    __delay_ms(10);
    Lcd_Shift_Right();
    }

    Lcd_Clear();
    Lcd_Set_Cursor(2,1);
    Lcd_Write_Char('S');
    Lcd_Write_Char('E');
    __delay_ms(10);
    }
    */
    }

  • mash

    Hi
    How may I run two hour meter with same speed.?
    I tried but I am getting 1 sec delay in each increments.
    Hour1-0000
    Hour2-0001
    while I want
    Hour1-0000
    Hour2-0000

    Hence I want that both hourmeter should run with incremental rate.

  • Hi,
    Make sure that all connections are correct and also try adjusting the contrast.

  • Jaguar paw

    Yes i believe they are also would i need to check contrast if backlight is not connected?

  • Jaguar paw

    I haave checked the connections and they seem fine. Would i need to worry about contrast if the backlight is not used ? I still have no luck !:(

  • Joan

    Hi, I am a rather late entrant to this world. Your LCD program works great! However have problems when using the sprint method to display the examples you shared viz., the Float and Integer. MPLAB X IDE returns “…..error 1098 conflicting declarations for variable “_sprintf”. Also “Build failed”. Your inputs will be of great help. I can share the code sample if required. Thanks

  • Yes, contrast and backlight are different.

  • did you include the header file ?? and make sure that your sprintf syntax is correct.

  • Joan

    Hi Ligo, Yes the header file is included and the main program is working great. The problem is only with the ‘sprintf’ example – I copied the code exactly as given but the program is returning ‘ build failed’. There are some empty spaces (dots) in your example, what does this mean. Appreciate your help. Thanks

  • Joan

    Hi, As I can see if you are using Internal Clock you also need to set OSCCON in your main program e.g. OSCCON = 0x071; This will set the internal clock to 8Mhz

  • You need to include the header file stdio.h for that.

  • Tim

    First, thanks a lot, this tutorial and the one for interfacing the HC-SR04 are awesome!!

    So I am having issues trying to get the code to compile. I am using the dsPIC33f with XC16 compiler to attempt to build this. I have changed all of the RDs to RBs, as my chip doesn’t have port D available. I am running into the issue within the lcd.h file and it is giving me the error that ” ‘RB4’ undeclared (first use in this function)” for pretty much all of the RB pins. Also, within the main.c I am getting errors for all of the pragma config statements “unknown configuration setting: ‘FOSC'” etc. Any help you might be able to give would be much appreciated. Thanks!

  • Tedro Chalouhy

    In the proteus circuit, the LCD LM016L does not have the last two ports LED+ and LED-
    i have loaded ur code to the pic16F877A and did all the connections the way u did except for those two LED ports in the lcd, and the lcd didn’t show anything when i ran it, any help?

  • This code won’t work in dsPIC. You need to make a lot of changes for that.

  • That is not a problem. For simulating LED is not required. It will work fine in simualtion without those LED connections.

  • It means that you need to reduce the delay. Just split it in to two delays and try.

  • Ivan

    Hi, I need to show 4 messages in differents lines , I have intented with “LM044L” LCD, but until now I have been unable. Thanks

  • Check the datasheet of your LCD controller, you might need to make some changes depending on it.