Programming 4x20 lcd display with pic16f877a

Discussion in 'Embedded Systems and Microcontrollers' started by AlucardSensei, Aug 7, 2012.

  1. AlucardSensei

    Thread Starter New Member

    Aug 7, 2012
    20
    0
    First of all, hey everyone! I'm kinda new to this business (although I have a couple of years worth of experience with programming in general), and I just found out about this forum, because I've encountered a problem with my microcontroller programming. I have a bit of experience with microcontrollers from one of college courses, but only in Assembly and this is a bit more complex than what I've learned there. I have a project where I need to program the microcontroller to write some text to the LCD, and for starters I just it to write a simple "Hello world", but I've ran headfirst into a wall right off the bat. I've gotten a header file online for working with the LCD, and I've managed to pick up what's it doing for the most part, but I can't seem to get the LCD to display any text at all, all it does is start up, I get a blinking cursor which I can move around by setting the ENABLE bit to 1 through my developing board (not sure if that's the correct term, English is not my native language) and that's it (even though it shouldn't be blinking or even be there at all based on the code). I'm using MPLAB with Hi-Tech C Compiler. Something seemed wrong with the interface length setup with the code being 0x28, because the datasheet clearly states that the 5th bit should be 1, so I've tried changing that, but to no avail. Here's the code and the datasheet for the LCD; any help would be greatly appreciated. Thanks in advance!

    #delay.h
    Code ( (Unknown Language)):
    1.  
    2.  
    3. #define MHZ *1000L          /* number of kHz in a MHz */
    4. #define KHZ *1          /* number of kHz in a kHz */
    5.  
    6. #if XTAL_FREQ == 20MHZ
    7.  
    8.     #define DelayUs(x)  { unsigned int _dcnt; \
    9.         _dcnt = (x)/3; \
    10.         while(--_dcnt != 0) \
    11.     continue; }
    12.  
    13. #elif XTAL_FREQ == 16MHZ
    14.  
    15.     #define DelayUs(x)  { unsigned int _dcnt; \
    16.         _dcnt = (x)/3.75; \
    17.         while(--_dcnt != 0) \
    18.     continue; }
    19.  
    20. #elif XTAL_FREQ == 8MHZ
    21.  
    22.     #define DelayUs(x)  { unsigned int _dcnt; \
    23.         _dcnt = (x)/7.5; \
    24.         while(--_dcnt != 0) \
    25.     continue; }
    26.  
    27. #elif XTAL_FREQ == 4MHZ
    28.  
    29.     #define DelayUs(x)  { unsigned int _dcnt; \
    30.         _dcnt = (x)/15; \
    31.         while(--_dcnt != 0) \
    32.     continue; }
    33.  
    34. #else
    35.     #error Please define XTAL_FREQ - 20MHZ/16MHZ/8MHZ/4MHZ
    36. #endif
    37.  
    38. void DelayMs(unsigned int cnt){
    39.     do {
    40.         DelayUs(1000);
    41.     } while(--cnt);
    42. }
    #lcd.h
    Code ( (Unknown Language)):
    1. /*
    2.  *  LCD interface example
    3.  *  Uses routines from delay.c
    4.  * 
    5.  *  RD3 is connected to the LCD RS input (register select)
    6.  *  RD2 is connected to the LCD RW bit (read/write)
    7.  *  RD1 is connected to the LCD EN bit (enable)
    8.  *  RD4-RD7 are connected to the LCD data bits 4-7 (high nibble)
    9.  * 
    10.  *  To use these routines, set up the port I/O (TRISD) then
    11.  *  call lcd_init(), then other routines as required.
    12.  * 
    13.  */
    14.  
    15. #ifndef _XTAL_FREQ
    16.  // Unless specified elsewhere, 4MHz system frequency is assumed
    17.  #define _XTAL_FREQ 4000000
    18. #endif
    19.  
    20.  
    21. #include    <htc.h>
    22. #include "delay.h"
    23.  
    24. #define LCD_RS RD3
    25. #define LCD_RW RD2
    26. #define LCD_EN RD1
    27. #define LCD_DATA    PORTD
    28.  
    29. #define LCD_STROBE()    ((LCD_EN = 1),(LCD_EN=0))
    30.  
    31. unsigned char lcd_line;
    32.  
    33. /* write a byte to the LCD in 4 bit mode */
    34.  
    35. void lcd_write(unsigned char rs_bit, unsigned char c)
    36. {
    37.     LCD_RS = rs_bit;
    38.     DelayUs(50);
    39.     LCD_DATA = (c & 0xF0);// | (LCD_DATA & 0x0F);
    40.     LCD_STROBE();
    41.     LCD_DATA = ( ( c << 4 ) & 0xF0 );// | (LCD_DATA & 0x0F);
    42.     LCD_STROBE();
    43.     DelayUs(50);
    44. }
    45.  
    46. /*
    47.  * Go to the specified position
    48.  */
    49.  
    50. void lcd_goto(unsigned char pos_x,unsigned char pos_y)
    51. {
    52.     pos_y--;
    53.     lcd_line = pos_x;
    54.     lcd_write(0, 0b00000010);   //1.1: CURSOR RETURN
    55.     DelayMs(2);
    56.     if(pos_x == 1)
    57.     {
    58.         lcd_write(0, 0x80+pos_y);
    59.     }
    60.     else if(pos_x == 2)
    61.     {
    62.         lcd_write(0, 0xC0+pos_y);
    63.     }
    64.     else if(pos_x == 3)
    65.     {
    66.         lcd_write(0, 0x94+pos_y);
    67.     }
    68.     else if(pos_x == 4)
    69.     {
    70.         lcd_write(0, 0xD4+pos_y);
    71.     }
    72. }
    73.  
    74. /*
    75.  *  Clear and home the LCD
    76.  */
    77.  
    78. void lcd_clear(void)
    79. {
    80.     lcd_line=1;
    81.     lcd_write(0,0x1);
    82.     DelayMs(2);
    83. }
    84.  
    85. /* write a string of chars to the LCD */
    86.  
    87. void lcd_puts(const char * s)
    88. {
    89.     LCD_EN = 0;
    90.     int i = 0;
    91.  
    92.     while(*s)
    93.     {
    94.         switch (*s)
    95.         {
    96.             case '\b':  lcd_write(0,0x10);  break; //backspace
    97.             case '\f':  lcd_write(0,0x1); //clear display
    98.                         DelayMs(2);
    99.                         break;
    100.             case '\n':  lcd_goto(lcd_line++,1);  break; //newline
    101.             default  :  lcd_write(1,s[i]);     // write characters
    102.                         break;
    103.         }
    104.         i++;
    105.     }
    106.     LCD_EN = 1;
    107. }
    108.  
    109. /* write one character to the LCD */
    110.  
    111. void lcd_putch(unsigned char c)
    112. {
    113.     lcd_write(1, c); // write characters
    114. }
    115.  
    116. //Backspace
    117. void lcd_back(void)
    118. {
    119.     lcd_write(0,0x10);
    120. }
    121.    
    122. /* initialise the LCD - put into 4 bit mode */
    123. void lcd_init()
    124. {
    125.     LCD_RS = 0;
    126.     LCD_EN = 0;
    127.     LCD_RW = 0;
    128.    
    129.     DelayMs(15);    // wait 15mSec after power applied,
    130.     LCD_DATA = (LCD_DATA & 0x0F) | ( ( 0x3 << 4 ) & 0xF0 ); //Reset
    131.     LCD_STROBE();
    132.     DelayMs(5);
    133.     LCD_STROBE();
    134.     DelayUs(200);
    135.     LCD_STROBE();
    136.     DelayUs(200);  
    137.     LCD_DATA = (LCD_DATA & 0x0F) | ( ( 0x2 << 4 ) & 0xF0 ); // Four bit mode
    138.     LCD_STROBE();
    139.  
    140.     lcd_write(0, 0b00101000); // Set interface length
    141.     lcd_write(0, 0b00001100);  // Display On, Cursor Off, Cursor Blink Off
    142.     lcd_clear();        // Clear screen
    143.     lcd_write(0, 0x6);  // Set entry Mode
    144. }
    145. [/i]


    #main.c
    Code ( (Unknown Language)):
    1. #define XTAL_FREQ 4MHZ
    2. #include <htc.h>
    3. #include "lcd.h"
    4.  
    5. void
    6. main(void)
    7. {
    8.     TRISD = 0b00000000;
    9.     lcd_init();
    10.     lcd_goto(2, 5);
    11.     lcd_puts("Hello world!");
    12.  
    13.     while (1);
    14. }
    15.  
     
  2. AlucardSensei

    Thread Starter New Member

    Aug 7, 2012
    20
    0
    Eh, forget it, it was a programmator error. :)
     
Loading...