Skip to content

Instantly share code, notes, and snippets.

@gshrikant
Last active January 3, 2016 20:29
Show Gist options
  • Save gshrikant/8515712 to your computer and use it in GitHub Desktop.
Save gshrikant/8515712 to your computer and use it in GitHub Desktop.
HD44780-compatible LCD Driver for LPC2148
/*
* lcd.c
*
* Low-level driver for Hitachi's HD44780 LCD for LPC2148 board
*
* Created on: 20-Jan-2014
* Author: Shrikant Giridhar
*/
#include "lpc214x.h"
// LCD Pinout
#define DATA 19 // Parallel port (4 pins)
#define ENABLE 18 // Enable
#define RS 17 // Register Select - Data/Command (0 or 1)
#define RW 16 // Write/Read select (0 or 1)
#define BUSY 22 // Busy flag (DB7)
// HD44780U command set
#define _CLEAR 0x01 // Clear DDRAM
#define _FNSET 0x28 // 4-bit, 2-line and 5x8 fonts
#define _ENTRY 0x03 // Increment cursor, no display shift
#define _HOME 0x80 // Beginning of DDRAM
#define _CMD 0x00 // Send a command
#define _TEXT 0x01 // Send data
// Useful Macros
#define _BV(x) 1 << x
#define TOGGLE(x) x ^= x
// Prototypes
void initLCD(void);
void cmdLCD(uint32_t cmd);
void putLCD(unsigned char character);
void print(char* str);
void clrscr(void);
static void writeLCD(uint32_t cmd);
static void tinyDelay(void);
/*! \brief Generate a cycle-accurate delay */
static void tinyDelay(void)
{
// Adhoc; convert to asm later
uint32_t i = 0;
for ( ; i < 131072; ++i);
}
/*! \brief Send commands to the LCD */
static void writeLCD(uint32_t data, uint32_t rs)
{
// Prepare for write
IO0CLR |= _BV(ENABLE);
IO0CLR |= _BV(RW);
if (rs)
IO0CLR |= _BV(RS);
else
IO0SET |= _BV(RS);
// Send upper nibble (MSB)
IO0PIN = (data & 0xF0) << DATA;
IO0PIN ^= _BV(ENABLE);
IO0PIN ^= _BV(ENABLE);
// Send lower nibble (LSB)
IO0PIN = (data & 0x0F) << DATA;
// Strobe
IO0PIN ^= _BV(ENABLE);
IO0PIN ^= _BV(ENABLE);
// See if write is done
while(IO0PIN & _BV(BUSY));
tinyDelay();
// Set all (inactive)
IO0SET |= 0x0F << DATA;
}
/*! \brief Clear the display */
void clrscr(void)
{
tinyDelay();
writeLCD(_CLEAR);
}
/*! \brief Send an instruction to the LCD controller */
void cmdLCD(uint32_t cmd)
{
tinyDelay();
writeLCD(cmd, _CMD);
}
/*! \brief Display a single character on the LCD */
void putLCD(unsigned char character)
{
tinyDelay();
writeLCD(character, _TEXT);
}
/*! \brief Sets up the LCD for communication */
void initLCD(void)
{
// All outputs
IO0DIR |= (0x0F << DATA) | (_BV(ENABLE)) | (_BV(RW)) | (_BV(RS));
cmdLCD(_CLEAR);
cmdLCD(_FNSET);
cmdLCD(_ENTRY);
cmdLCD(_HOME);
}
/*! \brief Prints a formatted string on the LCD */
void print(char *str)
{
// Save context
char *temp;
temp = str;
while (*temp != '\0')
{
putLCD(*temp);
++temp;
}
putLCD('\n');
}
@gshrikant
Copy link
Author

Example Usage:

print("Hello World");    // Appends newline automatically
clrscr();  

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment