lcdfunc.c

This LCD sample application shows how to control HD44780-based character LCD (by Victor Golutvin, corrections by David Hobday).



#include    <system.h>
#include    "main.h"

///////////////////////////////////////////
// Bug fixes by David Hobday 22/09/2003
// This code had a number of problems.
// 1) Reset sequence incorrect, no delay 4.1ms after first 8 bit mode command being sent.
// 2) Missing brackets meant the desired order of evaluation did not occur in a couple of places.
// 3) Corrected display font selection to 5x7
//
// This code  does not use the busy bit, just relies on fixed time delays between commands, but this 
// does save a connection.
// 

/*
Initialising by internal reset circuit 

The HD44780 automatically initialises (resets) when power is turned on using the internal reset 
circuit. The following instructions are executed in initialisation. 
The busy flag (BF) is kept in busy state until initialisation ends. The busy state (BF=1) 
is 10ms after Vcc rises to 4.5volts. 

1. Display clear

2. Function set ..... DL = 1: 8 bit interface
                       N = 0: 1 line display
                       F = 0: 5 x 7 dot character font

3. Display ON/OFF ...  D = 0: Display OFF
                       C = 0: Cursor OFF
                       B = 0: Blink OFF

4. Entry mode set .. I/D = 1: +1 (increment)
                       S = 0: No shift

5. Write DD RAM
   When the rise time of power supply (0.2 -> 4.5) is out
   of the range 0.1ms - 10ms, or when the low level width
   of power OFF (less than 0.2) is less than 1ms, the
   internal reset circuit will not operate normally.
   In this case, initialisation will not be performed
   normally. Initialise by instruction, as detailed below.

If the power supply conditions for correctly operating the internal reset circuit are not met, 
initialisation by instruction is required. 

======  W h e n     i n t e r f a c e    i s    4 - b i t s    w i d e  ======
 
        [Power ON]

[  Wait more than 15ms  ]
[after Vdd rises to 4.5v]

RS  R/W DB7 DB6 DB5 DB4  Can't check BF before this instruction
 0   0   0   0   1   1   Function set (8-bit interface)

    [Wait more than]
    [     4.1ms    ]

RS  R/W DB7 DB6 DB5 DB4  Can't check BF before this instruction
 0   0   0   0   1   1   Function set (8-bit interface)

    [Wait more than]
    [     100us    ]

RS  R/W DB7 DB6 DB5 DB4  Can't check BF before this instruction
 0   0   0   0   1   1   Function set (8-bit interface)

                         BF can be checked after the following
                         instructions. When BF is not checked,
                         the waiting time between instructions
                         is longer than the execution time.
                         (See Instruction set)

RS  R/W DB7 DB6 DB5 DB4
 0   0   0   0   1   0   Function set (to 4-bit interface)

RS  R/W DB7 DB6 DB5 DB4
 0   0   0   0   1   0
 0   0   N   F   *   *   Function set  [4-bit Interface      ]
                                       [Specify display lines]
RS  R/W DB7 DB6 DB5 DB4                [and character font   ]
 0   0   0   0   0   0                  These cannot be
 0   0   1   0   0   0   Display OFF    changed afterwards
                                        
RS  R/W DB7 DB6 DB5 DB4
 0   0   0   0   0   0   
 0   0   0   0   0   1   Display ON

RS  R/W DB7 DB6 DB5 DB4 
 0   0   0   0   0   0   
 0   0   0   1  I/D  S   entry mode set

[end of initialisation]

*/

/**********************************
 * Initialisation by instructions *
 **********************************/

void init_LCD(void)
{
    delay_ms(16);

   LCD_icmd( 0x30 ) ;          /*  8 Bit mode  */
   delay_ms(5);   // DH - min delay here of 4.1 ms
   LCD_icmd( 0x30 ) ;          /*  8 Bit mode  */
   LCD_icmd( 0x30 ) ;          /*  8 Bit mode  */

   LCD_icmd( 0x20 ) ;          /*  4-BIT Mode  */
   LCD_cmd( 0x28 );            /*  Function Set: 4-bit,2-line,5X7 */

   LCD_cmd( 0x0C );            /*  Display on, Cursor off         */
   LCD_cmd( 0x06 );            /*  Entry mode: INC addr, NO SHIFT display */

   LCD_cmd( 0x01 );            /*  Clear Display */
   delay_ms( 4 );
}


/*******************************************************
 *  LCD_cmd - Write ASCII character to LCD peripheral  *
 *      configured as a 4 bit interface                *
 *******************************************************/
void LCD_char(byte data)
{
    LCD = (data & 0xF0) | (LCD & 0x0F);         /* Write HI nibble word to LCD */
    write_data;
    LCD = ((data << 4) & 0xF0) | (LCD & 0x0F);  /* Write LO nibble word to LCD */
    write_data;
    delay_us(160);
}
/*****************************************************
 *  LCD_icmd - Write control word to LCD peripheral  *
 *****************************************************/
void LCD_icmd(byte data)
{
    LCD = data | (LCD&0x0F) ;
    write_cmd;
    delay_us(160);
}

/***************************************************
 *  LCD_cmd - Write control word to LCD peripheral *
 *      configured as a 4 bit interface            *
 **************************************************/
void LCD_cmd(byte data)
{
    LCD = (data & 0xF0) | (LCD&0x0F);         /* Write HI nibble word to LCD */
    write_cmd;
    LCD = ((data << 4) & 0xF0) | (LCD&0x0F);  /* Write LO nibble word to LCD */
    write_cmd;
    if (data < 0x03) delay_ms(4); else delay_us(160);
}

/********************************
 * Display byte in HEX - format *
 ********************************/
void PHex(byte data)
{
byte n;
    n = ((data >> 4) & 0x0F) + 0x30;
    if (n > 0x39) n = n+7;
    LCD_char(n);
    n = (data & 0x0F) + 0x30;
    if (n > 0x39) n = n+7;
    LCD_char(n);
}

void ph1(byte data)
{
    if (data > 0x39) data = data+7;
    LCD_char(data);
}

/**********************************
 * Display byte as decimal number *
 **********************************/
void Hex2Dec(byte data)
{
     if (data>99) ph1(((data /100) & 255) + 0x30);
     data = data % 100;
     ph1( ((data / 10) & 255) + 0x30 );
     ph1( ((data % 10) & 255) + 0x30 );
}



void printf( const char* text )
{
    char i = 0;
    while( text[i] != 0 )
        LCD_char( text[i++] );
}


http://www.sourceboost.com/home.html

Copyright © 2002-2006 SourceBoost Technologies