47#include <avr/cpufunc.h>
48#include <util/delay.h>
62static uint8_t data_length_bitmask = 0;
65#define CLEAR_DISPLAY 0b00000001U
66#define CURSOR_HOME 0b00000010U
67#define ENTRY_MODE_SET 0b00000100U
68#define ON_OFF_CTRL 0b00001000U
69#define CURSOR_DISPLAY_SHIFT 0b00010000U
70#define FUNCTION_SET 0b00100000U
73#define DATA_LENGTH_BIT 4U
74#define DISPLAY_LINES_BIT 3U
75#define FONT_SIZE_BIT 2U
76#define MOVE_DIRECTION_BIT 1U
77#define DISPLAY_SHIFT_BIT 0U
78#define CURSOR_ENABLE_BIT 1U
79#define BLINK_ENABLE_BIT 0U
80#define ON_OFF_CTRL_BIT 2U
81#define RIGHT_LEFT_BIT 2U
82#define SHIFT_OR_CURSOR_BIT 3U
83#define BUSY_FLAG_BIT 7U
86#define DISPLAY_ON true
87#define DISPLAY_OFF false
90#define POWER_RAMP_DELAY_MS 100
91#define SHORT_INSTR_DELAY_MS 2
92#define LONG_INSTR_DELAY_MS 10
93#define SCROLL_DELAY_MS 400
94#define ENABLE_DELAY_US 2
97void lcd_command(uint8_t data);
98void lcd_char(
char character);
99void pulse_enable(
void);
108 p_config_local = p_config;
111 LCD_CTRL_DDR |= (1U << LCD_RS) | (1U << LCD_EN);
116 data_length_bitmask = 0xff;
120 data_length_bitmask |= (1U << LCD_D7) | (1U << LCD_D6);
121 data_length_bitmask |= (1U << LCD_D5) | (1U << LCD_D4);
125 LCD_DATA_DDR |= data_length_bitmask;
128 _delay_ms(POWER_RAMP_DELAY_MS);
132 byte |= FUNCTION_SET;
135 for (uint8_t count = 0; count < 3; ++count)
138 _delay_ms(LONG_INSTR_DELAY_MS);
142 byte |= FUNCTION_SET;
150 byte |= (DISPLAY_OFF << ON_OFF_CTRL_BIT);
151 byte |= (p_config_local->
cursor_enable << CURSOR_ENABLE_BIT);
152 byte |= (p_config_local->
blink_enable << BLINK_ENABLE_BIT);
156 byte |= CLEAR_DISPLAY;
160 byte |= ENTRY_MODE_SET;
162 byte |= (p_config_local->
display_shift << DISPLAY_SHIFT_BIT);
167 byte |= (DISPLAY_ON << ON_OFF_CTRL_BIT);
168 byte |= (p_config_local->
cursor_enable << CURSOR_ENABLE_BIT);
169 byte |= (p_config_local->
blink_enable << BLINK_ENABLE_BIT);
182 byte |= (p_config_local->
cursor_enable << CURSOR_ENABLE_BIT);
183 byte |= (p_config_local->
blink_enable << BLINK_ENABLE_BIT);
195 byte |= (DISPLAY_ON << ON_OFF_CTRL_BIT);
196 byte |= (p_config_local->
cursor_enable << CURSOR_ENABLE_BIT);
197 byte |= (p_config_local->
blink_enable << BLINK_ENABLE_BIT);
207 for (uint8_t index = 0; str[index] != 0; ++index)
209 lcd_char(str[index]);
231 str[count] = (digit +
'0');
238 lcd_char(str[count - 1]);
258 address = (column + 64);
262 lcd_command(address);
273 for (uint8_t count = 0; count < 16; ++count)
281 for (uint8_t count = 0; count < 16; ++count)
295 byte |= ENTRY_MODE_SET;
297 byte |= (p_config_local->
display_shift << DISPLAY_SHIFT_BIT);
311 lcd_command(CURSOR_HOME);
312 _delay_ms(SHORT_INSTR_DELAY_MS);
322 byte |= CURSOR_DISPLAY_SHIFT;
324 for (uint8_t count = 0; count < distance; ++count)
337 byte |= CURSOR_DISPLAY_SHIFT;
338 byte |= (1U << RIGHT_LEFT_BIT);
340 for (uint8_t count = 0; count < distance; ++count)
353 byte |= CURSOR_DISPLAY_SHIFT;
354 byte |= (1U << SHIFT_OR_CURSOR_BIT);
356 for (uint8_t count = 0; count < distance; ++count)
361 _delay_ms(SCROLL_DELAY_MS);
373 byte |= CURSOR_DISPLAY_SHIFT;
374 byte |= (1U << SHIFT_OR_CURSOR_BIT);
375 byte |= (1U << RIGHT_LEFT_BIT);
377 for (uint8_t count = 0; count < distance; ++count)
382 _delay_ms(SCROLL_DELAY_MS);
396void lcd_command(uint8_t data)
398 LCD_CTRL_PORT &= ~(1U << LCD_RS);
402 LCD_DATA_PORT = data;
409 LCD_DATA_PORT &= ~(data_length_bitmask);
410 byte = (data & 0b11110000);
411 byte = (
byte >> (7U - LCD_D7));
412 LCD_DATA_PORT |= byte;
415 LCD_DATA_PORT &= ~(data_length_bitmask);
416 byte = (data & 0b00001111);
417 byte = (
byte << (LCD_D7 - 3U));
418 LCD_DATA_PORT |= byte;
421 _delay_ms(SHORT_INSTR_DELAY_MS);
428void lcd_char(
char character)
430 LCD_CTRL_PORT |= (1U << LCD_RS);
434 LCD_DATA_PORT = character;
441 LCD_DATA_PORT &= ~(data_length_bitmask);
442 byte = (character & 0b11110000);
443 byte = (
byte >> (7U - LCD_D7));
444 LCD_DATA_PORT |= byte;
447 LCD_DATA_PORT &= ~(data_length_bitmask);
448 byte = (character & 0b00001111);
449 byte = (
byte << (LCD_D7 - 3U));
450 LCD_DATA_PORT |= byte;
453 _delay_ms(SHORT_INSTR_DELAY_MS);
460void pulse_enable(
void)
462 LCD_CTRL_PORT |= (1U << LCD_EN);
463 _delay_us(ENABLE_DELAY_US);
464 LCD_CTRL_PORT &= ~(1U << LCD_EN);
465 _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.