Last active
June 10, 2025 20:49
-
-
Save jgibbard/04a664990a2dc06f00ad8ca82f02ca4e to your computer and use it in GitHub Desktop.
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
#include "lcd_test.h" | |
#define FCY 16000000UL | |
#include <libpic30.h> | |
#define LCD_RS LATBbits.LATB15 | |
#define LCD_RW LATDbits.LATD5 | |
#define LCD_E LATDbits.LATD4 | |
#define LCD_DATA PORTE | |
#define LCD_DATA_TRIS TRISE | |
static void lcd_enable(); | |
static uint8_t is_lcd_busy(); | |
static void lcd_send_cmd(uint8_t cmd); | |
void lcd_setup() { | |
// Pin 44, RB15, AN15, LCD_RS | |
TRISBbits.TRISB15 = 0; | |
ANSBbits.ANSB15 = 0; | |
LATBbits.LATB15 = 0; | |
// Pin 82, RD5, LCD_RW | |
TRISDbits.TRISD5 = 0; | |
LATDbits.LATD5 = 0; | |
// Pin 81, RD4, LCD_E | |
TRISDbits.TRISD4 = 0; | |
LATDbits.LATD4 = 0; | |
// Pin 93, RE0, LCD_D0 | |
TRISEbits.TRISE0 = 0; | |
LATEbits.LATE0 = 0; | |
// Pin 94, RE1, LCD_D1 | |
TRISEbits.TRISE1 = 0; | |
LATEbits.LATE1 = 0; | |
// Pin 98, RE2, LCD_D2 | |
TRISEbits.TRISE2 = 0; | |
LATEbits.LATE2 = 0; | |
// Pin 99, RE3, LCD_D3 | |
TRISEbits.TRISE3 = 0; | |
LATEbits.LATE3 = 0; | |
// Pin 100, RE4, LCD_D4 | |
TRISEbits.TRISE4 = 0; | |
LATEbits.LATE4 = 0; | |
// Pin 3, RE5, LCD_D5 | |
TRISEbits.TRISE5 = 0; | |
LATEbits.LATE5 = 0; | |
// Pin 4, RE6, LCD_D6 | |
TRISEbits.TRISE6 = 0; | |
LATEbits.LATE6 = 0; | |
// Pin 5, RE7, LCD_D7 | |
TRISEbits.TRISE7 = 0; | |
LATEbits.LATE7 = 0; | |
__delay_ms(100); | |
// Set display settings | |
lcd_clear(); | |
// 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(0b00000110); | |
// 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(0b00111000); | |
// Turn on display, turn off cursor, turn off blink | |
// 0b00001 D C B. D = Display, C = Cursor, B = Blink. 1= ON 0 = OFF | |
lcd_send_cmd(0b00001100); | |
} | |
static void lcd_enable() { | |
LCD_E = 1; | |
__delay_us(1); | |
//delay_1us(); | |
LCD_E = 0; | |
} | |
//Returns 1 if busy, 0 if ready | |
static uint8_t is_lcd_busy() { | |
// Set data lines as inputs | |
LCD_DATA_TRIS = 0b11111111; | |
// RW==1 : Read data | |
LCD_RW = 1; | |
// 0 = command, 1 = data | |
LCD_RS = 0; | |
// Pulse the enable line for 1us | |
LCD_E = 1; | |
__delay_us(1); | |
// Read data from LCD | |
uint16_t lcd_read_val = LCD_DATA; | |
LCD_E = 0; | |
// Set data lines as outputs | |
LCD_DATA_TRIS = 0; | |
// If MSB = 1 then return 1, else return 0 | |
return ((lcd_read_val & 0b10000000) == 0b10000000); | |
} | |
static void lcd_send_cmd(uint8_t cmd) { | |
// loop until LCD ready | |
while(is_lcd_busy()); | |
// Set data lines as inputs | |
LCD_DATA_TRIS = 0; | |
// Set to write mode | |
LCD_RW = 0; | |
// 0 = command, 1 = data | |
LCD_RS = 0; | |
// Set data lines to cmd | |
LCD_DATA = cmd; | |
// Pulse the enable for 1 us | |
lcd_enable(); | |
} | |
void lcd_send_char(uint8_t data) { | |
// Wait until LCD is not busy | |
while(is_lcd_busy()); | |
// Set data lines to inputs | |
LCD_DATA_TRIS = 0; | |
// Set to write mode | |
LCD_RW = 0; | |
// Set to data mode | |
LCD_RS = 1; | |
// Set data lines to data | |
LCD_DATA = data; | |
// Pulse the enable line for 1us | |
lcd_enable(); | |
} | |
void lcd_send_string(const uint8_t *var) { | |
// While *var != 0 send *var and inc to next char | |
while(*var) { | |
lcd_send_char(*var++); | |
} | |
} | |
void lcd_set_cursor(uint8_t row, uint8_t column) { | |
if (row == 1) { | |
// Set DRAM address 0b1xxxxxxx = row 1, 0b10000000 = Row 1 column 1, 0b10000001 = row 1, column 2, etc | |
lcd_send_cmd(0b10000000 + (column-1)); | |
} else if (row==2) { | |
// Set DRAM address 0b11xxxxxx = row 2 | |
lcd_send_cmd(0b11000000 + (column-1)); | |
} | |
} | |
void lcd_home() { | |
// Sets DRAM to address 0, and returns display from being shifted | |
lcd_send_cmd(0b00000010); | |
} | |
void lcd_clear() { | |
// Clears all DRAM, sets DRAM address to 0 | |
lcd_send_cmd(0b00000001); | |
} | |
void lcd_cursor_shift(uint8_t direction) { | |
// Sends command to shift cursor | |
// Bit 2 = 0 = Shift right. // Bit 2 = 1 = Shift left | |
lcd_send_cmd(0b00010000 | direction); | |
} | |
void lcd_screen_shift(uint8_t direction) { | |
//Sends command to shift display | |
lcd_send_cmd(0b00011000 | direction); | |
} | |
// Custom char generator: https://www.quinapalus.com/hd44780udg.html | |
void lcd_add_char(uint8_t address, | |
uint8_t line0, uint8_t line1, uint8_t line2, uint8_t line3, | |
uint8_t line4, uint8_t line5, uint8_t line6, uint8_t line7) { | |
// Set address to CGRAM. CHAR0 is at 0x40, CHAR1 is at 0x48, | |
// CHAR2 is at 0x56, etc. 8 CHARS can be stored | |
lcd_send_cmd(0x40 + address); | |
// Send line one of char 0bXXX11111. 3MSBs are ignored | |
lcd_send_char(line0); | |
// Send line two of char 0bXXX11111. 3MSBs are ignored | |
lcd_send_char(line1); | |
// etc | |
lcd_send_char(line2); | |
lcd_send_char(line3); | |
lcd_send_char(line4); | |
lcd_send_char(line5); | |
lcd_send_char(line6); | |
lcd_send_char(line7); | |
// Set address back to DRAM, location 1,1 | |
lcd_send_cmd(0b10000000); | |
} |
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
#ifndef LCD_TEST_H | |
#define LCD_TEST_H | |
#include "xc.h" | |
#define LCD_SHIFT_RIGHT 0b00000100 | |
#define LCD_SHIFT_LEFT 0b00000000 | |
void lcd_setup(); | |
void lcd_send_string(const uint8_t *var); | |
void lcd_send_char(uint8_t data); | |
void lcd_set_cursor(uint8_t row, uint8_t column); | |
void lcd_home(); | |
void lcd_clear(); | |
void lcd_cursor_shift(uint8_t direction); | |
void lcd_screen_shift(uint8_t direction); | |
void lcd_add_char(uint8_t address, | |
uint8_t line0, uint8_t line1, uint8_t line2, uint8_t line3, | |
uint8_t line4, uint8_t line5, uint8_t line6, uint8_t line7); | |
#endif | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment