Lcd 4 bit initialization problem after MCU reset

Thread Starter

Vindhyachal Takniki

Joined Nov 3, 2014
594
1. I have interfaced 16x2 lcd in 4 bit mode. D0-D3 & R/w of lcd are grounded.

2. If system is power on, then lcd works properly. No issue. I have tried many times.

3. But when I press reset button on MCU so that it get reset & reinit the lcd. It don't works most of the time.
I don't understand why. Sometimes some random chinese number, some cursor only & sometimes random numbers.


4. All other pins interfaced worked fine when MCU get reset like led's & adc module except lcd.

5. Below is my code for lcd.

Code:
void main(void)
{
    const uint8_t str1[] = "******";
    const uint8_t str2[] = "999999";

    configure_lcd();
    lcd_string_print(&str1[0] , 0x80U);
    lcd_string_print(&str2[0] , 0xc0U);   
   
    while(1);
}



void configure_lcd(void) 
{
    initialize_lcd_pins();  
    init_lcd();
   
} 


void lcd_string_print(const uint8_t *p_str , uint8_t address) 
{ 
    uint8_t cnt = 0U;        /* max 16 chars to be printed */
    write_lcd_command(address);
    while( (*p_str != '\0') && (cnt < 16U) )
    {
        write_lcd_data(*p_str);
        p_str++;
    }
   
} 




void write_lcd_data(uint8_t value) 
{ 
    uint8_t cnt;
    LCD_RS_HIGH();
   
    shift_data_on_lcd_pins(value & 0xf0U);
    toggle_lcd_en_pin();
   
/* delay for 12ms */  
    __delay_us(12000);

    shift_data_on_lcd_pins( (value << 4U) & 0xf0U );
    toggle_lcd_en_pin( );    
   
/* delay for 12ms */  
    __delay_us(12000);      
   
} 




void write_lcd_command(uint8_t value) 
{ 
    uint8_t cnt;  
    LCD_RS_LOW();
   
    shift_data_on_lcd_pins(value & 0xf0U);
    toggle_lcd_en_pin();
   
/* delay for 12ms */  
    __delay_us(12000);    
   
    shift_data_on_lcd_pins( (value << 4U) & 0xf0U );
    toggle_lcd_en_pin( );    
   
/* delay for 12ms */  
    __delay_us(12000);    
   
}



static void init_lcd(void) 
{ 
    uint8_t cnt;
/* delay for 300ms */  
    __delay_ms(300);    
   
/* rs shoud be low */    
    LCD_RS_LOW();
   
/* write 0x30 on port */    
    shift_data_on_lcd_pins(0x30U);
    __delay_us(12000); 
   
/* write 0x30 on port */    
    shift_data_on_lcd_pins(0x30U);    
    __delay_us(12000);      

/* write 0x30 on port */    
    shift_data_on_lcd_pins(0x30U);      
    __delay_us(12000); 
   
/* write 0x20 on port */    
    shift_data_on_lcd_pins(0x20U);      
    toggle_lcd_en_pin();    
   
    write_lcd_command(0x28U);
    __delay_us(12000);    
   
    write_lcd_command(0x0cU);
    __delay_us(12000); 
   
    write_lcd_command(0x01U); 
    __delay_us(12000); 
   
    write_lcd_command(0x06U);
    __delay_us(12000); 
   
    write_lcd_command(0x80U);
    __delay_us(12000);    
   
    write_lcd_command(0x0eU);
    __delay_us(12000);      
   
} 




static void shift_data_on_lcd_pins(uint8_t value) 
{ 
    if(value & REG8_BIT_7)
    {
        LCD_D7_HIGH();
    }  
    else
    {
        LCD_D7_LOW();
    }  
   
   
    if(value & REG8_BIT_6)
    {
        LCD_D6_HIGH();
    }  
    else
    {
        LCD_D6_LOW();
    }      
   
   
    if(value & REG8_BIT_5)
    {
        LCD_D5_HIGH();
    }  
    else
    {
        LCD_D5_LOW();
    }      
   
   
    if(value & REG8_BIT_4)
    {
        LCD_D4_HIGH();
    }  
    else
    {
        LCD_D4_LOW();
    }        
   
} 


void initialize_lcd_pins(void) 
{ 
    LCD_EN_OUTPUT_LOW();
    LCD_RS_OUTPUT_LOW();  
    LCD_D7_OUTPUT_LOW();
    LCD_D6_OUTPUT_LOW();  
    LCD_D5_OUTPUT_LOW();
    LCD_D4_OUTPUT_LOW();      
   
} 



static void toggle_lcd_en_pin(void) 
{ 
    LCD_EN_HIGH();
    __delay_us(500);
    LCD_EN_LOW();
    __delay_us(500);
   
}
 

GopherT

Joined Nov 23, 2012
8,009
How is your circuit laid out. A reset button for the Microcontroller doesn't reset the LCD in most cases. The LCD module can continue to display values after the micro is disconnected - as long as it had power.

You can add some commands to reset and clear all registers in the LCD module on micro initialization. Check the datasheet for the module for proper reset and initialization. Your power down may be enough to clear all registers in the LCD module on a hard power down but not for a Microcontroller reset.
 

JohnInTX

Joined Jun 26, 2012
4,787
One thing to consider is what the uC I/O pins are doing during power up vs. soft reset. During a power up, junk on the IO will likely be ignored by the LCD (its also powering up.) On a warm reset however, the LCD will see any spurious transitions on its control pins (the processor I/O) and may interpret what it sees as commands and clobber the initialization.

To guard against this kind of thing:
Pull down the LCD E line to be sure it can't float up when the processor IO pins are in the HIz state during reset. You might want to pull up RS too, so that any spurious writes are to the data registers and not the control regs.
Ensure that when you re-init the I/O, you set the proper values first (E=low etc) before setting the direction.

Good luck.
 
Top