LCD doesnt work

Discussion in 'Embedded Systems and Microcontrollers' started by allcircuit, Jan 23, 2009.

  1. allcircuit

    Thread Starter Active Member

    Jan 7, 2009
    31
    0
    Well, I tried to diagnostic my PIC and LCD module (JHD 162A),
    by referring to this page.

    I am using the PCWH to compile and get the HEX file.

    The main program code:
    Code ( (Unknown Language)):
    1. #include <16F88.h>
    2. #fuses HS,NOWDT,PUT,NOLVP
    3. #use delay(clock=20000000)
    4. #include "flex_lcd.c"
    5.    
    6. //==========================
    7. void main()
    8. {
    9. lcd_init();  // Always call this first.
    10.  
    11. lcd_putc("\fHello World\n");
    12. lcd_putc("Line Number 2");
    13.  
    14. while(1);
    15. }
    And I modified the flex_lcd.c to meet my PIC:
    Code ( (Unknown Language)):
    1. // flex_lcd.c
    2.  
    3. // These pins are for the Microchip PicDem2-Plus board,
    4. // which is what I used to test the driver.  Change these
    5. // pins to fit your own board.
    6.  
    7. #define LCD_DB4   PIN_B0
    8. #define LCD_DB5   PIN_B1
    9. #define LCD_DB6   PIN_B2
    10. #define LCD_DB7   PIN_B3
    11.  
    12. #define LCD_RS    PIN_B4
    13. #define LCD_RW    PIN_B5
    14. #define LCD_E     PIN_B6
    15.  
    16. // If you only want a 6-pin interface to your LCD, then
    17. // connect the R/W pin on the LCD to ground, and comment
    18. // out the following line.
    19.  
    20. #define USE_LCD_RW   1    
    21.  
    22. //========================================
    23.  
    24. #define lcd_type 2        // 0=5x7, 1=5x10, 2=2 lines
    25. #define lcd_line_two 0x40 // LCD RAM address for the 2nd line
    26.  
    27.  
    28. int8 const LCD_INIT_STRING[4] =
    29. {
    30.  0x20 | (lcd_type << 2), // Func set: 4-bit, 2 lines, 5x8 dots
    31.  0xc,                    // Display on
    32.  1,                      // Clear display
    33.  6                       // Increment cursor
    34.  };
    35.                              
    36.  
    37. //-------------------------------------
    38. void lcd_send_nibble(int8 nibble)
    39. {
    40. // Note:  !! converts an integer expression
    41. // to a boolean (1 or 0).
    42.  output_bit(LCD_DB4, !!(nibble & 1));
    43.  output_bit(LCD_DB5, !!(nibble & 2));
    44.  output_bit(LCD_DB6, !!(nibble & 4));  
    45.  output_bit(LCD_DB7, !!(nibble & 8));  
    46.  
    47.  delay_cycles(1);
    48.  output_high(LCD_E);
    49.  delay_us(2);
    50.  output_low(LCD_E);
    51. }
    52.  
    53. //-----------------------------------
    54. // This sub-routine is only called by lcd_read_byte().
    55. // It's not a stand-alone routine.  For example, the
    56. // R/W signal is set high by lcd_read_byte() before
    57. // this routine is called.    
    58.  
    59. #ifdef USE_LCD_RW
    60. int8 lcd_read_nibble(void)
    61. {
    62. int8 retval;
    63. // Create bit variables so that we can easily set
    64. // individual bits in the retval variable.
    65. #bit retval_0 = retval.0
    66. #bit retval_1 = retval.1
    67. #bit retval_2 = retval.2
    68. #bit retval_3 = retval.3
    69.  
    70. retval = 0;
    71.    
    72. output_high(LCD_E);
    73. delay_cycles(1);
    74.  
    75. retval_0 = input(LCD_DB4);
    76. retval_1 = input(LCD_DB5);
    77. retval_2 = input(LCD_DB6);
    78. retval_3 = input(LCD_DB7);
    79.  
    80. output_low(LCD_E);
    81.    
    82. return(retval);  
    83. }  
    84. #endif
    85.  
    86. //---------------------------------------
    87. // Read a byte from the LCD and return it.
    88.  
    89. #ifdef USE_LCD_RW
    90. int8 lcd_read_byte(void)
    91. {
    92. int8 low;
    93. int8 high;
    94.  
    95. output_high(LCD_RW);
    96. delay_cycles(1);
    97.  
    98. high = lcd_read_nibble();
    99.  
    100. low = lcd_read_nibble();
    101.  
    102. return( (high<<4) | low);
    103. }
    104. #endif
    105.  
    106. //----------------------------------------
    107. // Send a byte to the LCD.
    108. void lcd_send_byte(int8 address, int8 n)
    109. {
    110. output_low(LCD_RS);
    111.  
    112. #ifdef USE_LCD_RW
    113. while(bit_test(lcd_read_byte(),7)) ;
    114. #else
    115. delay_us(60);
    116. #endif
    117.  
    118. if(address)
    119.    output_high(LCD_RS);
    120. else
    121.    output_low(LCD_RS);
    122.      
    123.  delay_cycles(1);
    124.  
    125. #ifdef USE_LCD_RW
    126. output_low(LCD_RW);
    127. delay_cycles(1);
    128. #endif
    129.  
    130. output_low(LCD_E);
    131.  
    132. lcd_send_nibble(n >> 4);
    133. lcd_send_nibble(n & 0xf);
    134. }
    135.  
    136. //----------------------------
    137. void lcd_init(void)
    138. {
    139. int8 i;
    140.  
    141. output_low(LCD_RS);
    142.  
    143. #ifdef USE_LCD_RW
    144. output_low(LCD_RW);
    145. #endif
    146.  
    147. output_low(LCD_E);
    148.  
    149. delay_ms(15);
    150.  
    151. for(i=0 ;i < 3; i++)
    152.    {
    153.     lcd_send_nibble(0x03);
    154.     delay_ms(5);
    155.    }
    156.  
    157. lcd_send_nibble(0x02);
    158.  
    159. for(i=0; i < sizeof(LCD_INIT_STRING); i++)
    160.    {
    161.     lcd_send_byte(0, LCD_INIT_STRING[i]);
    162.    
    163.     // If the R/W signal is not used, then
    164.     // the busy bit can't be polled.  One of
    165.     // the init commands takes longer than
    166.     // the hard-coded delay of 60 us, so in
    167.     // that case, lets just do a 5 ms delay
    168.     // after all four of them.
    169.     #ifndef USE_LCD_RW
    170.     delay_ms(5);
    171.     #endif
    172.    }
    173.  
    174. }
    175.  
    176. //----------------------------
    177.  
    178. void lcd_gotoxy(int8 x, int8 y)
    179. {
    180. int8 address;
    181.  
    182. if(y != 1)
    183.    address = lcd_line_two;
    184. else
    185.    address=0;
    186.  
    187. address += x-1;
    188. lcd_send_byte(0, 0x80 | address);
    189. }
    190.  
    191. //-----------------------------
    192. void lcd_putc(char c)
    193. {
    194.  switch(c)
    195.    {
    196.     case '\f':
    197.       lcd_send_byte(0,1);
    198.       delay_ms(2);
    199.       break;
    200.    
    201.     case '\n':
    202.        lcd_gotoxy(1,2);
    203.        break;
    204.    
    205.     case '\b':
    206.        lcd_send_byte(0,0x10);
    207.        break;
    208.    
    209.     default:
    210.        lcd_send_byte(1,c);
    211.        break;
    212.    }
    213. }
    214.  
    215. //------------------------------
    216. #ifdef USE_LCD_RW
    217. char lcd_getc(int8 x, int8 y)
    218. {
    219. char value;
    220.  
    221. lcd_gotoxy(x,y);
    222.  
    223. // Wait until busy flag is low.
    224. while(bit_test(lcd_read_byte(),7));
    225.  
    226. output_high(LCD_RS);
    227. value = lcd_read_byte();
    228. output_low(lcd_RS);
    229.  
    230. return(value);
    231. }
    232. #endif[/i]
    I am using the LM2936-3.3V to drive both the LCD and the PIC.
    The connection like this:
    From PIC -> LCD
    ----------------------
    RB0 (6) - DB4 (11)
    RB1 (7) - DB5 (12)
    RB2 (8) - DB6 (13)
    RB3 (9) - DB7 (14)
    RB4 (10) - RS (4)
    RB5 (11) - RW (5)
    RB6 (12) - E (6)

    PIC: pin 5 to 0V and pin 14 to 3.3V
    LCD: pin 1 to 0V, pin 2 to 3.3V, pin 3 to contrast 10K

    However i also see nothing... i just able to contrast at line two. :confused:
     
  2. FastEddie

    Active Member

    Jul 14, 2007
    35
    0
    Hi,
    Are you using 16F88 or 16LF88? The 16F88 min. is 4V. While the 16LF88 min. is 2V the max freq running at 2V is 4MHz. At 3.3V the max freq is 10 MHz. That's the way I understood the charts (Figures 18-1 and 18-2 in the datasheet for 16F88). Maybe try lowering your clock speed or up the input voltage. Hope this helped.

    Ed
     
  3. Dutar

    Member

    Jan 27, 2009
    13
    0
    Hi,
    Try these too

    1.
    Increase delay. I guess easiest way will be to define a higher clock value in the delay function. I suggest you to increase it by 3-4 times and if all goes well then you can try and optimize it.

    2.

    In pin definition above try to assign the last 4 bits of the out put register!
     
Loading...