Page 1 of 2 12 LastLast
Results 1 to 10 of 19

Thread: Error: Hi-Tech C program for LCD interface with PIC 16F877A

  1. #1

    Default Error: Hi-Tech C program for LCD interface with PIC 16F877A

    Hi,
    I have written a code to interface the LCD to PIC16F877A using Hi-Tech C compiler in MP LAB IDE. There are no errors in the program when I Build it. But when I simulate the program using PROTEUS or PIC Simulator I don't get the output.

    Please correct my program and notify the mistake I did. Pl help me..

    DETAILS:
    I use PIC16F877A, MP LAB IDE, PROTEUS, Hi-Tech C Compiler.

    OTHER DETAILS:
    LCD 4 bit Interface,
    RS = PORT E,0
    RW = PORT E,1
    EN = PORT E,2

    DATA = PORT A,(0-3) [4bit-Interface]

    __________________________________________________ ______________________
    CODE:

    #include<htc.h>

    #define RS RE0
    #define RW RE1
    #define EN RE2

    void LCD_delay(void)
    {
    long t;
    for(t=0;t<250;t++);
    }

    void LCD_delay2(void)
    {
    long a;
    for(a=0;a<10000;a++);
    }

    void LCD_command(unsigned char command)
    {
    unsigned char temp;
    RS = 0;

    // To send LSB part of command
    temp = command & 0x0f; //Mask only upper data in byte
    PORTA &= 0x30;
    PORTA |= temp;
    EN = 1;
    for(temp=0;temp<10;temp++);
    EN = 0;
    LCD_delay();

    // To send MSB part of command
    temp =(command & 0xf0)<<4;
    PORTA &= 0x30;
    PORTA |= temp;
    EN = 1;
    for(temp=0;temp<10;temp++);
    EN = 0;
    LCD_delay();
    }

    void LCD_data(unsigned char data)
    {
    unsigned char temp2;
    RS=1;
    temp2 = data & 0x0f;
    PORTA &= 0x30;
    PORTA |= temp2;
    EN = 1;
    for(temp2=0;temp2<10;temp2++);
    EN = 0;
    LCD_delay();

    temp2 =(data & 0xf0)<<4;
    PORTA &= 0x30;
    PORTA |= temp2;
    EN = 1;
    for(temp2=0;temp2<10;temp2++);
    EN = 0;
    LCD_delay();
    }

    void initialise_LCD(void)
    {
    ADCON0 = 0x00;//Disable ADC ports
    ADCON1 = 0x06;//Disable ADC ports

    TRISA = 0x00;
    PORTA = 0x00; //DATA i/p to LCD

    TRISE = 0x00;
    PORTE = 0x00; //CONTROL i/p to LCD

    LCD_command(0x02);//Command return the cursor to home
    LCD_delay2();
    LCD_command(0x07);//increment, disp shift
    LCD_delay2();
    LCD_command(0x0c);//off cursor, display on
    LCD_delay2();
    LCD_command(0x18);//Display shift,shift to left
    LCD_command(0x28); //4bit interface, 2line, 5x8 dots
    LCD_delay2();
    }

    void clear_LCD()
    {
    LCD_command(0x01);
    LCD_delay2();
    }

    void display_LCD(char line_number,char position, const char *message)
    {
    int a;
    if(line_number==1)
    {
    a = 0x80 + position;
    RS = 0;
    LCD_command(a);
    }
    else
    {
    a = 0xC0 + position;
    RS = 0;
    LCD_command(a);
    }
    while(*message!=0)
    {
    RS = 1;
    LCD_data(*message);
    message++;
    }
    }

    void main(void)
    {
    __CONFIG(0x193A);
    initialise_LCD();
    RW=0;
    while(1)
    {
    clear_LCD();
    display_LCD(1,1,"WELCOME");
    display_LCD(2,4,"welcome");
    LCD_delay();
    }
    }

    __________________________________________________ ______________________

    Circuit is attached:
    Circuit PROTEUS.jpg

    __________________________________________________ ______________________

    Kindly help me... This will be useful to others too.. Thanks in advance..

  2. #2

    Default

    Shouldn't it be MSB first and then LSB to be sent to the LCD ?

  3. #3

    Default

    Yeah U r correct. Thanks.

    So the program should be corrected as:

    void LCD_command(unsigned char command)
    {
    unsigned char temp;
    RS = 0;

    // To send MSB part of command
    temp = (command & 0xf0)<<4;
    PORTA &= 0x30;
    PORTA |= temp;
    EN = 1;
    for(temp=0;temp<10;temp++);
    EN = 0;
    LCD_delay();

    // After sending MSB, To send LSB part of command
    temp =command & 0x0f;
    PORTA &= 0x30;
    PORTA |= temp;
    EN = 1;
    for(temp=0;temp<10;temp++);
    EN = 0;
    LCD_delay();
    }

    And same thing should be done for sending data.

    Am i right?? Also pl recheck nd tel if der r stil some errors. Thanks again..
    Last edited by nitinmathew2007; 05-31-2011 at 12:24 PM. Reason: Mistake in reply

  4. #4

    Default

    Nitin, there are plenty of examples on the internet for this. Just make sure you have sufficient delay, and the initialization sequence is correct. Check the datasheet for the correct sequence to initialize. The 0x03 0x03, 0x02 and then 0x28 should be first in sequence. I do not remember exactly.Correlate with the datasheet
    Last edited by shobhitkukreti; 05-31-2011 at 01:06 PM.

  5. #5

    Default

    Ya ok tanX anyway..

    As u said i modified and tried but still i din get output. So am concentrating on delay and initialization sequence. once i get it right i ll paste my coding here for future use...

    Thanks once again..

    --Nitin

  6. #6

    Default

    I can give you the code for MSP430. You can port it to PIC

  7. #7

    Default

    Ya k fine! Meanwhile I am trying to correct my code.
    Last edited by nitinmathew2007; 05-31-2011 at 08:16 PM.

  8. #8

    Default

    Try this sequence:

    P2OUT |= 0x30; //
    delay(295);
    enable();
    delay(195);
    P2OUT |= 0x30;
    delay(195);
    enable();
    delay(145);
    P2OUT |= 0x30;
    delay(195);
    enable();
    delay(195);
    P2OUT |= 0x20; // 4bit mode, completes in single cycle
    delay(195);
    enable();
    lcd_send_cmd(0x28); // 4 bit mode
    delay(195);;
    lcd_send_cmd(0x06); // Entry Mode
    delay(195);
    lcd_send_cmd(0x08);
    delay(195);
    lcd_send_cmd(0x0E); // Display On, Cursor On, Blink Off/On
    delay(195);
    lcd_send_cmd(0x14); // Display shift/Increment
    delay(195);
    lcd_send_cmd(0x02);// Return to Home Position
    delay(280);
    lcd_send_cmd(0x01); // Clear Display
    delay(195);
    }

  9. #9

    Default

    Now after incorporating all your corrections and suggestions, my new program is as follows. I tried 2-3 methods still I am unable to get the output. I shall BOLD the corrections made from the first prog.

    #include<htc.h>

    #define RS RE0
    #define RW RE1
    #define EN RE2

    void LCD_delay(void)
    {
    int t;
    for(t=0;t<250;t++);
    }

    void LCD_delay2(void)
    {
    long a;
    for(a=0;a<8000;a++);
    }

    void LCD_command(unsigned char command)
    {
    unsigned char temp;
    RS = 0;

    // To send MSB part of command
    temp = (command & 0xf0)>>4; //PL note here the operator should be ">>" right??
    PORTA &= 0x30;
    PORTA |= temp;
    EN = 1;
    for(temp=0;temp<10;temp++);
    EN = 0;
    LCD_delay();

    // After sending MSB, To send LSB part of command
    temp =command & 0x0f;
    PORTA &= 0x30;
    PORTA |= temp;
    EN = 1;
    for(temp=0;temp<10;temp++);
    EN = 0;
    LCD_delay();
    LCD_delay();
    }

    void LCD_data(unsigned char data)
    {
    unsigned char temp;
    RS=1;
    temp =(data & 0xf0)>>4;
    PORTA &= 0x30;
    PORTA |= temp;
    EN = 1;
    for(temp=0;temp<10;temp++);
    EN = 0;
    LCD_delay();

    temp = data & 0x0f;
    PORTA &= 0x30;
    PORTA |= temp;
    EN = 1;
    for(temp=0;temp<10;temp++);
    EN = 0;
    LCD_delay();
    LCD_delay();
    }

    void initialise_LCD(void)
    {
    ADCON0 = 0x00;//Disable ADC ports
    ADCON1 = 0x06;//Disable ADC ports

    TRISA = 0x00;
    PORTA = 0x00; //DATA or COMMAND i/p to LCD

    TRISE = 0x00;
    PORTE = 0x00; //CONTROL i/p to LCD

    LCD_delay2();
    LCD_command(0x30);
    LCD_delay2();
    LCD_command(0x30);
    LCD_delay();
    LCD_command(0x30);
    LCD_delay();
    LCD_command(0x20);
    LCD_delay2();

    /* //I TRIED THE FOLLOWING TOO BUT DIN WORK, So THE FOLL CODES R COMMENTED
    PORTA=0x03;
    for(i=0;i<25;i++); //I use this cuz i use 4 bit interface if i send 0x30 I ll get oly 0 in porta. So i send MSB 1st then LSB! (made my own try :P)
    PORTA=0x30;
    LCD_delay2();
    EN=1;
    PORTA=0x03;
    for(i=0;i<25;i++);
    PORTA=0x30;
    LCD_delay2();
    EN=1;
    PORTA=0x03;
    for(i=0;i<25;i++);
    PORTA=0x30;
    LCD_delay();
    EN=1;
    PORTA=0x02;
    for(i=0;i<25;i++);
    PORTA=0x20;
    LCD_delay2();
    EN=1;

    */

    LCD_command(0x28); //4-bit interface, 2 lines, 5*8 dots
    LCD_delay2();
    LCD_command(0x07);//increment, disp shift
    LCD_delay2();
    LCD_command(0x0c);//off cursor, display on
    LCD_delay2();
    LCD_command(0x14);//Display shift,shift to left i.e. scroll
    LCD_delay2();
    LCD_command(0x02);//Command return the cursor to home
    LCD_delay2();
    LCD_command(0x01);
    LCD_delay2();
    }

    void clear_LCD()
    {
    LCD_command(0x01);
    LCD_delay2();
    }

    void display_LCD(char line_number,char position, const char *message)
    {
    int a;
    if(line_number==1)
    {
    a = 0x80 + position;
    RS = 0;
    LCD_command(a);
    }
    else
    {
    a = 0xC0 + position;
    RS = 0;
    LCD_command(a);
    }
    while(*message!=0)
    {
    RS = 1;
    LCD_data(*message);
    message++;
    }
    }

    void main(void)
    {
    __CONFIG(0x193A);
    initialise_LCD();
    RW=0;
    while(1)
    {
    display_LCD(1,1,"WELCOME");
    display_LCD(2,4,"welcome");
    LCD_delay();
    }
    }


    If u r free pl help help me in correcting the program. I guess only some mild error somewhere is causing the trouble! Pl help me...

    Thanks...
    Last edited by nitinmathew2007; 06-01-2011 at 08:40 PM.

  10. #10

    Default

    I made few modifications and made it as 8bit interface on port B. Now i gt the output. Bt the same if i try using 4bit on same PORT B i don get output! Only code I added to 8 bit interface is the masking MSB& LSB and sending them to ports.

    WORKING CODE FOR INTERFACING LCD in 8-bit MODE

    #include<htc.h>

    #define RS RE0
    #define RW RE1
    #define EN RE2

    void LCD_delay(void)
    {
    int t;
    for(t=0;t<250;t++);
    }

    void delay_ms(unsigned char delay)
    {
    unsigned int i,j;
    for(i=0;i<=delay;i++)
    {
    for(j=0;j<=1000;j++);
    }
    }

    void LCD_command(unsigned char command)
    {
    unsigned char temp;
    RS = 0;

    temp =command & 0xff;
    PORTB &= 0x00;
    PORTB |= temp;
    EN = 1;
    for(temp=0;temp<5;temp++);
    EN = 0;
    LCD_delay();
    }

    void LCD_data(unsigned char data)
    {
    unsigned char temp;
    RS=1;

    temp = data & 0xff;
    PORTB &= 0x00;
    PORTB |= temp;
    EN = 1;
    for(temp=0;temp<5;temp++);
    EN = 0;
    LCD_delay();
    }

    void initialise_LCD(void)
    {
    ADCON0 = 0x00;//Disable ADC ports
    ADCON1 = 0x06;//Disable ADC ports

    TRISB = 0x00;
    PORTB = 0x00; //DATA or COMMAND i/p to LCD

    TRISE = 0x00;
    PORTE = 0x00; //CONTROL i/p to LCD

    EN=0;
    RW=0;

    delay_ms(40);
    LCD_command(0x38);
    delay_ms(20);
    LCD_command(0x38);
    delay_ms(2);
    LCD_command(0x38);
    delay_ms(1);

    LCD_command(0x07);//increment, disp shift
    LCD_command(0x0c);//off cursor, display on
    LCD_command(0x14);//Display shift,shift to left i.e. scroll
    LCD_command(0x02);//Command return the cursor to home
    LCD_command(0x01);//clear LCD
    delay_ms(1);
    }

    void clear_LCD()
    {
    LCD_command(0x01);
    delay_ms(1);
    }

    void display_LCD(char line_number,char position, const char *message)
    {
    int a;
    if(line_number==1)
    {
    a=0x80+position;
    LCD_command(a);
    }
    else if(line_number==2)
    {
    a=0xC0+position;
    LCD_command(a);
    }
    while(*message!=0)
    {
    LCD_data(*message);
    delay_ms(15);
    message++;
    }
    }

    void main(void)
    {
    __CONFIG(0x193A);
    initialise_LCD();
    while(1)
    {
    display_LCD(1,8,"WELCOME TO ALL OF YOU PEOPLE...");
    display_LCD(2,4,"welcome");
    delay_ms(1);
    }
    }
    Last edited by nitinmathew2007; 06-02-2011 at 01:17 PM.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •