AVRly - AVR Development Resources
hd44780_lcd.h File Reference

Driver for the HD44780 based 16x2 liquid crystal display. More...

#include <stdint.h>
#include <stdbool.h>

Go to the source code of this file.

Classes

struct  lcd_config_t
 Configuration struct, to be instantiated and values assigned before passing it's address into and calling lcd_init(). More...
 

Functions

void init_lcd (lcd_config_t *p_config)
 Initialisation routine (run once at startup). More...
 
void lcd_display_off (void)
 Turn display off (config settings are retained). More...
 
void lcd_display_on (void)
 Turn display on. More...
 
void lcd_print_string (const char *str)
 Prints a string of characters to the display. More...
 
void lcd_print_integer (int16_t number)
 Prints an integer variable. More...
 
void lcd_set_cursor (uint8_t column, uint8_t row)
 Sets cursor location using x and y coordinates. More...
 
void lcd_fast_clear (void)
 Writes space characters to all 32 sections of display (or 16 if in 1 line mode). More...
 
void lcd_reconfigure (void)
 Edits config settings on the display (lcd_config_t members must be changed first). More...
 
void lcd_return_home (void)
 Sets DDRAM address 0 in address counter. More...
 
void lcd_shift_cursor_left (uint8_t distance)
 Moves cursor left without changing DDRAM contents. More...
 
void lcd_shift_cursor_right (uint8_t distance)
 Moves cursor right without changing DDRAM contents. More...
 
void lcd_shift_display_left (uint8_t distance, bool delay)
 Shifts display left without changing DDRAM contents. More...
 
void lcd_shift_display_right (uint8_t distance, bool delay)
 Shifts display right without changing DDRAM contents. More...
 

Detailed Description

Driver for the HD44780 based 16x2 liquid crystal display.

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Author
Jason Duffy
Date
1st March 2022

This file provides the basic low-level functionality for the ubiquitous 16x2 display. Please note that it uses long blocking waits in the initialisation routine (100ms), and short blocking waits in other utility functions (2uS - 2mS). This was done to simplify the code as the busy flag read introduced pitfalls. This driver currently only allows for a single display to be used, but this might be improved on at a later date.

This driver was written using the datasheet for the HITACHI HD44780U LCD driver chip, which can be found at the link below.

See also
http://www.datasheet-pdf.com/PDF/HD44780U-Datasheet-Hitachi-1109874

Definition in file hd44780_lcd.h.

Function Documentation

◆ init_lcd()

void init_lcd ( lcd_config_t p_config)

Initialisation routine (run once at startup).

This function is to be called immediately after powerup of the display module. Instantiate the lcd_config_t object first then pass it's address into init_lcd() before using any other lcd functions.

Parameters
p_configis a pointer to the lcd_config_t object.
Returns
Returns void.

Definition at line 105 of file hd44780_lcd.c.

106{
107 // copy address of config object pointer to a local pointer
108 p_config_local = p_config;
109
110 // Set data direction registers to output where applicable
111 LCD_CTRL_DDR |= (1U << LCD_RS) | (1U << LCD_EN);
112
113 // Test for bit mode and set appropriate bitmask
114 if (p_config_local->eight_bit_mode)
115 {
116 data_length_bitmask = 0xff; // 0b11111111
117 }
118 else
119 {
120 data_length_bitmask |= (1U << LCD_D7) | (1U << LCD_D6);
121 data_length_bitmask |= (1U << LCD_D5) | (1U << LCD_D4);
122 }
123
124 // Set relevant lcd data port direction to output
125 LCD_DATA_DDR |= data_length_bitmask;
126
127 // Delay to allow power ramp up in LCD controller
128 _delay_ms(POWER_RAMP_DELAY_MS);
129
130 // Begin initialising HD44780
131 uint8_t byte = 0;
132 byte |= FUNCTION_SET;
133 byte |= (p_config_local->eight_bit_mode << DATA_LENGTH_BIT);
134
135 for (uint8_t count = 0; count < 3; ++count)
136 {
137 lcd_command(byte);
138 _delay_ms(LONG_INSTR_DELAY_MS);
139 }
140
141 byte = 0;
142 byte |= FUNCTION_SET;
143 byte |= (p_config_local->eight_bit_mode << DATA_LENGTH_BIT);
144 byte |= (p_config_local->two_line_display << DISPLAY_LINES_BIT);
145 byte |= (p_config_local->five_by_ten_font << FONT_SIZE_BIT);
146 lcd_command(byte);
147
148 byte = 0;
149 byte |= ON_OFF_CTRL;
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);
153 lcd_command(byte);
154
155 byte = 0;
156 byte |= CLEAR_DISPLAY;
157 lcd_command(byte);
158
159 byte = 0;
160 byte |= ENTRY_MODE_SET;
161 byte |= (p_config_local->increment_counter << MOVE_DIRECTION_BIT);
162 byte |= (p_config_local->display_shift << DISPLAY_SHIFT_BIT);
163 lcd_command(byte);
164
165 byte = 0;
166 byte |= ON_OFF_CTRL;
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);
170 lcd_command(byte);
172}
void lcd_return_home(void)
Sets DDRAM address 0 in address counter.
Definition: hd44780_lcd.c:309
bool display_shift
true = display shift, false = cursor shift.
Definition: hd44780_lcd.h:62
bool cursor_enable
true = enabled, false = disabled.
Definition: hd44780_lcd.h:63
bool eight_bit_mode
true = 8 bit mode, false = 4 bit mode.
Definition: hd44780_lcd.h:58
bool increment_counter
true = increment, false = decrement.
Definition: hd44780_lcd.h:61
bool blink_enable
true = enabled, false = disabled.
Definition: hd44780_lcd.h:64
bool five_by_ten_font
true = 5x10 dots, false = 5x8 dots.
Definition: hd44780_lcd.h:60
bool two_line_display
true = 2 lines, false = 1 line.
Definition: hd44780_lcd.h:59

◆ lcd_display_off()

void lcd_display_off ( void  )

Turn display off (config settings are retained).

Side effect: cursor_enable and blink_enable variable states are written to the display during this command, so if they have been changed but lcd_reconfigure() was not called afterwards, this function will update those config bits on the display.

Returns
Returns void.

Definition at line 178 of file hd44780_lcd.c.

179{
180 uint8_t byte = 0;
181 byte |= ON_OFF_CTRL; // Default is off
182 byte |= (p_config_local->cursor_enable << CURSOR_ENABLE_BIT);
183 byte |= (p_config_local->blink_enable << BLINK_ENABLE_BIT);
184 lcd_command(byte);
185}

◆ lcd_display_on()

void lcd_display_on ( void  )

Turn display on.

Side effect: cursor_enable and blink_enable variable states are written to the display during this command, so if they have been changed but lcd_reconfigure() was not called afterwards, this function will update those config bits on the display.

Returns
Returns void.

Definition at line 191 of file hd44780_lcd.c.

192{
193 uint8_t byte = 0;
194 byte |= ON_OFF_CTRL;
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);
198 lcd_command(byte);
199}

◆ lcd_print_string()

void lcd_print_string ( const char *  str)

Prints a string of characters to the display.

This function takes a string literal (constant) as it's parameter. Be sure to enclose text passed in with "" quotation marks. eg: "Hello, World!".

Parameters
stris a string literal.
Returns
Returns void.

Definition at line 205 of file hd44780_lcd.c.

206{
207 for (uint8_t index = 0; str[index] != 0; ++index)
208 {
209 lcd_char(str[index]);
210 }
211}

◆ lcd_print_integer()

void lcd_print_integer ( int16_t  number)

Prints an integer variable.

This function prints a signed integer value to the display, values from -32768 to 32767 are acceptable.

Parameters
numberis a signed, fixed width integer.
Returns
Returns void.

Definition at line 217 of file hd44780_lcd.c.

218{
219 if (number < 0)
220 {
221 lcd_char('-');
222 }
223
224 uint8_t count = 0;
225 uint8_t digit = 0;
226 char str[20];
227
228 while (number > 0)
229 {
230 digit = number % 10;
231 str[count] = (digit + '0');
232 ++count;
233 number /= 10;
234 }
235
236 while (count > 0)
237 {
238 lcd_char(str[count - 1]);
239 --count;
240 }
241}

◆ lcd_set_cursor()

void lcd_set_cursor ( uint8_t  column,
uint8_t  row 
)

Sets cursor location using x and y coordinates.

Column is 0 for top row, 1 for bottom row (in 2 row mode). Row can be from 0 - 15, values outside of this range will be written to non visible spaces on the display.

Parameters
columnis the x coordinate.
rowis the y coordinate.
Returns
Returns void.

Definition at line 247 of file hd44780_lcd.c.

248{
249 uint8_t address = 0;
250
251 if (row == 0)
252 {
253 address = column;
254 }
255
256 else if (row == 1)
257 {
258 address = (column + 64);
259 }
260
261 address |= 0x80U; // Write 1 to MSB
262 lcd_command(address);
263}

◆ lcd_fast_clear()

void lcd_fast_clear ( void  )

Writes space characters to all 32 sections of display (or 16 if in 1 line mode).

This is much faster than the clear_display command, as that works by writing a space character to every single section of the display, even all the non-visible ones.

Returns
Returns void.

Definition at line 270 of file hd44780_lcd.c.

271{
272 lcd_set_cursor(0,0);
273 for (uint8_t count = 0; count < 16; ++count)
274 {
275 lcd_char(' ');
276 }
277
278 if (p_config_local->two_line_display)
279 {
280 lcd_set_cursor(0,1);
281 for (uint8_t count = 0; count < 16; ++count)
282 {
283 lcd_char(' ');
284 }
285 }
286}
void lcd_set_cursor(uint8_t column, uint8_t row)
Sets cursor location using x and y coordinates.
Definition: hd44780_lcd.c:247

◆ lcd_reconfigure()

void lcd_reconfigure ( void  )

Edits config settings on the display (lcd_config_t members must be changed first).

data_length, display_lines, and font_size cannot be changed after init_lcd() is called.

Returns
Returns void.

Definition at line 292 of file hd44780_lcd.c.

293{
294 uint8_t byte = 0;
295 byte |= ENTRY_MODE_SET;
296 byte |= (p_config_local->increment_counter << MOVE_DIRECTION_BIT);
297 byte |= (p_config_local->display_shift << DISPLAY_SHIFT_BIT);
298 lcd_command(byte);
299
300 // Also resends cursor and blink settings
302}
void lcd_display_on(void)
Turn display on.
Definition: hd44780_lcd.c:191

◆ lcd_return_home()

void lcd_return_home ( void  )

Sets DDRAM address 0 in address counter.

Also returns display from being shifted to original position. DDRAM contents remain unchanged.

Returns
Returns void.

Definition at line 309 of file hd44780_lcd.c.

310{
311 lcd_command(CURSOR_HOME);
312 _delay_ms(SHORT_INSTR_DELAY_MS);
313}

◆ lcd_shift_cursor_left()

void lcd_shift_cursor_left ( uint8_t  distance)

Moves cursor left without changing DDRAM contents.

Parameters
distanceis used to specify how many spaces to move.
Returns
Returns void.

Definition at line 319 of file hd44780_lcd.c.

320{
321 uint8_t byte = 0;
322 byte |= CURSOR_DISPLAY_SHIFT;
323
324 for (uint8_t count = 0; count < distance; ++count)
325 {
326 lcd_command(byte);
327 }
328}

◆ lcd_shift_cursor_right()

void lcd_shift_cursor_right ( uint8_t  distance)

Moves cursor right without changing DDRAM contents.

Parameters
distanceis used to specify how many spaces to move.
Returns
Returns void.

Definition at line 334 of file hd44780_lcd.c.

335{
336 uint8_t byte = 0;
337 byte |= CURSOR_DISPLAY_SHIFT;
338 byte |= (1U << RIGHT_LEFT_BIT);
339
340 for (uint8_t count = 0; count < distance; ++count)
341 {
342 lcd_command(byte);
343 }
344}

◆ lcd_shift_display_left()

void lcd_shift_display_left ( uint8_t  distance,
bool  delay 
)

Shifts display left without changing DDRAM contents.

Optional delay between shifts for scrolling effect.

Parameters
distanceis used to specify how many spaces to move.
delay- pass in true for scrolling effect, false for no delay.
Returns
Returns void.

Definition at line 350 of file hd44780_lcd.c.

351{
352 uint8_t byte = 0U;
353 byte |= CURSOR_DISPLAY_SHIFT;
354 byte |= (1U << SHIFT_OR_CURSOR_BIT);
355
356 for (uint8_t count = 0; count < distance; ++count)
357 {
358 lcd_command(byte);
359 if (delay == true)
360 {
361 _delay_ms(SCROLL_DELAY_MS);
362 }
363 }
364}

◆ lcd_shift_display_right()

void lcd_shift_display_right ( uint8_t  distance,
bool  delay 
)

Shifts display right without changing DDRAM contents.

Optional delay between shifts for scrolling effect.

Parameters
distanceis used to specify how many spaces to move.
delay- pass in true for scrolling effect, false for no delay.
Returns
Returns void.

Definition at line 370 of file hd44780_lcd.c.

371{
372 uint8_t byte = 0;
373 byte |= CURSOR_DISPLAY_SHIFT;
374 byte |= (1U << SHIFT_OR_CURSOR_BIT);
375 byte |= (1U << RIGHT_LEFT_BIT);
376
377 for (uint8_t count = 0; count < distance; ++count)
378 {
379 lcd_command(byte);
380 if (delay == true)
381 {
382 _delay_ms(SCROLL_DELAY_MS);
383 }
384 }
385}