Connect with us

Help Programming 16x2 LCD - PIC16F73

Discussion in 'Microcontrollers, Programming and IoT' started by Sadlercomfort, Feb 19, 2016.

Scroll to continue with content
  1. Sadlercomfort

    Sadlercomfort Ash

    424
    53
    Feb 9, 2013
    Hi Guys,

    I'm having trouble programming an 16x2 LCD, I wondered if someone could check my code. It compiles ok.

    Still don't fully understand how to program this LCD, the order of which to execute commands seems confusing.

    What is the sequence of writing data to the LCD, for example selecting the line cursor position?



    Code:
    #include <htc.h>
    #include <pic.h>
    #define _XTAL_FREQ 4000000
    __CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & CP_OFF & BOREN_OFF );
    
    /****************** PIN Mapping *******************/
    #define BF RC0
    #define RS RA3
    #define RW RA4
    #define EN RA5
    #define D0 RC7
    #define D1 RC6
    #define D2 RC5
    #define D3 RC4
    #define D4 RC3
    #define D5 RC2
    #define D6 RC1
    #define D7 RC0
    /************ LCD Command Mapping LSB-BITFLIP *****************/
    #define CLRDISP     0b01000000
    #define DISPLAY_ON     0b00110000
    #define DISPLAY_OFF 0b00010000
    #define CURSOR_ON     0b01010000
    #define CURSOR_OFF  0b00010000
    #define CURSOR_INC  0b01100000
    #define MODE_8BIT     0b00011100
    #define MODE_4BIT    0b00010100
    /************** Line Addr Mapping LSB-BITFLIP******************/
    #define LCD_LINE1     0b00000001
    #define LCD_LINE2     0b00000011
    #define LCD_LINE3     0b00101001
    #define LCD_LINE4     0b00101011
    
       
    void LCD_cmd(unsigned char cmd);
    void LCD_busy(void);
    void LCD_data(unsigned char data);
    void LCD_init(void);
    void LCD_string(const char *ptr);
    
    
    void LCD_init(void){
        TRISB = 0x00;
        TRISC = 0x00;
        LCD_cmd(MODE_8BIT);                        //2 Line, 5x8 disp, 8 bit
        LCD_cmd(CLRDISP);                        //Clear Display
        LCD_cmd(CURSOR_INC);                    //Increment Cursor on each write
        LCD_cmd(DISPLAY_ON | CURSOR_OFF);        //Bitwise OR
    return;
    }
    
    void LCD_cmd(unsigned char cmd){
        LCD_busy();                    //Check if LCD busy
        RS=0;                        //Register set to CMD
        RW=0;                        //Write data
        EN=1;                        //Ensure Enable is HIGH
        PORTC=cmd;                    //Send data to PORTC
        __delay_ms(50);
        EN=0;                        //Enable is LOW
    }
    
    void LCD_busy(){
        TRISCbits.TRISC0=1;         //Make D7 as input
        EN=0;                        //Ensure Enable is LOW
        RS=0;                        //Register set to CMD
        RW=1;                        //Read Data
        EN=1;                        //Enable LOW too HIGH transition
        __delay_ms(50);
        while(BF);
        TRISCbits.TRISC0=0;         //Make D7 as output
        EN=0;
    }
    
    void LCD_data(unsigned char data){
        RS=1;
        RW=0;
        EN=1;
        PORTC=data;
        __delay_ms(50);
        EN=0;
    }
    
    void LCD_string(const char *buffer){
        while(*buffer)              // Write data to LCD up to null
        {
            LCD_busy();           // Wait while LCD is busy
            LCD_data(*buffer);      // Write character to LCD
            buffer++;               // Increment buffer
        }
    }
    
    void main(){
        LCD_init();
        LCD_cmd(LCD_LINE1);
        __delay_ms(50);
        LCD_string("     Welcome to     ");
        __delay_ms(50);
        LCD_cmd(LCD_LINE2);
        __delay_ms(50);
        LCD_string("Handicare");
        __delay_ms(2000);
    }
     
  2. Sadlercomfort

    Sadlercomfort Ash

    424
    53
    Feb 9, 2013
    Thanks Minder, I think i read Nigels code before..
    I've had a quick read through the first two links, but still having trouble understanding.

    Too send commands or data.. have i got this bit write (No pun intended).

    Sending a Command:
    Code:
    RS=0;
    RW=0;
    EN=1;
    PORTC=cmd;
    __delay_ms(50);
    EN=0;
    Sending Text data:
    Code:
    RS=1;
    RW=0;
    EN=1;
    PORTC=data;
    __delay_ms(50);
    EN=0;
     
  3. Minder

    Minder

    3,013
    640
    Apr 24, 2015
    Yes, I only use Assembly but if you look at TUT3 of Nigels site it shows the status of each command and should make it clear what happens for each function,
    See http://www.winpicprog.co.uk/pic_tutorial3.htm
    I use the read busy status of the display rather than use a delay, but both work.
    M.
     
  4. Sadlercomfort

    Sadlercomfort Ash

    424
    53
    Feb 9, 2013
    I was taught assembly initially, but its been a few years.. :rolleyes:

    Since I'm struggling to understand this in C.. I'll try revisit assembly go through Nigel assembly code.. o_O
     
  5. Sadlercomfort

    Sadlercomfort Ash

    424
    53
    Feb 9, 2013
    I'm having even more trouble understanding the assembly version, can anybody help? o_O
     
  6. Sadlercomfort

    Sadlercomfort Ash

    424
    53
    Feb 9, 2013
    I can't find where I've gone wrong here, so I really need some help here.

    Another Tutorial Site Used:
    http://embedjournal.com/programming-lcd-in-8-bit-mode/

    My LCD Command Sheet:
    http://s000.tinyupload.com/index.php?file_id=00528284006574499388

    My Circuit Diagram:

    [​IMG]

    My current code:
    Code:
    #include <htc.h>
    #include <pic.h>
    #define _XTAL_FREQ 4000000
    __CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & CP_OFF & BOREN_OFF );
    
    /****************** PIN Mapping *******************/
    #define BF PORTCbits.RC7
    #define RS PORTAbits.RA3      
    #define RW PORTAbits.RA4  
    #define EN PORTAbits.RA5  
    #define D0 PORTCbits.RC0
    #define D1 PORTCbits.RC1
    #define D2 PORTCbits.RC2
    #define D3 PORTCbits.RC3
    #define D4 PORTCbits.RC4
    #define D5 PORTCbits.RC5
    #define D6 PORTCbits.RC6
    #define D7 PORTCbits.RC7
    /************ LCD Command Mapping *****************/
    #define CLRDISP     0b00000010
    #define DISPLAY_ON     0b00001100
    #define DISPLAY_OFF 0b00001000
    #define CURSOR_ON     0b00001010    /////////////////////////////
    #define CURSOR_OFF  0b00001000    //See CMD Instruction Sheet//
    #define CURSOR_INC  0b00000110    /////////////////////////////
    #define MODE_8BIT     0b00111000
    #define MODE_4BIT    0b00101000
    
    #define DATAPORT PORTC
    /************** Line Addr Mapping******************/
    #define LCD_LINE1     0b10000000
    #define LCD_LINE2     0b11000000  
    #define LCD_LINE3     0b10010100
    #define LCD_LINE4     0b11010100
    
      
    void LCD_cmd(unsigned char cmd);
    void LCD_busy(void);
    void LCD_data(unsigned char data);
    void LCD_init(void);
    void LCD_string(const char *ptr);
    
    
    
    void LCD_init(void){
        LCD_cmd(MODE_8BIT);                        //2 Line, 5x8 disp, 8 bit
        LCD_cmd(CLRDISP);                        //Clear Display
        LCD_cmd(CURSOR_INC);                    //Increment Cursor on each write
        LCD_cmd(DISPLAY_ON | CURSOR_OFF);        //Bitwise OR
    return;
    }  
    
    void LCD_cmd(unsigned char cmd){
        LCD_busy();                    //Check if LCD busy
        RS=0;                        //Register set to CMD
        RW=0;                        //Write data
        EN=1;                        //Ensure Enable is HIGH
        DATAPORT=cmd;                    //Send data to PORTC
        __delay_ms(200);
        EN=0;                        //Enable is LOW
    }
    
    void LCD_busy(){
        TRISC7=1;         //Make D7 as input
        RS=0;                        //Register set to CMD
        RW=1;                        //Read Data
        EN=1;                        //Enable LOW too HIGH transition
        __delay_ms(200);
        while(BF);
        TRISC7=0;         //Make D7 as output
        EN=0;
    }
    
    void LCD_data(unsigned char data){
        RS=1;
        RW=0;
        EN=1;
        DATAPORT=data;
        __delay_ms(200);
        EN=0;
    }
    
    void LCD_string(const char *buffer){
        while(*buffer)              // Write data to LCD up to null
        {
            LCD_busy();           // Wait while LCD is busy
            LCD_data(*buffer);      // Write character to LCD
            buffer++;               // Increment buffer
        }
    }
    
    void main(){
        TRISA = 0x00;
        TRISB = 0x00;
        TRISC = 0x00;
        LCD_init();
        while(1)
        {
        LCD_cmd(LCD_LINE1);
        __delay_ms(200);
        LCD_string("     Welcome to     ");
        __delay_ms(200);
        LCD_cmd(LCD_LINE2);
        __delay_ms(200);
        LCD_string("Handicare");
        __delay_ms(2000);
        }
    }
    


    Ok, I know I've set my frequency and config bits alright. I've also mapped out my commands, lines and pins.
    This part of my program seems okay and I've checked it several times.
     
    Last edited: Mar 15, 2016
  7. Minder

    Minder

    3,013
    640
    Apr 24, 2015
  8. Sadlercomfort

    Sadlercomfort Ash

    424
    53
    Feb 9, 2013
    I've read that Minder :rolleyes: still stuck
     
  9. Minder

    Minder

    3,013
    640
    Apr 24, 2015
    The write to a line is address (in Hex) 0x80 for 1st line, 0xc0 for second line, any subsequent write to a line will increment the position, if you want to write to a particular char in either line, then add the posn to either 0x80 or 0xc0.
    I don't use C so I cannot help very much with the problem.
    M.
     
  10. Sadlercomfort

    Sadlercomfort Ash

    424
    53
    Feb 9, 2013
    Ok, I've done that. I have the 1st line as 0b11000000 (0x80) and the 2nd line as 0b11000000 (0xc0).

    Minder, whats this part of the code for in asm.. I dont think I've used the hex table in my code
    Code:
    HEX_Table      ADDWF   PCL       , f
                    RETLW   0x30
                    RETLW   0x31
                    RETLW   0x32
                    RETLW   0x33
                    RETLW   0x34
                    RETLW   0x35
                    RETLW   0x36
                    RETLW   0x37
                    RETLW   0x38
                    RETLW   0x39
                    RETLW   0x41
                    RETLW   0x42
                    RETLW   0x43
                    RETLW   0x44
                    RETLW   0x45
                    RETLW   0x46
    
    
    Text        addwf    PCL, f
            retlw    'H'
            retlw    'e'
            retlw    'l'
            retlw    'l'
            retlw    'o'
            retlw    0x00
    
    Text2        ADDWF   PCL, f
                    RETLW   'R'
                    RETLW   'e'
                    RETLW   'a'
                    RETLW   'd'
                    RETLW   'y'
                    RETLW   '.'
                    RETLW   '.'
                    RETLW   '.'
                    RETLW   0x00
     
  11. Minder

    Minder

    3,013
    640
    Apr 24, 2015
    That is a method of table read for the 16F series.
    I found the 18F series much better to use as they have quite a few features and advantages over the 16F series, especially programming in Assembly.
    If you are still getting problems with proven code, could it possibly be a hardware issue?
    M.
     
  12. Sadlercomfort

    Sadlercomfort Ash

    424
    53
    Feb 9, 2013
    I'm using a PIC16F73.

    I do believe its my code, I have checked my hardware several times.

    Do you have any more asm code I could look at, or a complete LCD program
     
    Last edited: Mar 16, 2016
  13. Minder

    Minder

    3,013
    640
    Apr 24, 2015
    Sadlercomfort likes this.
  14. Sadlercomfort

    Sadlercomfort Ash

    424
    53
    Feb 9, 2013
    Thanks! ;)

    Could I have the code for the 18F series aswell? :rolleyes:

    I always read the datasheet for a new PIC to become familiar with its registers, so should be alright.
     
  15. Minder

    Minder

    3,013
    640
    Apr 24, 2015
    Last edited: Mar 17, 2016
  16. Sadlercomfort

    Sadlercomfort Ash

    424
    53
    Feb 9, 2013
    Thanks Minder,

    Will let you know if I'm successful..
     
  17. Sadlercomfort

    Sadlercomfort Ash

    424
    53
    Feb 9, 2013
    Hi Minder.. I finally got it working.
    [​IMG]
    The problem was hardware related and somehow I was not getting +5V when switching my RS, RW and EN pins.
    This might of had something to do with the pins being on PORTA.

    My code was pretty much OK! Here is my working code:
    Code:
    #include <htc.h>
    #include <pic.h>
    #define _XTAL_FREQ 4000000
    __CONFIG(FOSC_XT & WDTE_OFF & PWRTE_OFF & CP_OFF & BOREN_OFF );
    
    /****************** PIN Mapping *******************/
    #define BF PORTCbits.RC7
    #define RS PORTBbits.RB4       
    #define RW PORTBbits.RB3   
    #define EN PORTBbits.RB2   
    #define D0 PORTCbits.RC0
    #define D1 PORTCbits.RC1
    #define D2 PORTCbits.RC2
    #define D3 PORTCbits.RC3
    #define D4 PORTCbits.RC4
    #define D5 PORTCbits.RC5
    #define D6 PORTCbits.RC6
    #define D7 PORTCbits.RC7
    #define DATAPORT PORTC
    /************ LCD Command Mapping *****************/
    #define CLRDISP     0b00000001
    #define DISPLAY_ON     0b00001100
    #define DISPLAY_OFF 0b00001000
    #define CURSOR_ON     0b00001010    /////////////////////////////
    #define CURSOR_OFF  0b00001000    //See CMD Instruction Sheet//
    #define CURSOR_INC  0b00000110    /////////////////////////////
    #define MODE_8BIT     0b00111000
    #define MODE_4BIT    0b00101000
    /************** Line Addr Mapping******************/
    #define LCD_LINE1     0b10000000
    #define LCD_LINE2     0b11000000   
    
    
    void LCD_cmd(unsigned char cmd);
    void LCD_busy(void);
    void LCD_data(unsigned char data);
    void LCD_init(void);
    
    
    void LCD_init(void){
        LCD_cmd(MODE_8BIT);                        //2 Line, 5x8 disp, 8 bit
        LCD_cmd(CLRDISP);                        //Clear Display
        LCD_cmd(CURSOR_INC);                    //Increment Cursor on each write
        LCD_cmd(DISPLAY_ON | CURSOR_OFF);        //Bitwise OR
    }   
    
    
    void LCD_cmd(unsigned char cmd){
        LCD_busy();                    //Check if LCD busy
        RS=0;                        //Register set to CMD
        EN=1;                        //Ensure Enable is HIGH
        RW=0;                        //Write data
        DATAPORT=cmd;                    //Send data to PORTC
        __delay_ms(200);
        EN=0;                        //Enable is LOW
    }
    
    
    void LCD_busy(){
        TRISC7=1;         //Make D7 as input
        RS=0;                        //Register set to CMD
        EN=1;                        //Enable LOW too HIGH transition
        RW=1;                        //Read Data
        __delay_ms(200);
        while(BF);
        TRISC7=0;         //Make D7 as output
        EN=0;
    }
    
    
    void LCD_data(unsigned char data){
        RS=1;
        EN=1;
        RW=0;
        DATAPORT=data;
        __delay_ms(200);
        EN=0;
    }
    
    
    void LCD_string(const char *buffer){
        while(*buffer)              // Write data to LCD up to null
        {
            LCD_busy();           // Wait while LCD is busy
            LCD_data(*buffer);      // Write character to LCD
            buffer++;               // Increment buffer
        }
    }
    
    
    void main()
    {
        ADCON1=0b00000111;
        TRISA = 0x00;
        TRISB = 0x00;
        TRISC = 0x00;
        LCD_init();
        while(1)
        {
        LCD_cmd(LCD_LINE1);
        __delay_ms(200);
        LCD_string("Finally");
        __delay_ms(200);
        LCD_cmd(LCD_LINE2);
        __delay_ms(200);
        LCD_string("Working!");
        __delay_ms(2000);
        }
    }    
     
  18. Md fahim faysal

    Md fahim faysal

    6
    0
    Aug 8, 2017
    Hlw bro. Can i use this code in a shine wave inverter? Pic 16f73
    Lcd 1602,
    I want help
     
  19. kellys_eye

    kellys_eye

    4,275
    1,146
    Jun 25, 2010
    This thread has nothing to do with sinewave converters. Please start a new thread.
     
    Md fahim faysal likes this.
Ask a Question
Want to reply to this thread or ask your own question?
You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.
Electronics Point Logo
Continue to site
Quote of the day

-