Last active
January 3, 2016 20:29
-
-
Save gshrikant/8515712 to your computer and use it in GitHub Desktop.
HD44780-compatible LCD Driver for LPC2148
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Example Usage: