From a9b4431d67bebe8bb44d937e30179224b1a51f27 Mon Sep 17 00:00:00 2001 From: "Christian L. V. Madsen" Date: Wed, 18 Jun 2025 16:15:19 +0200 Subject: [PATCH] works now and is tested.. but needs cleanup!! --- lcd_hd44780.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++--- lcd_hd44780.h | 6 +++++ 2 files changed, 68 insertions(+), 3 deletions(-) diff --git a/lcd_hd44780.c b/lcd_hd44780.c index 63cca46..1a880e1 100644 --- a/lcd_hd44780.c +++ b/lcd_hd44780.c @@ -72,14 +72,12 @@ static int lcd_write_8bit(cm_lcd_hd44780_t *inst, uint8_t dataOrCmd, hd44780_Ins // Then Clock data in with E pin. Data is clocked on Falling edge: inst->gpio_data.e_pin = 0; inst->setGetGpio_event(&(inst->gpio_data),LCD_HD44780_SET); - // Wait until display is ready: WaitUntilReady(inst); // Then set E pin high so its ready for next time: inst->gpio_data.e_pin = 1; inst->setGetGpio_event(&(inst->gpio_data),LCD_HD44780_SET); - return 0; } @@ -101,15 +99,74 @@ static void lcd_writeCmd_disp(cm_lcd_hd44780_t *inst, hd44780_cmd_t cmd, hd44780 } +void lcd_hd44780_printChar(cm_lcd_hd44780_t *inst, char character) { + if (inst->bit_mode == LCD_HD44780_BITMODE_8BIT) { + lcd_write_8bit(inst, character, LCD_HD44780_DATA); + } else { + // Write MSB first + lcd_write_8bit(inst, ((character >> 4) & 0x0F) << 4, LCD_HD44780_DATA); + // Then LSB + lcd_write_8bit(inst, (character & 0x0F) << 4, LCD_HD44780_DATA); + } +} + +void lcd_hd44780_printf(cm_lcd_hd44780_t *inst, char *string) { + while (*string) { + lcd_hd44780_printChar(inst, *string++); + } +} + +void lcd_hd44780_print_xy(cm_lcd_hd44780_t *inst, uint8_t x, uint8_t y, const char *str) { + // Base DDRAM addresses for each row (for 2-line display) + const uint8_t row_offsets[] = {0x00, 0x40, 0x14, 0x54}; // for 4-line displays + + if (y > 3) return; // Prevent invalid row access + + // Set DDRAM address command: 0x80 | (offset + x) + lcd_writeCmd_disp(inst, 0x80 | (row_offsets[y] + x), LCD_HD44780_SET); + + // Write characters + while (*str) { + lcd_hd44780_printChar(inst, *str++); + } +} + +void lcd_hd44780_cursorHome(cm_lcd_hd44780_t *inst) { + lcd_writeCmd_disp(inst, LCD_HD44780_RETURN_HOME, LCD_HD44780_SET); +} + +void lcd_hd44780_clearDisp(cm_lcd_hd44780_t *inst) { + + lcd_writeCmd_disp(inst, LCD_HD44780_CLEAR_DISP, LCD_HD44780_SET); + + // Wait for the command to finish. + // This is a long operation (? 1.53 ms), so if not polling BF, delay at least 2 ms. + if (!inst->isInit) { + inst->wait_event(2); + } else { + WaitUntilReady(inst); + } +} + + void lcd_hd44780_initDisp(cm_lcd_hd44780_t *inst){ // Make sure E pin is high when data isnt ready on BUS! inst->gpio_data.e_pin = 1; inst->setGetGpio_event(&(inst->gpio_data),LCD_HD44780_SET); + inst->wait_event(1); // Wait for more than 15ms after VCC rise.. inst->wait_event(15); lcd_writeCmd_disp(inst, LCD_HD44780_FUNCTION_SET,LCD_HD44780_SET); + + // Init display to 4 bit mode if selected! + if(inst->bit_mode == LCD_HD44780_BITMODE_4BIT){ + + lcd_write_8bit(inst, 0x20, LCD_HD44780_INSTRUCTION); + inst->wait_event(1); // Small delay + } + // Wait for 4.1ms.. // Delay(4) @@ -123,7 +180,7 @@ void lcd_hd44780_initDisp(cm_lcd_hd44780_t *inst){ lcd_writeCmd_disp(inst, LCD_HD44780_ENTRY_MODE,LCD_HD44780_SET); // Init has been done, and we can now use Busy Flag polling instead of delay! - inst->isInit = 0x1; + //inst->isInit = 0x1; } @@ -150,6 +207,8 @@ void lcd_hd44780_init(cm_lcd_hd44780_t *inst, lcd_hd44780_bitmode bit_mode){ inst->bit_mode = bit_mode; lcd_hd44780_initDisp(inst); + + lcd_hd44780_clearDisp(inst); return; } diff --git a/lcd_hd44780.h b/lcd_hd44780.h index f32f126..1d847e7 100644 --- a/lcd_hd44780.h +++ b/lcd_hd44780.h @@ -23,9 +23,11 @@ typedef enum { LCD_HD44780_RETURN_HOME = 0x2, LCD_HD44780_ENTRY_MODE = 0x6, LCD_HD44780_DISP_ONOFF_CTL = 0xE, + LCD_HD44780_DISPLAY_ON_CURSOR_ON_BLINK_ON = 0x0F, LCD_HD44780_CURSOR_SHIFT = 0x6, LCD_HD44780_FUNCTION_SET = 0x30, + }hd44780_cmd_t; typedef enum{ @@ -86,5 +88,9 @@ typedef struct{ void lcd_hd44780_init(cm_lcd_hd44780_t *inst,lcd_hd44780_bitmode bit_mode); void lcd_hd44780_regGpioEvt(cm_lcd_hd44780_t *inst, setGet_Gpio_Event_fpt getGpioEvt_fpt); void lcd_hd44780_regWaitEvt(cm_lcd_hd44780_t *inst, wait_ms_Event_fpt waitEvt_fpt); +void lcd_hd44780_cursorHome(cm_lcd_hd44780_t *inst); +void lcd_hd44780_printf(cm_lcd_hd44780_t *inst, char *string); +void lcd_hd44780_clearDisp(cm_lcd_hd44780_t *inst); +void lcd_hd44780_print_xy(cm_lcd_hd44780_t *inst, uint8_t x, uint8_t y, const char *str); #endif /*LCD_HD44780_H_*/