Skip to content

Instantly share code, notes, and snippets.

@jgibbard
Created September 7, 2013 12:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jgibbard/6475089 to your computer and use it in GitHub Desktop.
Save jgibbard/6475089 to your computer and use it in GitHub Desktop.
16x2 Character LCD screen library for PIC microcontrollers
/*
* File: LCD_LIB.c
* Author: James Gibbard
* Description: Display library for operating 16x2 Hitachi HD44780 type displays
* Created on 24 April 2013, 15:23
*/
#include <xc.h>
#include "LCD_LIB.h"
#include <stdio.h>
void LCD_ENABLE (void)
{
LCD_E = 1; //Set enable line high
__delay_us(1); //Wait 1us
LCD_E = 0; //Set enable line low
}
char LCD_BUSY(void) //Returns 1 if busy, 0 if ready
{
unsigned char LCD_READ_VAL;
LCD_DATA_TRIS = 0b11111111; //Set data lines as input
LCD_RW = 1; //1 = Read data
LCD_RS = 0; //0 = command, 1 = data
LCD_E = 1; //Pulse the enable line for 1us
__delay_us(1);
LCD_READ_VAL = LCD_DATA; //Read data from LCD
LCD_E = 0;
LCD_DATA_TRIS = 0; //Set data lines as outputs
LCD_READ_VAL = LCD_READ_VAL & 0b10000000;
if(LCD_READ_VAL == 0b10000000) //If MSB = 1 then return 1, else return 0
{
return 1; //If busy return 1
}
else
{
return 0; //else return 0
}
}
void LCD_SEND_CMD (unsigned char CMD)
{
while(LCD_BUSY() == 1); //loop until LCD ready
LCD_DATA_TRIS = 0; //Set data lines as inputs
LCD_RW = 0; //Set to write mode
LCD_RS = 0; //0 = command, 1 = data
LCD_DATA = CMD; //set data lines to CMD
LCD_ENABLE(); //Pulse the enable for 1 us
}
void LCD_SEND_DATA (unsigned char data)
{
while(LCD_BUSY() == 1); //wait until LCD is not busy
LCD_DATA_TRIS = 0; //Set data lines to inputs
LCD_RW = 0; //Set to write mode
LCD_RS = 1; //Set to data mode
LCD_DATA = data; //Set data lines to data
LCD_ENABLE(); //Pulse the enable line for 1us
}
void LCD_INIT(void)
{
LCD_DATA_TRIS = 0; //Set data lines to outputs
LCD_CONTROL_TRIS = 0; //Set control lines to outputs
LCD_DATA = 0; //Clear the data lines
LCD_E = 0; //Clear the enable line
LCD_RW = 0; //Clear the R/W line
LCD_RS = 0; //Clear the RS line
__delay_ms(100); //Wait for the display to power up
LCD_CLEAR(); //Clear the display
//Set display settings
LCD_SEND_CMD(0b00000110); //Set cursor to inc, display shift off
//0b 000001 ID S. ID 1 = inc address (cursor goes right), ID 0 = dec address (cursor goes left). S 1 = shift, 0 = no shift
LCD_SEND_CMD(0b00111000); //Set display type to 8 wire connection, dual line mode, 5x8 dots
//0b 0 0 1 DL N F x x. DL 1 = 8 wires, 0 = 4 wires. N 1 = 2 line display. 0 = 1 line display. F 1 = 5x10 dots, 0 = 5x8 dots
LCD_SEND_CMD(0b00001100); //Turn on display, turn off cursor, turn off blink
//0b00001 D C B. D = Display, C = Cursor, B = Blink. 1= ON 0 = OFF
}
void LCD_SEND_STRING(const char *var)
{
while(*var) //While *var =/= 0 send *var and inc to next char
{
LCD_SEND_DATA(*var++);
}
}
void LCD_SEND_NUM(unsigned char val)
{
char num[4]; //Create a 4 long array of chars to store the 3 digit values + null terminator
sprintf(num, "%d",val); //Print val in decimal format to string called num
LCD_SEND_STRING(num); //Send string to LCD
}
void LCD_NEW_CHAR(unsigned char address, unsigned char line0, unsigned char line1, unsigned char line2, unsigned char line3, unsigned char line4, unsigned char line5, unsigned char line6, unsigned char line7)
{
LCD_SEND_CMD(0x40 + address); //Set address to CGRAM. CHAR0 is at 0x40, CHAR1 is at 0x48, CHAR2 is at 0x56, etc. 8 CHARS can be stored
LCD_SEND_DATA(line0); //Send line one of char 0bXXX11111. 3MSBs are ignored
LCD_SEND_DATA(line1); //Send line two of char 0bXXX11111. 3MSBs are ignored
LCD_SEND_DATA(line2); //etc
LCD_SEND_DATA(line3);
LCD_SEND_DATA(line4);
LCD_SEND_DATA(line5);
LCD_SEND_DATA(line6);
LCD_SEND_DATA(line7);
LCD_SEND_CMD(0b10000000); //Set address back to DRAM, location 1,1
}
void LCD_SET_CURSOR(unsigned char row, unsigned char column)
{
if (row == 1) //If row 1
{
LCD_SEND_CMD(0b10000000 + (column-1)); //set DRAM address 0b1xxxxxxx = row 1, 0b10000000 = Row 1 column 1, 0b10000001 = row 1, column 2, etc
}
else if (row==2) //If row 2
{
LCD_SEND_CMD(0b11000000 + (column-1)); ////set DRAM address 0b11xxxxxx = row 2
}
}
void LCD_HOME(void)
{
LCD_SEND_CMD(0b00000010); //Sets DRAM to address 0, and returns display from being shifted
}
void LCD_CLEAR(void)
{
LCD_SEND_CMD(0b00000001); //Clears all DRAM, sets DRAM address to 0
}
void LCD_CURSOR_SHIFT(unsigned char direction)
{
LCD_SEND_CMD(0b00010000 | direction); //Sends command to shift cursor
} //Bit 2 = 0 = Shift right. //Bit 2 = 1 = Shift left
void LCD_SCREEN_SHIFT(unsigned char direction)
{
LCD_SEND_CMD(0b00011000 | direction); //Sends command to shift display
} //Bit 2 = 0 = Shift right. //Bit 2 = 1 = Shift left
/*
* File: LCD_LIB.h
* Author: James Gibbard
* Description: Display library for operating 16x2 Hitachi HD44780 type displays
* Created on 24 April 2013, 15:23
*/
#define _XTAL_FREQ 4000000 //Fosc = 4MHz
//Define pins used by LCD
#define LCD_RS PORTCbits.RC6 //Define Register select pin RS = 0 = command, RS = 1 = data
#define LCD_RW PORTCbits.RC7 //Define Read / Write pin. Write = 0, read =1
#define LCD_E PORTCbits.RC1 //Define enable pin, falling edge triggered
#define LCD_DATA PORTB //Define data port
#define LCD_DATA_TRIS TRISB //Define data port I/O
#define LCD_CONTROL_TRIS TRISC //Define control port I/O
//Define variables
#define LCD_LINE2 0b11000000
#define SHIFT_RIGHT 0b00000100
#define SHIFT_LEFT 0b00000000
//Function prototypes
void LCD_ENABLE(void); //Sends an enable pulse. Sets E high for 1us
char LCD_BUSY(void); //Checks busy flag. Returns 1 for bust. 0 for ready
void LCD_SEND_CMD(unsigned char); //Sends a command to the LCD
void LCD_SEND_DATA(unsigned char); //Sends data to the LCD
void LCD_INIT(void); //Initialises the LCD
void LCD_SEND_STRING(const char *var); //Sends a string to the LCD
void LCD_SEND_NUM(unsigned char); //Displays an 8bit number as a decimal number on the LCD
void LCD_SET_CURSOR(unsigned char, unsigned char); //Sets the cursor position (Row 1-2, Column 1-40)
void LCD_HOME(void); //Sets DRAM to address 0, and returns display from being shifted
void LCD_CLEAR(void); //Clears all DRAM, sets DRAM address to 0
void LCD_CURSOR_SHIFT(unsigned char); //Shifts cursor, SHIFT_LEFT shifts left, SHIFT_RIGHT shifts right
void LCD_SCREEN_SHIFT(unsigned char); //Shifts screen, SHIFT_LEFT shifts left, SHIFT_RIGHT shifts right
void LCD_NEW_CHAR(unsigned char,unsigned char,unsigned char,unsigned char,unsigned char,unsigned char,unsigned char,unsigned char, unsigned char);
//^Saves a new character in the LCD's CGROM
@vicredsky
Copy link

Hello,

I used the library functions, however the display does not seem to initialize properly??
My email is:redansky@yahoo.com

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