Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

[SOLVED] LCD 4 bit Mode is not working

Status
Not open for further replies.

thannara123

Advanced Member level 5
Joined
Jan 7, 2010
Messages
1,580
Helped
122
Reputation
244
Reaction score
114
Trophy points
1,353
Location
India
Activity points
10,382
I am trying to make an LCD Interfacing with 4 bit mode ,
But not working I tried a lot of
Data looked in Debug mode good not found wrong

what is the problem ?

Attached Code and Proteus files





C:
#pragma config FOSC = XT        // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = ON         // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#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)

#define _XTAL_FREQ 1000000

#include <xc.h>
#define LCD_PORTB PORTB
#define RS  RB0
#define EN  RB1

void Strobe (void)
{
    EN = 1;
    __delay_us(1);
     EN = 0;
 
}
void LCD_cmd( unsigned char cmd)
{
    RS = 0;
    __delay_ms(1);
    LCD_PORTB = (cmd & 0xf0) ;
    Strobe();
    LCD_PORTB = (cmd << 4 );
    Strobe();
}
void LCD_data( unsigned char data)
{
     RS = 1;
    __delay_ms(1);
    LCD_PORTB |= (data & 0xf0);
    Strobe();
    LCD_PORTB |= (data << 4 );
    Strobe();
}
void LCD_init()
{
    __delay_ms(20);
     LCD_cmd(0x38);
     __delay_ms(4);
     LCD_cmd(0x38);
    __delay_ms(10);
   // LCD_cmd(0x38);   // Power on Initilization
    LCD_cmd(0x28);    /* 4bit mode */
    LCD_cmd(0x28);    /* Initialization of 16X2 LCD in 4bit mode */
 
    LCD_cmd(0x0C);    /* Display ON Cursor OFF */
    LCD_cmd(0x06);    /* Auto Increment cursor */
 
}
void string(const char *ptr)
{
    while (*ptr)
    {
        LCD_data(*ptr++);
    }
}

     void main()
    {
       TRISB =0;
       TRISD =0;
   
   
       LCD_init();
       LCD_cmd(0x80);
     //string("HELLO WORLD");
      // LINE2;
       string("IT IS WORKING:-)");
   
       while(1);
        return ;
}

1.jpg
 

Attachments

  • LCD_4_Bit_Interfacing.rar
    156.1 KB · Views: 116

Did you even check connections ? Don't seem clear the missing crossing dot at the VSS bus of LCD module ?
 

    thannara123

    Points: 2
    Helpful Answer Positive Rating
What should one figure out from the above picture ? Are you considering that removing the whole wire from the VSS pin at the LCD module would solve the missing net connection ?
--- Updated ---

In addition, got rid of the VEE biasing connection; I guess it should not be feft floating.
 
Last edited:
What should one figure out from the above picture ? Are you considering that removing the whole wire from the VSS pin at the LCD module would solve the missing net connection ?
--- Updated ---

In addition, got rid of the VEE biasing connection; I guess it should not be feft floating.
Sir ,
In proteus simulation its worked yet it not conected , i already connected it earlier the above picture it is removed (sorry )
 

Vee controls contrast and needs to be adjustable ( use a 5 or 10K pot):

iu


Does your code check the LCD busy state ?

1673459440237.png


Regards, Dana.
 

Attachments

  • 44780.pdf
    278.4 KB · Views: 98
Last edited:

In proteus simulation its worked .......
Are you using real hardware or a simulator?
Also what is not working? If it is simply no characters visible, then try setting up the 'contrast' voltage and turning it so that you see the blank rectangles and then turn it back a little (until the rectangles are very faint or just not visible). A common mistake is to have the contract set so low that the character 'dots' are not lit up.

Also @danadakk: the wiring around the variable resistor is wrong - no connection to Vss.
Susan
 

Are you using real hardware or a simulator?
Also what is not working? If it is simply no characters visible, then try setting up the 'contrast' voltage and turning it so that you see the blank rectangles and then turn it back a little (until the rectangles are very faint or just not visible). A common mistake is to have the contract set so low that the character 'dots' are not lit up.

Also @danadakk: the wiring around the variable resistor is wrong - no connection to Vss.
Susan
The pot V wants to range from Vss to Vdd, at least thats what I am doing on my baords and works just fine to
control the contrast. Seems like most of the time Vee in a 5V system wants to be ~ 3 to 4 V.


Regards, Dana.
 

@[B]danadakk[/B] , My code is not checking Busy Flag of LCD

@betwixt , where does the port clear inside the Functions ? (tried inside the function by initlizing with zero but not worked )


@Aussie Susan I am Simulating on proteus ,Thats y i didnt connected Vss and VEE, in my previous simulation ,its works without VDD and VEE ,
Now in this simulation i tried VEE to VCC and VSS to GND ,But not worked .
Nothing displyaing the LCD




Is my code okay ?
 
Last edited:

@betwixt , where does the port clear inside the Functions ? (tried inside the function by initlizing with zero but not worked )
Did you understand why |= can't work in this place? I wonder how you arrived at this code? Did you invent it on your own, or is it copy-and-paste fault?
 

Did you understand why |= can't work in this place? I wonder how you arrived at this code? Did you invent it on your own, or is it copy-and-paste fault?
Sir Nothing done there by ORing i too much time tired by rediting the code so ,i forget to remove that OR operator .

Earlier i done and worked a lot of LCD interface .

For a long time I cant do electronics .After 4,5 years i am refreshing my some of ,

I tired this circuit and the code is by changing several time to work out .


C:
RS = 0;   
    __delay_ms(1);    
    LCD_PORTB = (cmd & 0xf0) ;  
    Strobe();
    LCD_PORTB = (cmd << 4 );
    Strobe();

I think this code is enogh isnt it sir ? , But not working
 
Last edited:

You should try to understand what you are doing here.

RS is also located in PORTB, so the correct LCD_DATA function could like this
Code:
void LCD_data( unsigned char data)
{
    __delay_ms(1);
    LCD_PORTB = (data & 0xf0);
    RS = 1;
    Strobe();
    LCD_PORTB = (data << 4 );
    RS = 1;
    Strobe();
}

or shorter
Code:
void LCD_data( unsigned char data)
{
    __delay_ms(1);
    LCD_PORTB = (data & 0xf0) | 1;
    Strobe();
    LCD_PORTB = (data << 4 ) | 1;
    Strobe();
}
 

You should try to understand what you are doing here.

RS is also located in PORTB, so the correct LCD_DATA function could like this
Code:
void LCD_data( unsigned char data)
{
    __delay_ms(1);
    LCD_PORTB = (data & 0xf0);
    RS = 1;
    Strobe();
    LCD_PORTB = (data << 4 );
    RS = 1;
    Strobe();
}

or shorter
Code:
void LCD_data( unsigned char data)
{
    __delay_ms(1);
    LCD_PORTB = (data & 0xf0) | 1;
    Strobe();
    LCD_PORTB = (data << 4 ) | 1;
    Strobe();
}
changed as you said but not worked sir ,:cry:
 

Show us the whole code again now you have implemented the changes we suggested.

Brian.
C:
#pragma config FOSC = XT         // Oscillator Selection bits (XT oscillator)
#pragma config WDTE = OFF       // Watchdog Timer Enable bit (WDT disabled)
#pragma config PWRTE = OFF      // Power-up Timer Enable bit (PWRT disabled)
#pragma config BOREN = OFF      // Brown-out Reset Enable bit (BOR disabled)
#pragma config LVP = ON         // Low-Voltage (Single-Supply) In-Circuit Serial Programming Enable bit (RB3/PGM pin has PGM function; low-voltage programming enabled)
#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)
#include <xc.h>
#define _XTAL_FREQ 4000000



#define RS  PORTBbits.RB0
#define EN  PORTBbits.RB1

void Strobe (void)
{
    EN = 1;
    __delay_us(2);
     EN = 0; 
    
}
void LCD_cmd( unsigned char cmd)
{ 
    PORTB = 0x00;
    PORTB = (cmd & 0xf0) ; 
     RS = 0;
    Strobe();     
    PORTB = (cmd << 4 )&0xf0;
    Strobe(); 
      
}
void LCD_data( unsigned char data)
{   PORTB = 0x00;
    PORTB = (data & 0xf0) | 1;
    Strobe();   
    PORTB = (data << 4 ) | 1;
    Strobe();
    
}
void LCD_init()
{
    __delay_ms(20);
     LCD_cmd(0x38); 
     __delay_ms(4);
     LCD_cmd(0x38);
    __delay_ms(2);
    LCD_cmd(0x28);    /* 4bit mode */
    LCD_cmd(0x28);    /* Initialization of 16X2 LCD in 4bit mode */
    
    LCD_cmd(0x0C);    /* Display ON Cursor OFF */
    LCD_cmd(0x06);    /* Auto Increment cursor */
    
}
void string(const char *ptr)
{
    while (*ptr)
    {
        LCD_data(*ptr++);
    }
}

     void main()
    {
       TRISB =0;
       PORTB = 0X00;
      
      
      
       LCD_init();
       while(1)
       {
      
     string("HELLO WORLD");
      // LINE2;
       string("Testing)");
      //LCD_data(1);
       }
               return ;
}

Also change the circuit as said
 

Hi,

Code:
PORTB = 0x00;
PORTB = (data & 0xf0) | 1;

could give a race condition problem due to pipelining

better do:
Code:
PORTB = 0x00;
NOP;
PORTB = (data & 0xf0) | 1;

*****
Code:
PORTB = (data & 0xf0) | 1;
    Strobe();   
    PORTB = (data << 4 ) | 1;
    Strobe();
results in a very narrow EN=0, because in STROBE function there is no delay after EN=0

better use:
Code:
void Strobe (void)
{
    EN = 1;
    __delay_us(2);
     EN = 0;
    __delay_us(2);    
}

Klaus
 
Didn't you note you are issuing an 8bit mode configuration command to the LCD whereas the actual connections are for 4 bits only ?

Code C - [expand]
1
LCD_cmd(0x38);

 

    thannara123

    Points: 2
    Helpful Answer Positive Rating
Might be prudent to confirm you comply to the 44780 controller timing :

1673529946814.png


More info in datasheet, attached. Also there are knockoff 44780 chips, confirm what
your module has to make sure you are working with correct datasheet.


Regards, Dana.
 

Attachments

  • HD44780.pdf
    322.1 KB · Views: 101

    thannara123

    Points: 2
    Helpful Answer Positive Rating
There is still a potential problem with writing to PORTB. When you use:
Code:
PORTB = (cmd & 0xf0) ;
PORTB = (cmd << 4 )&0xf0;
you reset the lower four bits of PORTB which drives EN and RS low.

Personally I #define all the pins to the LCD, including the data pins and then set/reset them individually. It avoids any clashes when writing to the port because each bit is controlled without changing the others and as a bonus you can use any pin on any port to connect to the LCD. It does take a few extra instructions but given the delays are there anyway it doesn't slow things down significantly.

something like this:
Code:
#define LCD_D0 RB4
#define LCD_D1 RB5
#define LCD_D2 RB6
#define LCD_D3 RB7

LCD_write(char data)
{
if(data & 0x01) LCD_D0 = 1 else LCD_D0 = 0;
if(data & 0x02) LCD_D1 = 1 else LCD_D1 = 0;
if(data & 0x04) LCD_D2 = 1 else LCD_D2 = 0;
if(data & 0x08) LCD_D3 = 1 else LCD_D3 = 0;
}
then pass the commands/data to the LCD_Write routine in the lower 4 bits. By changing the defines you can swap any port pins. It is also quite easy to expand the routine to write 8 bit data.

Brian.
 
Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top