Lcd 4 bit initialization problem after MCU reset

Discussion in 'Embedded Systems and Microcontrollers' started by Vindhyachal Takniki, Nov 16, 2014.

  1. Vindhyachal Takniki

    Thread Starter Member

    Nov 3, 2014
    349
    6
    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 (Text):
    1.  
    2. void main(void)
    3. {
    4.     const uint8_t str1[] = "******";
    5.     const uint8_t str2[] = "999999";
    6.  
    7.     configure_lcd();
    8.     lcd_string_print(&str1[0] , 0x80U);
    9.     lcd_string_print(&str2[0] , 0xc0U);  
    10.    
    11.     while(1);
    12. }
    13.  
    14.  
    15.  
    16. void configure_lcd(void)
    17. {
    18.     initialize_lcd_pins();  
    19.     init_lcd();
    20.    
    21. }
    22.  
    23.  
    24. void lcd_string_print(const uint8_t *p_str , uint8_t address)
    25. {
    26.     uint8_t cnt = 0U;        /* max 16 chars to be printed */
    27.     write_lcd_command(address);
    28.     while( (*p_str != '\0') && (cnt < 16U) )
    29.     {
    30.         write_lcd_data(*p_str);
    31.         p_str++;
    32.     }
    33.    
    34. }
    35.  
    36.  
    37.  
    38.  
    39. void write_lcd_data(uint8_t value)
    40. {
    41.     uint8_t cnt;
    42.     LCD_RS_HIGH();
    43.    
    44.     shift_data_on_lcd_pins(value & 0xf0U);
    45.     toggle_lcd_en_pin();
    46.    
    47. /* delay for 12ms */  
    48.     __delay_us(12000);
    49.  
    50.     shift_data_on_lcd_pins( (value << 4U) & 0xf0U );
    51.     toggle_lcd_en_pin( );    
    52.    
    53. /* delay for 12ms */  
    54.     __delay_us(12000);      
    55.    
    56. }
    57.  
    58.  
    59.  
    60.  
    61. void write_lcd_command(uint8_t value)
    62. {
    63.     uint8_t cnt;  
    64.     LCD_RS_LOW();
    65.    
    66.     shift_data_on_lcd_pins(value & 0xf0U);
    67.     toggle_lcd_en_pin();
    68.    
    69. /* delay for 12ms */  
    70.     __delay_us(12000);    
    71.    
    72.     shift_data_on_lcd_pins( (value << 4U) & 0xf0U );
    73.     toggle_lcd_en_pin( );    
    74.    
    75. /* delay for 12ms */  
    76.     __delay_us(12000);    
    77.    
    78. }
    79.  
    80.  
    81.  
    82. static void init_lcd(void)
    83. {
    84.     uint8_t cnt;
    85. /* delay for 300ms */  
    86.     __delay_ms(300);    
    87.    
    88. /* rs shoud be low */    
    89.     LCD_RS_LOW();
    90.    
    91. /* write 0x30 on port */    
    92.     shift_data_on_lcd_pins(0x30U);
    93.     __delay_us(12000);
    94.    
    95. /* write 0x30 on port */    
    96.     shift_data_on_lcd_pins(0x30U);    
    97.     __delay_us(12000);      
    98.  
    99. /* write 0x30 on port */    
    100.     shift_data_on_lcd_pins(0x30U);      
    101.     __delay_us(12000);
    102.    
    103. /* write 0x20 on port */    
    104.     shift_data_on_lcd_pins(0x20U);      
    105.     toggle_lcd_en_pin();    
    106.    
    107.     write_lcd_command(0x28U);
    108.     __delay_us(12000);    
    109.    
    110.     write_lcd_command(0x0cU);
    111.     __delay_us(12000);
    112.    
    113.     write_lcd_command(0x01U);
    114.     __delay_us(12000);
    115.    
    116.     write_lcd_command(0x06U);
    117.     __delay_us(12000);
    118.    
    119.     write_lcd_command(0x80U);
    120.     __delay_us(12000);    
    121.    
    122.     write_lcd_command(0x0eU);
    123.     __delay_us(12000);      
    124.    
    125. }
    126.  
    127.  
    128.  
    129.  
    130. static void shift_data_on_lcd_pins(uint8_t value)
    131. {
    132.     if(value & REG8_BIT_7)
    133.     {
    134.         LCD_D7_HIGH();
    135.     }  
    136.     else
    137.     {
    138.         LCD_D7_LOW();
    139.     }  
    140.    
    141.    
    142.     if(value & REG8_BIT_6)
    143.     {
    144.         LCD_D6_HIGH();
    145.     }  
    146.     else
    147.     {
    148.         LCD_D6_LOW();
    149.     }      
    150.    
    151.    
    152.     if(value & REG8_BIT_5)
    153.     {
    154.         LCD_D5_HIGH();
    155.     }  
    156.     else
    157.     {
    158.         LCD_D5_LOW();
    159.     }      
    160.    
    161.    
    162.     if(value & REG8_BIT_4)
    163.     {
    164.         LCD_D4_HIGH();
    165.     }  
    166.     else
    167.     {
    168.         LCD_D4_LOW();
    169.     }        
    170.    
    171. }
    172.  
    173.  
    174. void initialize_lcd_pins(void)
    175. {
    176.     LCD_EN_OUTPUT_LOW();
    177.     LCD_RS_OUTPUT_LOW();  
    178.     LCD_D7_OUTPUT_LOW();
    179.     LCD_D6_OUTPUT_LOW();  
    180.     LCD_D5_OUTPUT_LOW();
    181.     LCD_D4_OUTPUT_LOW();      
    182.    
    183. }
    184.  
    185.  
    186.  
    187. static void toggle_lcd_en_pin(void)
    188. {
    189.     LCD_EN_HIGH();
    190.     __delay_us(500);
    191.     LCD_EN_LOW();
    192.     __delay_us(500);
    193.    
    194. }  
    195.  
     
  2. GopherT

    AAC Fanatic!

    Nov 23, 2012
    6,052
    3,815
    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.
     
  3. Vindhyachal Takniki

    Thread Starter Member

    Nov 3, 2014
    349
    6
    I am using basic 16x2 HD44780 interface lcd.
    There are 11 pins to interface in 8 bit mode & 6 pin to interface in 4 bit mode.
    There is no reset pin on LCD
     
  4. JohnInTX

    Moderator

    Jun 26, 2012
    2,346
    1,028
    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.
     
    absf likes this.
  5. takao21203

    Distinguished Member

    Apr 28, 2012
    3,577
    463
    Power the LCD through IO port.
     
  6. Vindhyachal Takniki

    Thread Starter Member

    Nov 3, 2014
    349
    6
    problem solved,
    forgot to strobe enable pin in initial commands.
     
    ErnieM likes this.
Loading...