47#include <util/delay.h>
61static uint8_t data_length_bitmask = 0;
64#define CLEAR_DISPLAY 0b00000001U
65#define CURSOR_HOME 0b00000010U
66#define ENTRY_MODE_SET 0b00000100U
67#define ON_OFF_CTRL 0b00001000U
68#define CURSOR_DISPLAY_SHIFT 0b00010000U
69#define FUNCTION_SET 0b00100000U
72#define DATA_LENGTH_BIT 4U
73#define DISPLAY_LINES_BIT 3U
74#define FONT_SIZE_BIT 2U
75#define MOVE_DIRECTION_BIT 1U
76#define DISPLAY_SHIFT_BIT 0U
77#define CURSOR_ENABLE_BIT 1U
78#define BLINK_ENABLE_BIT 0U
79#define ON_OFF_CTRL_BIT 2U
80#define RIGHT_LEFT_BIT 2U
81#define SHIFT_OR_CURSOR_BIT 3U
82#define BUSY_FLAG_BIT 7U
85#define DISPLAY_ON true
86#define DISPLAY_OFF false
89#define POWER_RAMP_DELAY_MS 100
90#define SHORT_INSTR_DELAY_MS 2
91#define LONG_INSTR_DELAY_MS 10
92#define SCROLL_DELAY_MS 400
93#define ENABLE_DELAY_US 2
96void lcd_command(uint8_t data);
97void lcd_char(
char character);
98void pulse_enable(
void);
107 p_config_local = p_config;
110 LCD_CTRL_DDR |= (1U << LCD_RS) | (1U << LCD_EN);
115 data_length_bitmask = 0xff;
119 data_length_bitmask |= (1U << LCD_D7) | (1U << LCD_D6);
120 data_length_bitmask |= (1U << LCD_D5) | (1U << LCD_D4);
124 LCD_DATA_DDR |= data_length_bitmask;
127 _delay_ms(POWER_RAMP_DELAY_MS);
131 byte |= FUNCTION_SET;
134 for (uint8_t count = 0; count < 3; ++count)
137 _delay_ms(LONG_INSTR_DELAY_MS);
141 byte |= FUNCTION_SET;
149 byte |= (DISPLAY_OFF << ON_OFF_CTRL_BIT);
150 byte |= (p_config_local->
cursor_enable << CURSOR_ENABLE_BIT);
151 byte |= (p_config_local->
blink_enable << BLINK_ENABLE_BIT);
155 byte |= CLEAR_DISPLAY;
159 byte |= ENTRY_MODE_SET;
161 byte |= (p_config_local->
display_shift << DISPLAY_SHIFT_BIT);
166 byte |= (DISPLAY_ON << ON_OFF_CTRL_BIT);
167 byte |= (p_config_local->
cursor_enable << CURSOR_ENABLE_BIT);
168 byte |= (p_config_local->
blink_enable << BLINK_ENABLE_BIT);
181 byte |= (p_config_local->
cursor_enable << CURSOR_ENABLE_BIT);
182 byte |= (p_config_local->
blink_enable << BLINK_ENABLE_BIT);
194 byte |= (DISPLAY_ON << ON_OFF_CTRL_BIT);
195 byte |= (p_config_local->
cursor_enable << CURSOR_ENABLE_BIT);
196 byte |= (p_config_local->
blink_enable << BLINK_ENABLE_BIT);
206 for (uint8_t index = 0; str[index] != 0; ++index)
208 lcd_char(str[index]);
230 str[count] = (digit +
'0');
237 lcd_char(str[count - 1]);
257 address = (column + 64);
261 lcd_command(address);
272 for (uint8_t count = 0; count < 16; ++count)
280 for (uint8_t count = 0; count < 16; ++count)
294 byte |= ENTRY_MODE_SET;
296 byte |= (p_config_local->
display_shift << DISPLAY_SHIFT_BIT);
310 lcd_command(CURSOR_HOME);
311 _delay_ms(SHORT_INSTR_DELAY_MS);
321 byte |= CURSOR_DISPLAY_SHIFT;
323 for (uint8_t count = 0; count < distance; ++count)
336 byte |= CURSOR_DISPLAY_SHIFT;
337 byte |= (1U << RIGHT_LEFT_BIT);
339 for (uint8_t count = 0; count < distance; ++count)
352 byte |= CURSOR_DISPLAY_SHIFT;
353 byte |= (1U << SHIFT_OR_CURSOR_BIT);
355 for (uint8_t count = 0; count < distance; ++count)
360 _delay_ms(SCROLL_DELAY_MS);
372 byte |= CURSOR_DISPLAY_SHIFT;
373 byte |= (1U << SHIFT_OR_CURSOR_BIT);
374 byte |= (1U << RIGHT_LEFT_BIT);
376 for (uint8_t count = 0; count < distance; ++count)
381 _delay_ms(SCROLL_DELAY_MS);
395void lcd_command(uint8_t data)
397 LCD_CTRL_PORT &= ~(1U << LCD_RS);
401 LCD_DATA_PORT = data;
408 LCD_DATA_PORT &= ~(data_length_bitmask);
409 byte = (data & 0b11110000);
410 byte = (
byte >> (7U - LCD_D7));
411 LCD_DATA_PORT |= byte;
414 LCD_DATA_PORT &= ~(data_length_bitmask);
415 byte = (data & 0b00001111);
416 byte = (
byte << (LCD_D7 - 3U));
417 LCD_DATA_PORT |= byte;
420 _delay_ms(SHORT_INSTR_DELAY_MS);
427void lcd_char(
char character)
429 LCD_CTRL_PORT |= (1U << LCD_RS);
433 LCD_DATA_PORT = character;
440 LCD_DATA_PORT &= ~(data_length_bitmask);
441 byte = (character & 0b11110000);
442 byte = (
byte >> (7U - LCD_D7));
443 LCD_DATA_PORT |= byte;
446 LCD_DATA_PORT &= ~(data_length_bitmask);
447 byte = (character & 0b00001111);
448 byte = (
byte << (LCD_D7 - 3U));
449 LCD_DATA_PORT |= byte;
452 _delay_ms(SHORT_INSTR_DELAY_MS);
459void pulse_enable(
void)
461 LCD_CTRL_PORT |= (1U << LCD_EN);
462 _delay_us(ENABLE_DELAY_US);
463 LCD_CTRL_PORT &= ~(1U << LCD_EN);
464 _delay_us(ENABLE_DELAY_US);
void lcd_shift_cursor_left(uint8_t distance)
Moves cursor left without changing DDRAM contents.
void lcd_print_string(const char *str)
Prints a string of characters to the display.
void lcd_display_off(void)
Turn display off (config settings are retained).
void lcd_print_integer(int16_t number)
Prints an integer variable.
void lcd_shift_display_right(uint8_t distance, bool delay)
Shifts display right without changing DDRAM contents.
void init_lcd(lcd_config_t *p_config)
Initialisation routine (run once at startup).
void lcd_display_on(void)
Turn display on.
void lcd_fast_clear(void)
Writes space characters to all 32 sections of display (or 16 if in 1 line mode).
void lcd_shift_display_left(uint8_t distance, bool delay)
Shifts display left without changing DDRAM contents.
void lcd_reconfigure(void)
Edits config settings on the display (lcd_config_t members must be changed first).
void lcd_return_home(void)
Sets DDRAM address 0 in address counter.
void lcd_shift_cursor_right(uint8_t distance)
Moves cursor right without changing DDRAM contents.
void lcd_set_cursor(uint8_t column, uint8_t row)
Sets cursor location using x and y coordinates.
Driver for the HD44780 based 16x2 liquid crystal display.
Definitions for pin mapping (for CCS81 gas sensor)
Configuration struct, to be instantiated and values assigned before passing it's address into and cal...
bool display_shift
true = display shift, false = cursor shift.
bool cursor_enable
true = enabled, false = disabled.
bool eight_bit_mode
true = 8 bit mode, false = 4 bit mode.
bool increment_counter
true = increment, false = decrement.
bool blink_enable
true = enabled, false = disabled.
bool five_by_ten_font
true = 5x10 dots, false = 5x8 dots.
bool two_line_display
true = 2 lines, false = 1 line.