Microcontroller interfacing with LCD 16x1

Discussion in 'Embedded Systems and Microcontrollers' started by IamNew, Dec 7, 2011.

  1. IamNew

    Thread Starter New Member

    Dec 7, 2011
    3
    0
    I am doing a microcontroller project which utilizing AT 89S52 and a LCD 16x1. I have problem when trying to display letter of 'N' to the LCD. I could have the display on the LCD display but it only give me the LCD backlight and show me the black boxes. My microcontroller is tested fine.

    Below is the codes that I programmed into my microcontroller
    Code ( (Unknown Language)):
    1. //Program to test LCD. Display single character "A"
    2.  
    3. #include<reg51.h>
    4. #define cmdport P3
    5. #define dataport P2
    6. #define q 100
    7. sbit rs = cmdport^0;  //register select pin
    8. sbit rw = cmdport^1;  // read write pin
    9. sbit e = cmdport^6;  //enable pin
    10.  
    11. void delay(unsigned int msec)  // Function to provide time delay in msec.
    12. {
    13. int i,j ;
    14. for(i=0;i<msec;i++)
    15. for(j=0;j<1275;j++);
    16. }
    17.  
    18. void lcdcmd(unsigned char item)  //Function to send command to LCD
    19. {
    20. dataport = item;
    21. rs= 0;
    22. rw=0;
    23. e=1;
    24. delay(1);
    25. e=0;
    26. }
    27.  
    28. void lcddata(unsigned char item)  //Function to send data to LCD
    29. {
    30. dataport = item;
    31. rs= 1;
    32. rw=0;
    33. e=1;
    34. delay(1);
    35. e=0;
    36. }
    37.  
    38. void main()
    39. {
    40. lcdcmd(0x38);  // for using 8-bit 2 row mode of LCD
    41. delay(100);
    42. lcdcmd(0x0E);  // turn display ON for cursor blinking
    43. delay(100);
    44. lcdcmd(0x01);  //clear screen
    45. delay(100);
    46. lcdcmd(0x06);  //display ON
    47. delay(100);
    48. lcdcmd(0x86);  // bring cursor to position 6 of line 1
    49. delay(100);
    50. lcddata('A');
    51. }

    Below is schematic of my circuit:

    [​IMG]

    Please guide me if I am wrong somewhere in the circuit or the code.
     
  2. T.Jackson

    New Member

    Nov 22, 2011
    328
    14
    Do you want my honest opinion?
     
  3. IamNew

    Thread Starter New Member

    Dec 7, 2011
    3
    0
    Sure. I will appreciate it very much.
     
  4. T.Jackson

    New Member

    Nov 22, 2011
    328
    14
    Well, I could tell almost straight away that you don't have many flight hours as a general programmer. I think you're starting off with too high of expectations, trying to bite off a bit more than you can chew without having a solid grip on general problem solving.

    This is not easy to learn by yourself, and you could be in for many, many years of it without doing some form of formal study.

    You can do some online courses with computer programming, not necessarily for MCUs like PIC and Atmel, but perhaps Java programming, which is 100% relevant to what you're trying to do right here now. the C syntax is the same as Java, and any skills that you acquire whilst learning Java you will be able to carry across with you to other languages.

    I don't see valid algorithms in your code. If you cannot do this, then it is just just too hard, short of having an IQ of like 150 or more you will spend years trying to come to grips with it without getting some formal help.
     
  5. Georacer

    Moderator

    Nov 25, 2009
    5,142
    1,266
    T.Jackson, I remind you that this is a site focused on education and hobbyists. You are not to expect full professionalism and mastery of the topic at hand on everyday basis.

    You are welcome to give any helpful and constructive input in order to help the inquirer towards his goal, given that it is achievable and feasible. Keep, however, in mind that the user might not be after complete mastery of the subject, but just wants to make his contraption work. We are not the ones to tell him that he has to get a degree first. If you don't have anything to add towards that direction, you can choose not to answer in his thread.

    Education is always welcome, but let's be reasonable about it.
     
  6. AlexR

    Well-Known Member

    Jan 16, 2008
    735
    54
    The LCD initialisation sequence in your source code does not look right.
    The LCD display initialisation sequence is quite involved and must be done as per the data sheet for the controller that the display uses.
    If you know which control chip your display uses get its data sheet and follow the recommended initialisation sequence to the letter, paying careful attention to include all the recommender delays.
    The HD44780 is one of the most common controller in use so if you don't know your controller type try using the initialisation sequence on pages 45 (8 bit mode) and 46 (4 bit mode) of the HD44780 Data Sheet
     
  7. t06afre

    AAC Fanatic!

    May 11, 2009
    5,939
    1,222
  8. MrChips

    Moderator

    Oct 2, 2009
    12,447
    3,362

    Are you saying that it displays all other characters besides 'N' correctly?
     
  9. spinnaker

    AAC Fanatic!

    Oct 29, 2009
    4,887
    1,015
    The very first thing I would do is to write a little test program to toggle each bit going to the LCD and put a logic or scope probe on each LCD connection to make absolutely sure you have everything connected the way you think they should be connected.


    As someone said above your init code looks way to simple.

    Here is some code for LCD. It is for the PIC but you should be able to translate it fairly easily. One thing to know that the delays you use between commands and data are very important that they are set to the correct length.

    Code ( (Unknown Language)):
    1.  
    2. #define LCD_RS            LATCbits.LATC5        // Control (1=Command 0=Data)
    3. #define LCD_RS_TRIS        TRISCbits.TRISC5    // LCD Control TRIS
    4.  
    5. #define LCD_E            LATCbits.LATC4           // Enable pin
    6. #define LCD_E_TRIS        TRISCbits.TRISC4    // LCD Enable TRIS
    7. #define LCD_E_ANS        ANSELbits.ANS3
    8.  
    9. #define LCD_DB7         LATBbits.LATB7        // LCD Data Bit 7
    10. #define LCD_DB7_TRIS    TRISBbits.TRISB7    //LCD Data Bit 7 TRIS
    11.  
    12. #define LCD_DB6         LATCbits.LATC7        // LCD Data Bit 6
    13. #define LCD_DB6_TRIS     TRISCbits.TRISC7    //LCD Data Bit 6 TRIS
    14. #define    LCD_DB6_ANS        ANSELHbits.ANS9
    15.  
    16. #define LCD_DB5         LATCbits.LATC6        // LCD Data Bit 5
    17. #define LCD_DB5_TRIS     TRISCbits.TRISC6    //LCD Data Bit 5 TRIS
    18. #define LCD_DB5_ANS        ANSELHbits.ANS8
    19.  
    20. #define LCD_DB4         LATCbits.LATC3        // LCD Data Bit 4
    21. #define LCD_DB4_TRIS    TRISCbits.TRISC3    //LCD Data Bit 4 TRIS
    22. #define LCD_DB4_ANS        ANSELbits.ANS7
    23.  
    24.  
    25. /*
    26.  
    27. #define LCD_RS            LATBbits.LATB7        // Control (1=Command 0=Data)
    28. #define LCD_RS_TRIS        TRISBbits.TRISB7    // LCD Control TRIS
    29.  
    30. #define LCD_E            LATCbits.LATC7           // Enable pin
    31. #define LCD_E_TRIS        TRISCbits.TRISC7    // LCD Enable TRIS
    32. #define LCD_E_ANS        ANSELHbits.ANS9
    33.  
    34. #define LCD_DB7         LATCbits.LATC5        // LCD Data Bit 7
    35. #define LCD_DB7_TRIS    TRISCbits.TRISC5    //LCD Data Bit 7 TRIS
    36.  
    37. #define LCD_DB6         LATCbits.LATC4        // LCD Data Bit 6
    38. #define LCD_DB6_TRIS     TRISCbits.TRISC4    //LCD Data Bit 6 TRIS
    39.  
    40.  
    41. #define LCD_DB5         LATCbits.LATC3        // LCD Data Bit 5
    42. #define LCD_DB5_TRIS    TRISCbits.TRISC3    //LCD Data Bit 5 TRIS
    43. #define LCD_DB5_ANS        ANSELbits.ANS7
    44.  
    45. #define LCD_DB4         LATCbits.LATC6        // LCD Data Bit 4
    46. #define LCD_DB4_TRIS    TRISCbits.TRISC6    //LCD Data Bit 4 TRIS
    47. #define LCD_DB4_ANS        ANSELHbits.ANS8
    48.  
    49. */
    50.  
    51. void LCD_nybble(unsigned char data,char rs);
    52. void LCD_e_togg (void);
    53.  
    54.  
    55. void LCD_Init(void)
    56. {
    57.  
    58.     LCD_RS_TRIS = 0;
    59.     LCD_E_TRIS = 0;
    60.     LCD_DB7_TRIS = 0;
    61.     LCD_DB6_TRIS = 0;
    62.     LCD_DB5_TRIS = 0;
    63.     LCD_DB4_TRIS = 0;
    64.    
    65.     LCD_E_ANS = 0;    
    66.     LCD_DB4_ANS = 0;
    67.     LCD_DB4_ANS = 0;
    68. /*
    69.     while (1)
    70.     {
    71.  
    72.     LCD_RS = 0;
    73.     LCD_E = 0;
    74.     LCD_DB4 = 0;
    75.     LCD_DB5 = 0;
    76.     LCD_DB6 = 0;
    77.     LCD_DB7 = 0;
    78.  
    79.  
    80.     delay_ms(10);
    81.  
    82.     LCD_RS = 1;
    83.     LCD_E = 1;
    84.     LCD_DB4 = 1;
    85.     LCD_DB5 = 1;
    86.     LCD_DB6 = 1;
    87.     LCD_DB7 = 1;
    88.  
    89.     delay_ms(10);
    90. }
    91.  
    92. */    
    93.  
    94.     //This is our lcd initialization function
    95.     delay_ms(20);                   // Wait at least 16 mS after powerup
    96.  
    97.     LCD_nybble(0x03,0);             //send 0x03 cmd 3 times to initialize
    98.     delay_ms(5);
    99.  
    100.     LCD_e_togg();                   //Since 0x03 nybble is on the port already
    101.     delay_us(160);                  // we just toggle 2 more times
    102.  
    103.     LCD_e_togg();
    104.     delay_us(160);
    105.  
    106.     LCD_nybble(0x02,0);             //Enable 4 bit mode
    107.     delay_ms(1);
    108.  
    109.     LCD_cmd(0b00101100);            //set 4-bit mode and 2 lines @ 5x7
    110.     delay_us(160);
    111.  
    112.     LCD_cmd(0x10);                    //cursor move & shift left
    113.     delay_us(160);
    114.  
    115.     LCD_cmd(0x06);                    //entry mode = increment
    116.     delay_us(160);
    117.  
    118.     LCD_cmd(0b0001100);                //display on - cursor blink off
    119.     delay_us(160);
    120.  
    121.     LCD_cmd(0x01);                    //clear display
    122.     delay_us(160);
    123.  
    124.     delay_ms(5);
    125. }
    126.  
    127. void LCD_e_togg (void)
    128. {
    129. //This is our toggle E line function to
    130. //tell lcd to accept data
    131.     LCD_E=1;    
    132.     LCD_E=0;
    133.      
    134. }
    135.  
    136. void LCD_cmd(unsigned char letter)
    137. {
    138. //This is our Command Function
    139. //The RS is set to 0 to signify this is a command
    140.     unsigned char temp;             //Our temp Variable
    141.  
    142.     temp=letter;                    //move letter to temp
    143.     temp=temp>>4;                   //shift temp to right by 4
    144.     LCD_nybble(temp,0);             //send the 4 out
    145.  
    146.     temp=letter;                    //move letter to temp
    147.     temp=temp&0x0f;                 //and out first 4
    148.     LCD_nybble(temp,0);             //send out last 4
    149.  
    150.     delay_us(10);
    151. }
    152.  
    153. void LCD_char(unsigned char letter)
    154. {
    155. //This is the same as the lcd_cmd function except
    156. //that is sets RS to 1 telling the lcd this is characters
    157.     unsigned char temp;
    158.  
    159.     temp=letter;
    160.     temp=temp>>4;
    161.     LCD_nybble(temp,1);
    162.  
    163.     temp=letter;
    164.     temp=temp&0x0f;
    165.     LCD_nybble(temp,1);
    166. }
    167.  
    168. void LCD_string(char *senpoint, char Line)
    169. {
    170.     if(Line == 1)
    171.         LCD_cmd(LINE1);
    172.     else
    173.         LCD_cmd(LINE2);
    174.  
    175.     while(*senpoint != '\0')            // While we havent seen a \0 (esc) go on
    176.     {
    177.         LCD_char(*senpoint);            // Send 1st char to our char function
    178.         senpoint++;                     // Send next
    179.     }
    180.  
    181.     delay_us(10);
    182. }
    183. void LCD_nybble(unsigned char nyb,char rs)
    184. {
    185.     char i;
    186.     char x;
    187.  
    188.     LCD_RS = rs;                    // Set RS Pin (defined in header file)
    189.  
    190.     for(i=0;i<4;i++){                // Loop through nybble
    191.  
    192.         if((nyb & 0x08) != 0)       // AND the nybble to 8
    193.             x=1;                    // If the AND == 1 set x
    194.         else
    195.             x=0;                    // If the AND == 0 clear x
    196.  
    197.         if(i==0)                    // Select RA3:RA0 and set or clear pins
    198.             LCD_DB7=x;
    199.  
    200.         if(i==1)
    201.             LCD_DB6=x;
    202.  
    203.         if(i==2)
    204.             LCD_DB5=x;
    205.  
    206.         if(i==3)
    207.             LCD_DB4=x;
    208.  
    209.  
    210.         nyb=nyb<<1;                 // Shift nybble to the left by 1 (4 times total)
    211.     }
    212.  
    213.     LCD_e_togg();                   // Toggle E pin (defined in header file)
    214. }
    215.  
    216. void LCD_clr_line(char line)
    217. {
    218. //This is our clear line command.
    219.     char tline;                             // The line to clear variable
    220.     char x;                                 // loop variable
    221.  
    222.     if(line==0)                             // Set the variable value based on line
    223.         tline=0x80;                         // 0 = Line 1
    224.     else
    225.         tline=0xA8;                         // 1 = Line 2
    226.  
    227.     LCD_cmd(tline);                         // Send command to jump to beggining of line (1/2)
    228.     delay_ms(1);
    229.  
    230.     for(x=0;x<40;x++){                      // Loop through all 40 chars of line (even tho 16 are viewable)
    231.         LCD_char(0x20);                     // Send Blank Character
    232.         delay_us(50);                  
    233.     }
    234.  
    235.     LCD_cmd(tline);                         // Go back to beggining of line
    236.     delay_ms(1);
    237. }
    238.  
     
  10. THE_RB

    AAC Fanatic!

    Feb 11, 2008
    5,435
    1,305
    I don't think the code looks "too simple" it has everything needed, a function to send a command byte, a char byte and an init function.

    It's a good idea to REALLY double check the pins you use for RS E and RW, and also the data lines. Check the IC pins match the port pins as declared in your code.

    And check your init function, it's a good idea to send the top command 3 times, like in the datasheet recommended procedure (that AlexR suggested above).

    And always check your contrast pot and contract pin voltage! I've been caught out in the past chasing software when it was as simple as me forgetting to set the contrast pot, and immediately assuming it was software or bad pin wiring. ;)
     
Loading...