diff --git a/lib/hd44780_111/hd44780.c b/lib/hd44780_111/hd44780.c old mode 100755 new mode 100644 index 0e1dda7..e4a1efd --- a/lib/hd44780_111/hd44780.c +++ b/lib/hd44780_111/hd44780.c @@ -1,738 +1,772 @@ -/***************************************************************************** -Title : HD44780 Library -Author : SA Development -Version: 1.11 -*****************************************************************************/ - -#include -#include -#include -#define __ASSERT_USE_STDERR -#include -#include "hd44780.h" -#include "hd44780_settings.h" - - -#if (USE_ADELAY_LIBRARY==1) - #include "adelay.h" -#else - #define Delay_ns(__ns) \ - if((unsigned long) (F_CPU/1000000000.0 * __ns) != F_CPU/1000000000.0 * __ns)\ - __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000000.0 * __ns)+1);\ - else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000000.0 * __ns)) - #define Delay_us(__us) \ - if((unsigned long) (F_CPU/1000000.0 * __us) != F_CPU/1000000.0 * __us)\ - __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000.0 * __us)+1);\ - else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000.0 * __us)) - #define Delay_ms(__ms) \ - if((unsigned long) (F_CPU/1000.0 * __ms) != F_CPU/1000.0 * __ms)\ - __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000.0 * __ms)+1);\ - else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000.0 * __ms)) - #define Delay_s(__s) \ - if((unsigned long) (F_CPU/1.0 * __s) != F_CPU/1.0 * __s)\ - __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1.0 * __s)+1);\ - else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1.0 * __s)) -#endif - -#if !defined(LCD_BITS) || (LCD_BITS!=4 && LCD_BITS!=8) - #error LCD_BITS is not defined or not valid. -#endif - -#if !defined(WAIT_MODE) || (WAIT_MODE!=0 && WAIT_MODE!=1) - #error WAIT_MODE is not defined or not valid. -#endif - -#if !defined(RW_LINE_IMPLEMENTED) || (RW_LINE_IMPLEMENTED!=0 && RW_LINE_IMPLEMENTED!=1) - #error RW_LINE_IMPLEMENTED is not defined or not valid. -#endif - -#if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED!=1) - #error WAIT_MODE=1 requires RW_LINE_IMPLEMENTED=1. -#endif - -#if !defined(LCD_DISPLAYS) || (LCD_DISPLAYS<1) || (LCD_DISPLAYS>4) - #error LCD_DISPLAYS is not defined or not valid. -#endif - -// Constants/Macros -#define PIN(x) (*(&x - 2)) // Address of Data Direction Register of Port X -#define DDR(x) (*(&x - 1)) // Address of Input Register of Port X - -//PORT defines -#define lcd_rs_port_low() LCD_RS_PORT&=~_BV(LCD_RS_PIN) -#if RW_LINE_IMPLEMENTED==1 - #define lcd_rw_port_low() LCD_RW_PORT&=~_BV(LCD_RW_PIN) -#endif -#define lcd_db0_port_low() LCD_DB0_PORT&=~_BV(LCD_DB0_PIN) -#define lcd_db1_port_low() LCD_DB1_PORT&=~_BV(LCD_DB1_PIN) -#define lcd_db2_port_low() LCD_DB2_PORT&=~_BV(LCD_DB2_PIN) -#define lcd_db3_port_low() LCD_DB3_PORT&=~_BV(LCD_DB3_PIN) -#define lcd_db4_port_low() LCD_DB4_PORT&=~_BV(LCD_DB4_PIN) -#define lcd_db5_port_low() LCD_DB5_PORT&=~_BV(LCD_DB5_PIN) -#define lcd_db6_port_low() LCD_DB6_PORT&=~_BV(LCD_DB6_PIN) -#define lcd_db7_port_low() LCD_DB7_PORT&=~_BV(LCD_DB7_PIN) - -#define lcd_rs_port_high() LCD_RS_PORT|=_BV(LCD_RS_PIN) -#if RW_LINE_IMPLEMENTED==1 - #define lcd_rw_port_high() LCD_RW_PORT|=_BV(LCD_RW_PIN) -#endif -#define lcd_db0_port_high() LCD_DB0_PORT|=_BV(LCD_DB0_PIN) -#define lcd_db1_port_high() LCD_DB1_PORT|=_BV(LCD_DB1_PIN) -#define lcd_db2_port_high() LCD_DB2_PORT|=_BV(LCD_DB2_PIN) -#define lcd_db3_port_high() LCD_DB3_PORT|=_BV(LCD_DB3_PIN) -#define lcd_db4_port_high() LCD_DB4_PORT|=_BV(LCD_DB4_PIN) -#define lcd_db5_port_high() LCD_DB5_PORT|=_BV(LCD_DB5_PIN) -#define lcd_db6_port_high() LCD_DB6_PORT|=_BV(LCD_DB6_PIN) -#define lcd_db7_port_high() LCD_DB7_PORT|=_BV(LCD_DB7_PIN) - -#define lcd_rs_port_set(value) if (value) lcd_rs_port_high(); else lcd_rs_port_low(); -#if RW_LINE_IMPLEMENTED==1 - #define lcd_rw_port_set(value) if (value) lcd_rw_port_high(); else lcd_rw_port_low(); -#endif -#define lcd_db0_port_set(value) if (value) lcd_db0_port_high(); else lcd_db0_port_low(); -#define lcd_db1_port_set(value) if (value) lcd_db1_port_high(); else lcd_db1_port_low(); -#define lcd_db2_port_set(value) if (value) lcd_db2_port_high(); else lcd_db2_port_low(); -#define lcd_db3_port_set(value) if (value) lcd_db3_port_high(); else lcd_db3_port_low(); -#define lcd_db4_port_set(value) if (value) lcd_db4_port_high(); else lcd_db4_port_low(); -#define lcd_db5_port_set(value) if (value) lcd_db5_port_high(); else lcd_db5_port_low(); -#define lcd_db6_port_set(value) if (value) lcd_db6_port_high(); else lcd_db6_port_low(); -#define lcd_db7_port_set(value) if (value) lcd_db7_port_high(); else lcd_db7_port_low(); - -//PIN defines -#define lcd_db0_pin_get() (((PIN(LCD_DB0_PORT) & _BV(LCD_DB0_PIN))==0)?0:1) -#define lcd_db1_pin_get() (((PIN(LCD_DB1_PORT) & _BV(LCD_DB1_PIN))==0)?0:1) -#define lcd_db2_pin_get() (((PIN(LCD_DB2_PORT) & _BV(LCD_DB2_PIN))==0)?0:1) -#define lcd_db3_pin_get() (((PIN(LCD_DB3_PORT) & _BV(LCD_DB3_PIN))==0)?0:1) -#define lcd_db4_pin_get() (((PIN(LCD_DB4_PORT) & _BV(LCD_DB4_PIN))==0)?0:1) -#define lcd_db5_pin_get() (((PIN(LCD_DB5_PORT) & _BV(LCD_DB5_PIN))==0)?0:1) -#define lcd_db6_pin_get() (((PIN(LCD_DB6_PORT) & _BV(LCD_DB6_PIN))==0)?0:1) -#define lcd_db7_pin_get() (((PIN(LCD_DB7_PORT) & _BV(LCD_DB7_PIN))==0)?0:1) - -//DDR defines -#define lcd_rs_ddr_low() DDR(LCD_RS_PORT)&=~_BV(LCD_RS_PIN) -#if RW_LINE_IMPLEMENTED==1 - #define lcd_rw_ddr_low() DDR(LCD_RW_PORT)&=~_BV(LCD_RW_PIN) -#endif -#define lcd_db0_ddr_low() DDR(LCD_DB0_PORT)&=~_BV(LCD_DB0_PIN) -#define lcd_db1_ddr_low() DDR(LCD_DB1_PORT)&=~_BV(LCD_DB1_PIN) -#define lcd_db2_ddr_low() DDR(LCD_DB2_PORT)&=~_BV(LCD_DB2_PIN) -#define lcd_db3_ddr_low() DDR(LCD_DB3_PORT)&=~_BV(LCD_DB3_PIN) -#define lcd_db4_ddr_low() DDR(LCD_DB4_PORT)&=~_BV(LCD_DB4_PIN) -#define lcd_db5_ddr_low() DDR(LCD_DB5_PORT)&=~_BV(LCD_DB5_PIN) -#define lcd_db6_ddr_low() DDR(LCD_DB6_PORT)&=~_BV(LCD_DB6_PIN) -#define lcd_db7_ddr_low() DDR(LCD_DB7_PORT)&=~_BV(LCD_DB7_PIN) - -#define lcd_rs_ddr_high() DDR(LCD_RS_PORT)|=_BV(LCD_RS_PIN) -#if RW_LINE_IMPLEMENTED==1 - #define lcd_rw_ddr_high() DDR(LCD_RW_PORT)|=_BV(LCD_RW_PIN) -#endif -#define lcd_db0_ddr_high() DDR(LCD_DB0_PORT)|=_BV(LCD_DB0_PIN) -#define lcd_db1_ddr_high() DDR(LCD_DB1_PORT)|=_BV(LCD_DB1_PIN) -#define lcd_db2_ddr_high() DDR(LCD_DB2_PORT)|=_BV(LCD_DB2_PIN) -#define lcd_db3_ddr_high() DDR(LCD_DB3_PORT)|=_BV(LCD_DB3_PIN) -#define lcd_db4_ddr_high() DDR(LCD_DB4_PORT)|=_BV(LCD_DB4_PIN) -#define lcd_db5_ddr_high() DDR(LCD_DB5_PORT)|=_BV(LCD_DB5_PIN) -#define lcd_db6_ddr_high() DDR(LCD_DB6_PORT)|=_BV(LCD_DB6_PIN) -#define lcd_db7_ddr_high() DDR(LCD_DB7_PORT)|=_BV(LCD_DB7_PIN) - -#define lcd_rs_ddr_set(value) if (value) lcd_rs_ddr_high(); else lcd_rs_ddr_low(); -#if RW_LINE_IMPLEMENTED==1 - #define lcd_rw_ddr_set(value) if (value) lcd_rw_ddr_high(); else lcd_rw_ddr_low(); -#endif -#define lcd_db0_ddr_set(value) if (value) lcd_db0_ddr_high(); else lcd_db0_ddr_low(); -#define lcd_db1_ddr_set(value) if (value) lcd_db1_ddr_high(); else lcd_db1_ddr_low(); -#define lcd_db2_ddr_set(value) if (value) lcd_db2_ddr_high(); else lcd_db2_ddr_low(); -#define lcd_db3_ddr_set(value) if (value) lcd_db3_ddr_high(); else lcd_db3_ddr_low(); -#define lcd_db4_ddr_set(value) if (value) lcd_db4_ddr_high(); else lcd_db4_ddr_low(); -#define lcd_db5_ddr_set(value) if (value) lcd_db5_ddr_high(); else lcd_db5_ddr_low(); -#define lcd_db6_ddr_set(value) if (value) lcd_db6_ddr_high(); else lcd_db6_ddr_low(); -#define lcd_db7_ddr_set(value) if (value) lcd_db7_ddr_high(); else lcd_db7_ddr_low(); - -#if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) -static unsigned char PrevCmdInvolvedAddressCounter=0; -#endif - -#if (LCD_DISPLAYS>1) -static unsigned char ActiveDisplay=1; -#endif - -static inline void lcd_e_port_low() -{ - #if (LCD_DISPLAYS>1) - switch (ActiveDisplay) - { - case 2 : LCD_E2_PORT&=~_BV(LCD_E2_PIN); - break; - #if (LCD_DISPLAYS>=3) - case 3 : LCD_E3_PORT&=~_BV(LCD_E3_PIN); - break; - #endif - #if (LCD_DISPLAYS==4) - case 4 : LCD_E4_PORT&=~_BV(LCD_E4_PIN); - break; - #endif - default : - #endif - LCD_E_PORT&=~_BV(LCD_E_PIN); - #if (LCD_DISPLAYS>1) - } - #endif -} - -static inline void lcd_e_port_high() -{ - #if (LCD_DISPLAYS>1) - switch (ActiveDisplay) - { - case 2 : LCD_E2_PORT|=_BV(LCD_E2_PIN); - break; - #if (LCD_DISPLAYS>=3) - case 3 : LCD_E3_PORT|=_BV(LCD_E3_PIN); - break; - #endif - #if (LCD_DISPLAYS==4) - case 4 : LCD_E4_PORT|=_BV(LCD_E4_PIN); - break; - #endif - default : - #endif - LCD_E_PORT|=_BV(LCD_E_PIN); - #if (LCD_DISPLAYS>1) - } - #endif -} - -static inline void lcd_e_ddr_low() -{ - #if (LCD_DISPLAYS>1) - switch (ActiveDisplay) - { - case 2 : DDR(LCD_E2_PORT)&=~_BV(LCD_E2_PIN); - break; - #if (LCD_DISPLAYS>=3) - case 3 : DDR(LCD_E3_PORT)&=~_BV(LCD_E3_PIN); - break; - #endif - #if (LCD_DISPLAYS==4) - case 4 : DDR(LCD_E4_PORT)&=~_BV(LCD_E4_PIN); - break; - #endif - default : - #endif - DDR(LCD_E_PORT)&=~_BV(LCD_E_PIN); - #if (LCD_DISPLAYS>1) - } - #endif -} - -static inline void lcd_e_ddr_high() -{ - #if (LCD_DISPLAYS>1) - switch (ActiveDisplay) - { - case 2 : DDR(LCD_E2_PORT)|=_BV(LCD_E2_PIN); - break; - #if (LCD_DISPLAYS>=3) - case 3 : DDR(LCD_E3_PORT)|=_BV(LCD_E3_PIN); - break; - #endif - #if (LCD_DISPLAYS==4) - case 4 : DDR(LCD_E4_PORT)|=_BV(LCD_E4_PIN); - break; - #endif - default : - #endif - DDR(LCD_E_PORT)|=_BV(LCD_E_PIN); - #if (LCD_DISPLAYS>1) - } - #endif -} - - -/************************************************************************* -loops while lcd is busy, returns address counter -*************************************************************************/ -#if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) -static uint8_t lcd_read(uint8_t rs); - -static void lcd_waitbusy(void) - { - register uint8_t c; - unsigned int ul1=0; - - while ( ((c=lcd_read(0)) & (1<=16)?F_CPU/16384:16)) // Wait Until Busy Flag is Cleared - ul1++; - } -#endif - - -/************************************************************************* -Low-level function to read byte from LCD controller -Input: rs 1: read data - 0: read busy flag / address counter -Returns: byte read from LCD controller -*************************************************************************/ -#if RW_LINE_IMPLEMENTED==1 -static uint8_t lcd_read(uint8_t rs) - { - uint8_t data; - - #if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) - if (rs) - lcd_waitbusy(); - if (PrevCmdInvolvedAddressCounter) - { - Delay_us(5); - PrevCmdInvolvedAddressCounter=0; - } - #endif - - if (rs) - { - lcd_rs_port_high(); // RS=1: Read Data - #if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) - PrevCmdInvolvedAddressCounter=1; - #endif - } - else lcd_rs_port_low(); // RS=0: Read Busy Flag - - - lcd_rw_port_high(); // RW=1: Read Mode - - #if LCD_BITS==4 - lcd_db7_ddr_low(); // Configure Data Pins as Input - lcd_db6_ddr_low(); - lcd_db5_ddr_low(); - lcd_db4_ddr_low(); - - lcd_e_port_high(); // Read High Nibble First - Delay_ns(500); - - data=lcd_db4_pin_get() << 4 | lcd_db5_pin_get() << 5 | - lcd_db6_pin_get() << 6 | lcd_db7_pin_get() << 7; - - lcd_e_port_low(); - Delay_ns(500); - - lcd_e_port_high(); // Read Low Nibble - Delay_ns(500); - - data|=lcd_db4_pin_get() << 0 | lcd_db5_pin_get() << 1 | - lcd_db6_pin_get() << 2 | lcd_db7_pin_get() << 3; - - lcd_e_port_low(); - - lcd_db7_ddr_high(); // Configure Data Pins as Output - lcd_db6_ddr_high(); - lcd_db5_ddr_high(); - lcd_db4_ddr_high(); - - lcd_db7_port_high(); // Pins High (Inactive) - lcd_db6_port_high(); - lcd_db5_port_high(); - lcd_db4_port_high(); - #else //using 8-Bit-Mode - lcd_db7_ddr_low(); // Configure Data Pins as Input - lcd_db6_ddr_low(); - lcd_db5_ddr_low(); - lcd_db4_ddr_low(); - lcd_db3_ddr_low(); - lcd_db2_ddr_low(); - lcd_db1_ddr_low(); - lcd_db0_ddr_low(); - - lcd_e_port_high(); - Delay_ns(500); - - data=lcd_db7_pin_get() << 7 | lcd_db6_pin_get() << 6 | - lcd_db5_pin_get() << 5 | lcd_db4_pin_get() << 4 | - lcd_db3_pin_get() << 3 | lcd_db2_pin_get() << 2 | - lcd_db1_pin_get() << 1 | lcd_db0_pin_get(); - - lcd_e_port_low(); - - lcd_db7_ddr_high(); // Configure Data Pins as Output - lcd_db6_ddr_high(); - lcd_db5_ddr_high(); - lcd_db4_ddr_high(); - lcd_db3_ddr_high(); - lcd_db2_ddr_high(); - lcd_db1_ddr_high(); - lcd_db0_ddr_high(); - - lcd_db7_port_high(); // Pins High (Inactive) - lcd_db6_port_high(); - lcd_db5_port_high(); - lcd_db4_port_high(); - lcd_db3_port_high(); - lcd_db2_port_high(); - lcd_db1_port_high(); - lcd_db0_port_high(); - #endif - - lcd_rw_port_low(); - - #if (WAIT_MODE==0 || RW_LINE_IMPLEMENTED==0) - if (rs) - Delay_us(40); - else Delay_us(1); - #endif - return data; - } - -uint8_t lcd_getc() - { - return lcd_read(1); - } - -#endif - -/************************************************************************* -Low-level function to write byte to LCD controller -Input: data byte to write to LCD - rs 1: write data - 0: write instruction -Returns: none -*************************************************************************/ -static void lcd_write(uint8_t data,uint8_t rs) - { - #if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) - lcd_waitbusy(); - if (PrevCmdInvolvedAddressCounter) - { - Delay_us(5); - PrevCmdInvolvedAddressCounter=0; - } - #endif - - if (rs) - { - lcd_rs_port_high(); // RS=1: Write Character - #if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) - PrevCmdInvolvedAddressCounter=1; - #endif - } - else - { - lcd_rs_port_low(); // RS=0: Write Command - #if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) - PrevCmdInvolvedAddressCounter=0; - #endif - } - - #if LCD_BITS==4 - lcd_db7_port_set(data&_BV(7)); //Output High Nibble - lcd_db6_port_set(data&_BV(6)); - lcd_db5_port_set(data&_BV(5)); - lcd_db4_port_set(data&_BV(4)); - - Delay_ns(100); - lcd_e_port_high(); - - Delay_ns(500); - lcd_e_port_low(); - - lcd_db7_port_set(data&_BV(3)); //Output High Nibble - lcd_db6_port_set(data&_BV(2)); - lcd_db5_port_set(data&_BV(1)); - lcd_db4_port_set(data&_BV(0)); - - Delay_ns(100); - lcd_e_port_high(); - - Delay_ns(500); - lcd_e_port_low(); - - lcd_db7_port_high(); // All Data Pins High (Inactive) - lcd_db6_port_high(); - lcd_db5_port_high(); - lcd_db4_port_high(); - - #else //using 8-Bit_Mode - lcd_db7_port_set(data&_BV(7)); //Output High Nibble - lcd_db6_port_set(data&_BV(6)); - lcd_db5_port_set(data&_BV(5)); - lcd_db4_port_set(data&_BV(4)); - lcd_db3_port_set(data&_BV(3)); //Output High Nibble - lcd_db2_port_set(data&_BV(2)); - lcd_db1_port_set(data&_BV(1)); - lcd_db0_port_set(data&_BV(0)); - - Delay_ns(100); - lcd_e_port_high(); - Delay_ns(500); - lcd_e_port_low(); - - lcd_db7_port_high(); // All Data Pins High (Inactive) - lcd_db6_port_high(); - lcd_db5_port_high(); - lcd_db4_port_high(); - lcd_db3_port_high(); - lcd_db2_port_high(); - lcd_db1_port_high(); - lcd_db0_port_high(); - #endif - - #if (WAIT_MODE==0 || RW_LINE_IMPLEMENTED==0) - if (!rs && data<=((1<1) - lcd_db7_port_high(); - #else - unsigned char c; - switch (ActiveDisplay) - { - case 1 : c=LCD_DISPLAY_LINES; break; - case 2 : c=LCD_DISPLAY2_LINES; break; - #if (LCD_DISPLAYS>=3) - case 3 : c=LCD_DISPLAY3_LINES; break; - #endif - #if (LCD_DISPLAYS==4) - case 4 : c=LCD_DISPLAY4_LINES; break; - #endif - } - if (c>1) - lcd_db7_port_high(); - #endif - - Delay_ns(100); - lcd_e_port_high(); - Delay_ns(500); - lcd_e_port_low(); - Delay_us(40); - #else - #if (LCD_DISPLAYS==1) - if (LCD_DISPLAY_LINES<2) - lcd_db3_port_low(); - #else - unsigned char c; - switch (ActiveDisplay) - { - case 1 : c=LCD_DISPLAY_LINES; break; - case 2 : c=LCD_DISPLAY2_LINES; break; - #if (LCD_DISPLAYS>=3) - case 3 : c=LCD_DISPLAY3_LINES; break; - #endif - #if (LCD_DISPLAYS==4) - case 4 : c=LCD_DISPLAY4_LINES; break; - #endif - } - if (c<2) - lcd_db3_port_low(); - #endif - - lcd_db2_port_low(); - Delay_ns(100); - lcd_e_port_high(); - Delay_ns(500); - lcd_e_port_low(); - Delay_us(40); - #endif - - //Display Off - lcd_command(_BV(LCD_DISPLAYMODE)); - - //Display Clear - lcd_clrscr(); - - //Entry Mode Set - lcd_command(_BV(LCD_ENTRY_MODE) | _BV(LCD_ENTRY_INC)); - - //Display On - lcd_command(_BV(LCD_DISPLAYMODE) | _BV(LCD_DISPLAYMODE_ON)); - } - -#if (LCD_DISPLAYS>1) -void lcd_use_display(int ADisplay) - { - if (ADisplay>=1 && ADisplay<=LCD_DISPLAYS) - ActiveDisplay=ADisplay; - } -#endif - - -/************************************************************************* -Clear characters at position until length -Input: start position and lentgh -Returns: none -*************************************************************************/ -void lcd_clr(uint8_t pos, uint8_t len) - { - for (int i = 0; i < len; i++) { - lcd_goto(pos + i); - lcd_putc(' '); - } - } - +/***************************************************************************** +Title : HD44780 Library +Author : SA Development +Version: 1.11 +Modifications for: Arduino Mega 2560 + Itead Studio Arduino 1602 LED Keypad Shield +Modified by: Silver Kits October 2016 +*****************************************************************************/ +#include +#include +#include +#define __ASSERT_USE_STDERR +#include +#include "hd44780.h" +#include "hd44780_settings.h" + + +#if (USE_ADELAY_LIBRARY==1) +#include "adelay.h" +#else +#define Delay_ns(__ns) \ + if((unsigned long) (F_CPU/1000000000.0 * __ns) != F_CPU/1000000000.0 * __ns)\ + __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000000.0 * __ns)+1);\ + else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000000.0 * __ns)) +#define Delay_us(__us) \ + if((unsigned long) (F_CPU/1000000.0 * __us) != F_CPU/1000000.0 * __us)\ + __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000.0 * __us)+1);\ + else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000000.0 * __us)) +#define Delay_ms(__ms) \ + if((unsigned long) (F_CPU/1000.0 * __ms) != F_CPU/1000.0 * __ms)\ + __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000.0 * __ms)+1);\ + else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1000.0 * __ms)) +#define Delay_s(__s) \ + if((unsigned long) (F_CPU/1.0 * __s) != F_CPU/1.0 * __s)\ + __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1.0 * __s)+1);\ + else __builtin_avr_delay_cycles((unsigned long) ( F_CPU/1.0 * __s)) +#endif + +#if !defined(LCD_BITS) || (LCD_BITS!=4 && LCD_BITS!=8) +#error LCD_BITS is not defined or not valid. +#endif + +#if !defined(WAIT_MODE) || (WAIT_MODE!=0 && WAIT_MODE!=1) +#error WAIT_MODE is not defined or not valid. +#endif + +#if !defined(RW_LINE_IMPLEMENTED) || (RW_LINE_IMPLEMENTED!=0 && RW_LINE_IMPLEMENTED!=1) +#error RW_LINE_IMPLEMENTED is not defined or not valid. +#endif + +#if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED!=1) +#error WAIT_MODE=1 requires RW_LINE_IMPLEMENTED=1. +#endif + +#if !defined(LCD_DISPLAYS) || (LCD_DISPLAYS<1) || (LCD_DISPLAYS>4) +#error LCD_DISPLAYS is not defined or not valid. +#endif + +// Constants/Macros +#define PIN(x) (*(&x - 2)) // Address of Data Direction Register of Port X +#define DDR(x) (*(&x - 1)) // Address of Input Register of Port X + +//PORT defines +#define lcd_rs_port_low() LCD_RS_PORT&=~_BV(LCD_RS_PIN) +#if RW_LINE_IMPLEMENTED==1 +#define lcd_rw_port_low() LCD_RW_PORT&=~_BV(LCD_RW_PIN) +#endif +#define lcd_db0_port_low() LCD_DB0_PORT&=~_BV(LCD_DB0_PIN) +#define lcd_db1_port_low() LCD_DB1_PORT&=~_BV(LCD_DB1_PIN) +#define lcd_db2_port_low() LCD_DB2_PORT&=~_BV(LCD_DB2_PIN) +#define lcd_db3_port_low() LCD_DB3_PORT&=~_BV(LCD_DB3_PIN) +#define lcd_db4_port_low() LCD_DB4_PORT&=~_BV(LCD_DB4_PIN) +#define lcd_db5_port_low() LCD_DB5_PORT&=~_BV(LCD_DB5_PIN) +#define lcd_db6_port_low() LCD_DB6_PORT&=~_BV(LCD_DB6_PIN) +#define lcd_db7_port_low() LCD_DB7_PORT&=~_BV(LCD_DB7_PIN) + +#define lcd_rs_port_high() LCD_RS_PORT|=_BV(LCD_RS_PIN) +#if RW_LINE_IMPLEMENTED==1 +#define lcd_rw_port_high() LCD_RW_PORT|=_BV(LCD_RW_PIN) +#endif +#define lcd_db0_port_high() LCD_DB0_PORT|=_BV(LCD_DB0_PIN) +#define lcd_db1_port_high() LCD_DB1_PORT|=_BV(LCD_DB1_PIN) +#define lcd_db2_port_high() LCD_DB2_PORT|=_BV(LCD_DB2_PIN) +#define lcd_db3_port_high() LCD_DB3_PORT|=_BV(LCD_DB3_PIN) +#define lcd_db4_port_high() LCD_DB4_PORT|=_BV(LCD_DB4_PIN) +#define lcd_db5_port_high() LCD_DB5_PORT|=_BV(LCD_DB5_PIN) +#define lcd_db6_port_high() LCD_DB6_PORT|=_BV(LCD_DB6_PIN) +#define lcd_db7_port_high() LCD_DB7_PORT|=_BV(LCD_DB7_PIN) + +#define lcd_rs_port_set(value) if (value) lcd_rs_port_high(); else lcd_rs_port_low(); +#if RW_LINE_IMPLEMENTED==1 +#define lcd_rw_port_set(value) if (value) lcd_rw_port_high(); else lcd_rw_port_low(); +#endif +#define lcd_db0_port_set(value) if (value) lcd_db0_port_high(); else lcd_db0_port_low(); +#define lcd_db1_port_set(value) if (value) lcd_db1_port_high(); else lcd_db1_port_low(); +#define lcd_db2_port_set(value) if (value) lcd_db2_port_high(); else lcd_db2_port_low(); +#define lcd_db3_port_set(value) if (value) lcd_db3_port_high(); else lcd_db3_port_low(); +#define lcd_db4_port_set(value) if (value) lcd_db4_port_high(); else lcd_db4_port_low(); +#define lcd_db5_port_set(value) if (value) lcd_db5_port_high(); else lcd_db5_port_low(); +#define lcd_db6_port_set(value) if (value) lcd_db6_port_high(); else lcd_db6_port_low(); +#define lcd_db7_port_set(value) if (value) lcd_db7_port_high(); else lcd_db7_port_low(); + +//PIN defines +#define lcd_db0_pin_get() (((PIN(LCD_DB0_PORT) & _BV(LCD_DB0_PIN))==0)?0:1) +#define lcd_db1_pin_get() (((PIN(LCD_DB1_PORT) & _BV(LCD_DB1_PIN))==0)?0:1) +#define lcd_db2_pin_get() (((PIN(LCD_DB2_PORT) & _BV(LCD_DB2_PIN))==0)?0:1) +#define lcd_db3_pin_get() (((PIN(LCD_DB3_PORT) & _BV(LCD_DB3_PIN))==0)?0:1) +#define lcd_db4_pin_get() (((PIN(LCD_DB4_PORT) & _BV(LCD_DB4_PIN))==0)?0:1) +#define lcd_db5_pin_get() (((PIN(LCD_DB5_PORT) & _BV(LCD_DB5_PIN))==0)?0:1) +#define lcd_db6_pin_get() (((PIN(LCD_DB6_PORT) & _BV(LCD_DB6_PIN))==0)?0:1) +#define lcd_db7_pin_get() (((PIN(LCD_DB7_PORT) & _BV(LCD_DB7_PIN))==0)?0:1) + +//DDR defines +#define lcd_rs_ddr_low() DDR(LCD_RS_PORT)&=~_BV(LCD_RS_PIN) +#if RW_LINE_IMPLEMENTED==1 +#define lcd_rw_ddr_low() DDR(LCD_RW_PORT)&=~_BV(LCD_RW_PIN) +#endif +#define lcd_db0_ddr_low() DDR(LCD_DB0_PORT)&=~_BV(LCD_DB0_PIN) +#define lcd_db1_ddr_low() DDR(LCD_DB1_PORT)&=~_BV(LCD_DB1_PIN) +#define lcd_db2_ddr_low() DDR(LCD_DB2_PORT)&=~_BV(LCD_DB2_PIN) +#define lcd_db3_ddr_low() DDR(LCD_DB3_PORT)&=~_BV(LCD_DB3_PIN) +#define lcd_db4_ddr_low() DDR(LCD_DB4_PORT)&=~_BV(LCD_DB4_PIN) +#define lcd_db5_ddr_low() DDR(LCD_DB5_PORT)&=~_BV(LCD_DB5_PIN) +#define lcd_db6_ddr_low() DDR(LCD_DB6_PORT)&=~_BV(LCD_DB6_PIN) +#define lcd_db7_ddr_low() DDR(LCD_DB7_PORT)&=~_BV(LCD_DB7_PIN) + +#define lcd_rs_ddr_high() DDR(LCD_RS_PORT)|=_BV(LCD_RS_PIN) +#if RW_LINE_IMPLEMENTED==1 +#define lcd_rw_ddr_high() DDR(LCD_RW_PORT)|=_BV(LCD_RW_PIN) +#endif +#define lcd_db0_ddr_high() DDR(LCD_DB0_PORT)|=_BV(LCD_DB0_PIN) +#define lcd_db1_ddr_high() DDR(LCD_DB1_PORT)|=_BV(LCD_DB1_PIN) +#define lcd_db2_ddr_high() DDR(LCD_DB2_PORT)|=_BV(LCD_DB2_PIN) +#define lcd_db3_ddr_high() DDR(LCD_DB3_PORT)|=_BV(LCD_DB3_PIN) +#define lcd_db4_ddr_high() DDR(LCD_DB4_PORT)|=_BV(LCD_DB4_PIN) +#define lcd_db5_ddr_high() DDR(LCD_DB5_PORT)|=_BV(LCD_DB5_PIN) +#define lcd_db6_ddr_high() DDR(LCD_DB6_PORT)|=_BV(LCD_DB6_PIN) +#define lcd_db7_ddr_high() DDR(LCD_DB7_PORT)|=_BV(LCD_DB7_PIN) + +#define lcd_rs_ddr_set(value) if (value) lcd_rs_ddr_high(); else lcd_rs_ddr_low(); +#if RW_LINE_IMPLEMENTED==1 +#define lcd_rw_ddr_set(value) if (value) lcd_rw_ddr_high(); else lcd_rw_ddr_low(); +#endif +#define lcd_db0_ddr_set(value) if (value) lcd_db0_ddr_high(); else lcd_db0_ddr_low(); +#define lcd_db1_ddr_set(value) if (value) lcd_db1_ddr_high(); else lcd_db1_ddr_low(); +#define lcd_db2_ddr_set(value) if (value) lcd_db2_ddr_high(); else lcd_db2_ddr_low(); +#define lcd_db3_ddr_set(value) if (value) lcd_db3_ddr_high(); else lcd_db3_ddr_low(); +#define lcd_db4_ddr_set(value) if (value) lcd_db4_ddr_high(); else lcd_db4_ddr_low(); +#define lcd_db5_ddr_set(value) if (value) lcd_db5_ddr_high(); else lcd_db5_ddr_low(); +#define lcd_db6_ddr_set(value) if (value) lcd_db6_ddr_high(); else lcd_db6_ddr_low(); +#define lcd_db7_ddr_set(value) if (value) lcd_db7_ddr_high(); else lcd_db7_ddr_low(); + +#if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) +static unsigned char PrevCmdInvolvedAddressCounter = 0; +#endif + +#if (LCD_DISPLAYS>1) +static unsigned char ActiveDisplay = 1; +#endif + +static inline void lcd_e_port_low() +{ +#if (LCD_DISPLAYS>1) + + switch (ActiveDisplay) { + case 2 : + LCD_E2_PORT &= ~_BV(LCD_E2_PIN); + break; +#if (LCD_DISPLAYS>=3) + + case 3 : + LCD_E3_PORT &= ~_BV(LCD_E3_PIN); + break; +#endif +#if (LCD_DISPLAYS==4) + + case 4 : + LCD_E4_PORT &= ~_BV(LCD_E4_PIN); + break; +#endif + + default : +#endif + LCD_E_PORT &= ~_BV(LCD_E_PIN); +#if (LCD_DISPLAYS>1) + } + +#endif +} + +static inline void lcd_e_port_high() +{ +#if (LCD_DISPLAYS>1) + + switch (ActiveDisplay) { + case 2 : + LCD_E2_PORT |= _BV(LCD_E2_PIN); + break; +#if (LCD_DISPLAYS>=3) + + case 3 : + LCD_E3_PORT |= _BV(LCD_E3_PIN); + break; +#endif +#if (LCD_DISPLAYS==4) + + case 4 : + LCD_E4_PORT |= _BV(LCD_E4_PIN); + break; +#endif + + default : +#endif + LCD_E_PORT |= _BV(LCD_E_PIN); +#if (LCD_DISPLAYS>1) + } + +#endif +} + +static inline void lcd_e_ddr_low() +{ +#if (LCD_DISPLAYS>1) + + switch (ActiveDisplay) { + case 2 : + DDR(LCD_E2_PORT) &= ~_BV(LCD_E2_PIN); + break; +#if (LCD_DISPLAYS>=3) + + case 3 : + DDR(LCD_E3_PORT) &= ~_BV(LCD_E3_PIN); + break; +#endif +#if (LCD_DISPLAYS==4) + + case 4 : + DDR(LCD_E4_PORT) &= ~_BV(LCD_E4_PIN); + break; +#endif + + default : +#endif + DDR(LCD_E_PORT) &= ~_BV(LCD_E_PIN); +#if (LCD_DISPLAYS>1) + } + +#endif +} + +static inline void lcd_e_ddr_high() +{ +#if (LCD_DISPLAYS>1) + + switch (ActiveDisplay) { + case 2 : + DDR(LCD_E2_PORT) |= _BV(LCD_E2_PIN); + break; +#if (LCD_DISPLAYS>=3) + + case 3 : + DDR(LCD_E3_PORT) |= _BV(LCD_E3_PIN); + break; +#endif +#if (LCD_DISPLAYS==4) + + case 4 : + DDR(LCD_E4_PORT) |= _BV(LCD_E4_PIN); + break; +#endif + + default : +#endif + DDR(LCD_E_PORT) |= _BV(LCD_E_PIN); +#if (LCD_DISPLAYS>1) + } + +#endif +} + + +/************************************************************************* +loops while lcd is busy, returns address counter +*************************************************************************/ +#if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) +static uint8_t lcd_read(uint8_t rs); + +static void lcd_waitbusy(void) +{ + register uint8_t c; + unsigned int ul1 = 0; + + while ( ((c = lcd_read(0)) & (1 << LCD_BUSY)) && + ul1 < ((F_CPU / 16384 >= 16) ? F_CPU / 16384 : + 16)) { // Wait Until Busy Flag is Cleared + ul1++; + } +} +#endif + + +/************************************************************************* +Low-level function to read byte from LCD controller +Input: rs 1: read data + 0: read busy flag / address counter +Returns: byte read from LCD controller +*************************************************************************/ +#if RW_LINE_IMPLEMENTED==1 +static uint8_t lcd_read(uint8_t rs) +{ + uint8_t data; +#if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) + + if (rs) { + lcd_waitbusy(); + } + + if (PrevCmdInvolvedAddressCounter) { + Delay_us(5); + PrevCmdInvolvedAddressCounter = 0; + } + +#endif + + if (rs) { + lcd_rs_port_high(); // RS=1: Read Data +#if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) + PrevCmdInvolvedAddressCounter = 1; +#endif + } else { + lcd_rs_port_low(); // RS=0: Read Busy Flag + } + + lcd_rw_port_high(); // RW=1: Read Mode +#if LCD_BITS==4 + lcd_db7_ddr_low(); // Configure Data Pins as Input + lcd_db6_ddr_low(); + lcd_db5_ddr_low(); + lcd_db4_ddr_low(); + lcd_e_port_high(); // Read High Nibble First + Delay_ns(500); + data = lcd_db4_pin_get() << 4 | lcd_db5_pin_get() << 5 | + lcd_db6_pin_get() << 6 | lcd_db7_pin_get() << 7; + lcd_e_port_low(); + Delay_ns(500); + lcd_e_port_high(); // Read Low Nibble + Delay_ns(500); + data |= lcd_db4_pin_get() << 0 | lcd_db5_pin_get() << 1 | + lcd_db6_pin_get() << 2 | lcd_db7_pin_get() << 3; + lcd_e_port_low(); + lcd_db7_ddr_high(); // Configure Data Pins as Output + lcd_db6_ddr_high(); + lcd_db5_ddr_high(); + lcd_db4_ddr_high(); + lcd_db7_port_high(); // Pins High (Inactive) + lcd_db6_port_high(); + lcd_db5_port_high(); + lcd_db4_port_high(); +#else //using 8-Bit-Mode + lcd_db7_ddr_low(); // Configure Data Pins as Input + lcd_db6_ddr_low(); + lcd_db5_ddr_low(); + lcd_db4_ddr_low(); + lcd_db3_ddr_low(); + lcd_db2_ddr_low(); + lcd_db1_ddr_low(); + lcd_db0_ddr_low(); + lcd_e_port_high(); + Delay_ns(500); + data = lcd_db7_pin_get() << 7 | lcd_db6_pin_get() << 6 | + lcd_db5_pin_get() << 5 | lcd_db4_pin_get() << 4 | + lcd_db3_pin_get() << 3 | lcd_db2_pin_get() << 2 | + lcd_db1_pin_get() << 1 | lcd_db0_pin_get(); + lcd_e_port_low(); + lcd_db7_ddr_high(); // Configure Data Pins as Output + lcd_db6_ddr_high(); + lcd_db5_ddr_high(); + lcd_db4_ddr_high(); + lcd_db3_ddr_high(); + lcd_db2_ddr_high(); + lcd_db1_ddr_high(); + lcd_db0_ddr_high(); + lcd_db7_port_high(); // Pins High (Inactive) + lcd_db6_port_high(); + lcd_db5_port_high(); + lcd_db4_port_high(); + lcd_db3_port_high(); + lcd_db2_port_high(); + lcd_db1_port_high(); + lcd_db0_port_high(); +#endif + lcd_rw_port_low(); +#if (WAIT_MODE==0 || RW_LINE_IMPLEMENTED==0) + + if (rs) { + Delay_us(40); + } else { + Delay_us(1); + } + +#endif + return data; +} + +uint8_t lcd_getc() +{ + return lcd_read(1); +} + +#endif + +/************************************************************************* +Low-level function to write byte to LCD controller +Input: data byte to write to LCD + rs 1: write data + 0: write instruction +Returns: none +*************************************************************************/ +static void lcd_write(uint8_t data, uint8_t rs) +{ +#if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) + lcd_waitbusy(); + + if (PrevCmdInvolvedAddressCounter) { + Delay_us(5); + PrevCmdInvolvedAddressCounter = 0; + } + +#endif + + if (rs) { + lcd_rs_port_high(); // RS=1: Write Character +#if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) + PrevCmdInvolvedAddressCounter = 1; +#endif + } else { + lcd_rs_port_low(); // RS=0: Write Command +#if (WAIT_MODE==1 && RW_LINE_IMPLEMENTED==1) + PrevCmdInvolvedAddressCounter = 0; +#endif + } + +#if LCD_BITS==4 + lcd_db7_port_set(data & _BV(7)); //Output High Nibble + lcd_db6_port_set(data & _BV(6)); + lcd_db5_port_set(data & _BV(5)); + lcd_db4_port_set(data & _BV(4)); + Delay_ns(100); + lcd_e_port_high(); + Delay_ns(500); + lcd_e_port_low(); + lcd_db7_port_set(data & _BV(3)); //Output High Nibble + lcd_db6_port_set(data & _BV(2)); + lcd_db5_port_set(data & _BV(1)); + lcd_db4_port_set(data & _BV(0)); + Delay_ns(100); + lcd_e_port_high(); + Delay_ns(500); + lcd_e_port_low(); + lcd_db7_port_high(); // All Data Pins High (Inactive) + lcd_db6_port_high(); + lcd_db5_port_high(); + lcd_db4_port_high(); +#else //using 8-Bit_Mode + lcd_db7_port_set(data & _BV(7)); //Output High Nibble + lcd_db6_port_set(data & _BV(6)); + lcd_db5_port_set(data & _BV(5)); + lcd_db4_port_set(data & _BV(4)); + lcd_db3_port_set(data & _BV(3)); //Output High Nibble + lcd_db2_port_set(data & _BV(2)); + lcd_db1_port_set(data & _BV(1)); + lcd_db0_port_set(data & _BV(0)); + Delay_ns(100); + lcd_e_port_high(); + Delay_ns(500); + lcd_e_port_low(); + lcd_db7_port_high(); // All Data Pins High (Inactive) + lcd_db6_port_high(); + lcd_db5_port_high(); + lcd_db4_port_high(); + lcd_db3_port_high(); + lcd_db2_port_high(); + lcd_db1_port_high(); + lcd_db0_port_high(); +#endif +#if (WAIT_MODE==0 || RW_LINE_IMPLEMENTED==0) + + if (!rs && + data <= ((1 << LCD_CLR) | (1 << LCD_HOME))) { // Is command clrscr or home? + Delay_us(1640); + } else { + Delay_us(40); + } + +#endif +} + +/************************************************************************* +Send LCD controller instruction command +Input: instruction to send to LCD controller, see HD44780 data sheet +Returns: none +*************************************************************************/ +void lcd_command(uint8_t cmd) +{ + lcd_write(cmd, 0); +} + +/************************************************************************* +Set cursor to specified position +Input: pos position +Returns: none +*************************************************************************/ +void lcd_goto(uint8_t pos) +{ + //Do not go outside of screen limits + assert(pos < LCD_COLS_MAX); + lcd_command((1 << LCD_DDRAM) + pos); +} + + +/************************************************************************* +Clear screen +Input: none +Returns: none +*************************************************************************/ +void lcd_clrscr() +{ + lcd_command(1 << LCD_CLR); +} + + +/************************************************************************* +Return home +Input: none +Returns: none +*************************************************************************/ +void lcd_home() +{ + lcd_command(1 << LCD_HOME); +} + + +/************************************************************************* +Display character +Input: character to be displayed +Returns: none +*************************************************************************/ +void lcd_putc(char c) +{ + lcd_write(c, 1); +} + + +/************************************************************************* +Display string +Input: string to be displayed +Returns: none +*************************************************************************/ +void lcd_puts(const char *s) +{ + register char c; + + while ((c = *s++)) { + lcd_putc(c); + } +} + + +/************************************************************************* +Display string from flash +Input: string to be displayed +Returns: none +*************************************************************************/ +void lcd_puts_P(const char *progmem_s) +{ + register char c; + + while ((c = pgm_read_byte(progmem_s++))) { + lcd_putc(c); + } +} + +/************************************************************************* +Initialize display +Input: none +Returns: none +*************************************************************************/ +void lcd_init() +{ + //Set All Pins as Output + lcd_e_ddr_high(); + lcd_rs_ddr_high(); +#if RW_LINE_IMPLEMENTED==1 + lcd_rw_ddr_high(); +#endif + lcd_db7_ddr_high(); + lcd_db6_ddr_high(); + lcd_db5_ddr_high(); + lcd_db4_ddr_high(); +#if LCD_BITS==8 + lcd_db3_ddr_high(); + lcd_db2_ddr_high(); + lcd_db1_ddr_high(); + lcd_db0_ddr_high(); +#endif + //Set All Control Lines Low + lcd_e_port_low(); + lcd_rs_port_low(); +#if RW_LINE_IMPLEMENTED==1 + lcd_rw_port_low(); +#endif + //Set All Data Lines High + lcd_db7_port_high(); + lcd_db6_port_high(); + lcd_db5_port_high(); + lcd_db4_port_high(); +#if LCD_BITS==8 + lcd_db3_port_high(); + lcd_db2_port_high(); + lcd_db1_port_high(); + lcd_db0_port_high(); +#endif + //Startup Delay + Delay_ms(DELAY_RESET); + //Initialize Display + lcd_db7_port_low(); + lcd_db6_port_low(); + Delay_ns(100); + lcd_e_port_high(); + Delay_ns(500); + lcd_e_port_low(); + Delay_us(4100); + lcd_e_port_high(); + Delay_ns(500); + lcd_e_port_low(); + Delay_us(100); + lcd_e_port_high(); + Delay_ns(500); + lcd_e_port_low(); + Delay_us(40); + //Init differs between 4-bit and 8-bit from here +#if (LCD_BITS==4) + lcd_db4_port_low(); + Delay_ns(100); + lcd_e_port_high(); + Delay_ns(500); + lcd_e_port_low(); + Delay_us(40); + lcd_db4_port_low(); + Delay_ns(100); + lcd_e_port_high(); + Delay_ns(500); + lcd_e_port_low(); + Delay_ns(500); +#if (LCD_DISPLAYS==1) + + if (LCD_DISPLAY_LINES > 1) { + lcd_db7_port_high(); + } + +#else + unsigned char c; + + switch (ActiveDisplay) { + case 1 : + c = LCD_DISPLAY_LINES; + break; + + case 2 : + c = LCD_DISPLAY2_LINES; + break; +#if (LCD_DISPLAYS>=3) + + case 3 : + c = LCD_DISPLAY3_LINES; + break; +#endif +#if (LCD_DISPLAYS==4) + + case 4 : + c = LCD_DISPLAY4_LINES; + break; +#endif + } + + if (c > 1) { + lcd_db7_port_high(); + } + +#endif + Delay_ns(100); + lcd_e_port_high(); + Delay_ns(500); + lcd_e_port_low(); + Delay_us(40); +#else +#if (LCD_DISPLAYS==1) + + if (LCD_DISPLAY_LINES < 2) { + lcd_db3_port_low(); + } + +#else + unsigned char c; + + switch (ActiveDisplay) { + case 1 : + c = LCD_DISPLAY_LINES; + break; + + case 2 : + c = LCD_DISPLAY2_LINES; + break; +#if (LCD_DISPLAYS>=3) + + case 3 : + c = LCD_DISPLAY3_LINES; + break; +#endif +#if (LCD_DISPLAYS==4) + + case 4 : + c = LCD_DISPLAY4_LINES; + break; +#endif + } + + if (c < 2) { + lcd_db3_port_low(); + } + +#endif + lcd_db2_port_low(); + Delay_ns(100); + lcd_e_port_high(); + Delay_ns(500); + lcd_e_port_low(); + Delay_us(40); +#endif + //Display Off + lcd_command(_BV(LCD_DISPLAYMODE)); + //Display Clear + lcd_clrscr(); + //Entry Mode Set + lcd_command(_BV(LCD_ENTRY_MODE) | _BV(LCD_ENTRY_INC)); + //Display On + lcd_command(_BV(LCD_DISPLAYMODE) | _BV(LCD_DISPLAYMODE_ON)); +} + +#if (LCD_DISPLAYS>1) +void lcd_use_display(int ADisplay) +{ + if (ADisplay >= 1 && ADisplay <= LCD_DISPLAYS) { + ActiveDisplay = ADisplay; + } +} +#endif + + +/************************************************************************* +Clear characters at position until length +Input: start position and lentgh +Returns: none +*************************************************************************/ +void lcd_clr(uint8_t pos, uint8_t len) +{ + for (int i = 0; i < len; i++) { + lcd_goto(pos + i); + lcd_putc(' '); + } +} + diff --git a/lib/hd44780_111/hd44780.h b/lib/hd44780_111/hd44780.h index 83043ab..ff466d7 100755 --- a/lib/hd44780_111/hd44780.h +++ b/lib/hd44780_111/hd44780.h @@ -1,73 +1,75 @@ -/***************************************************************************** -Title : HD44780 Library -Author : SA Development -Version: 1.11 -*****************************************************************************/ - -#ifndef HD44780_H -#define HD44780_H - - -//LCD Commands for HD44780 -#define LCD_CLR 0 // DB0: clear display - -#define LCD_HOME 1 // DB1: return to home position - -#define LCD_ENTRY_MODE 2 // DB2: set entry mode -#define LCD_ENTRY_INC 1 // DB1: 1=increment, 0=decrement -#define LCD_ENTRY_SHIFT 0 // DB0: 1=display shift on - -#define LCD_DISPLAYMODE 3 // DB3: turn lcd/cursor on -#define LCD_DISPLAYMODE_ON 2 // DB2: turn display on -#define LCD_DISPLAYMODE_CURSOR 1 // DB1: turn cursor on -#define LCD_DISPLAYMODE_BLINK 0 // DB0: blinking cursor - -#define LCD_MOVE 4 // DB4: move cursor/display -#define LCD_MOVE_DISP 3 // DB3: move display (0-> cursor) -#define LCD_MOVE_RIGHT 2 // DB2: move right (0-> left) - -#define LCD_FUNCTION 5 // DB5: function set -#define LCD_FUNCTION_8BIT 4 // DB4: set 8BIT mode (0->4BIT mode) -#define LCD_FUNCTION_2LINES 3 // DB3: two lines (0->one line) -#define LCD_FUNCTION_10DOTS 2 // DB2: 5x10 font (0->5x7 font) - -#define LCD_CGRAM 6 // DB6: set CG RAM address -#define LCD_DDRAM 7 // DB7: set DD RAM address - -#define LCD_BUSY 7 // DB7: LCD is busy - -// LCD columns and rows definitions -#define LCD_ROW_1_START 0 -#define LCD_ROW_2_START 64 -#define LCD_ROW_1_LAST_VISIBLE_COL 15 -#define LCD_ROW_1_LAST_COL 39 -#define LCD_ROW_2_LAST_VISIBLE_COL 79 -#define LCD_ROW_1_LAST_COL 103 -#define LCD_COLS_MAX 103 -#define LCD_VISIBLE_COLS 16 - -// Maximum character what can be displayed with 1 byte -#define LCD_MAX_CARACTER 255 - - -void lcd_init(); -void lcd_command(uint8_t cmd); - -void lcd_clrscr(); -void lcd_clr(uint8_t pos, uint8_t len); -void lcd_home(); -void lcd_goto(uint8_t pos); - -#if RW_LINE_IMPLEMENTED==1 -uint8_t lcd_getc(); -#endif - -void lcd_putc(char c); -void lcd_puts(const char *s); -void lcd_puts_P(const char *progmem_s); -#if (LCD_DISPLAYS>1) -void lcd_use_display(int ADisplay); -#endif - -#endif - +/***************************************************************************** +Title : HD44780 Library +Author : SA Development +Version: 1.11 +Modifications for: Arduino Mega 2560 + Itead Studio Arduino 1602 LED Keypad Shield +Modified by: Silver Kits October 2016 +*****************************************************************************/ +#ifndef HD44780_H +#define HD44780_H + + +//LCD Commands for HD44780 +#define LCD_CLR 0 // DB0: clear display + +#define LCD_HOME 1 // DB1: return to home position + +#define LCD_ENTRY_MODE 2 // DB2: set entry mode +#define LCD_ENTRY_INC 1 // DB1: 1=increment, 0=decrement +#define LCD_ENTRY_SHIFT 0 // DB0: 1=display shift on + +#define LCD_DISPLAYMODE 3 // DB3: turn lcd/cursor on +#define LCD_DISPLAYMODE_ON 2 // DB2: turn display on +#define LCD_DISPLAYMODE_CURSOR 1 // DB1: turn cursor on +#define LCD_DISPLAYMODE_BLINK 0 // DB0: blinking cursor + +#define LCD_MOVE 4 // DB4: move cursor/display +#define LCD_MOVE_DISP 3 // DB3: move display (0-> cursor) +#define LCD_MOVE_RIGHT 2 // DB2: move right (0-> left) + +#define LCD_FUNCTION 5 // DB5: function set +#define LCD_FUNCTION_8BIT 4 // DB4: set 8BIT mode (0->4BIT mode) +#define LCD_FUNCTION_2LINES 3 // DB3: two lines (0->one line) +#define LCD_FUNCTION_10DOTS 2 // DB2: 5x10 font (0->5x7 font) + +#define LCD_CGRAM 6 // DB6: set CG RAM address +#define LCD_DDRAM 7 // DB7: set DD RAM address + +#define LCD_BUSY 7 // DB7: LCD is busy + +// LCD columns and rows definitions +#define LCD_ROW_1_START 0 +#define LCD_ROW_2_START 64 +#define LCD_ROW_1_LAST_VISIBLE_COL 15 +#define LCD_ROW_1_LAST_COL 39 +#define LCD_ROW_2_LAST_VISIBLE_COL 79 +#define LCD_ROW_1_LAST_COL 103 +#define LCD_COLS_MAX 103 +#define LCD_VISIBLE_COLS 16 + +// Maximum character what can be displayed with 1 byte +#define LCD_MAX_CARACTER 255 + + +void lcd_init(); +void lcd_command(uint8_t cmd); + +void lcd_clrscr(); +void lcd_clr(uint8_t pos, uint8_t len); +void lcd_home(); +void lcd_goto(uint8_t pos); + +#if RW_LINE_IMPLEMENTED==1 +uint8_t lcd_getc(); +#endif + +void lcd_putc(char c); +void lcd_puts(const char *s); +void lcd_puts_P(const char *progmem_s); +#if (LCD_DISPLAYS>1) +void lcd_use_display(int ADisplay); +#endif + +#endif + diff --git a/lib/hd44780_111/hd44780_settings.h b/lib/hd44780_111/hd44780_settings.h index 5d5c954..af41641 100755 --- a/lib/hd44780_111/hd44780_settings.h +++ b/lib/hd44780_111/hd44780_settings.h @@ -1,30 +1,38 @@ -#ifndef HD44780_SETTINGS_H -#define HD44780_SETTINGS_H - -#define USE_ADELAY_LIBRARY 0 -#define LCD_BITS 4 -#define RW_LINE_IMPLEMENTED 0 -#define WAIT_MODE 0 -#define DELAY_RESET 15 - -// Pin and port definitions for Arduino Mega 2560 -#define LCD_DB4_PORT PORTG -#define LCD_DB4_PIN 5 -#define LCD_DB5_PORT PORTE -#define LCD_DB5_PIN 3 -#define LCD_DB6_PORT PORTH -#define LCD_DB6_PIN 3 -#define LCD_DB7_PORT PORTH -#define LCD_DB7_PIN 4 - -#define LCD_RS_PORT PORTH -#define LCD_RS_PIN 5 - -#define LCD_DISPLAYS 1 - -#define LCD_DISPLAY_LINES 2 - -#define LCD_E_PORT PORTH -#define LCD_E_PIN 6 - -#endif /* HD44780_SETTINGS_H */ +/***************************************************************************** +Title : HD44780 Library +Author : SA Development +Version: 1.11 +Modifications for: Arduino Mega 2560 + Itead Studio Arduino 1602 LED Keypad Shield +Modified by: Silver Kits October 2016 +*****************************************************************************/ +#ifndef HD44780_SETTINGS_H +#define HD44780_SETTINGS_H + +#define USE_ADELAY_LIBRARY 0 +#define LCD_BITS 4 +#define RW_LINE_IMPLEMENTED 0 +#define WAIT_MODE 0 +#define DELAY_RESET 15 + +// Pin and port definitions for Arduino Mega 2560 +#define LCD_DB4_PORT PORTG +#define LCD_DB4_PIN 5 +#define LCD_DB5_PORT PORTE +#define LCD_DB5_PIN 3 +#define LCD_DB6_PORT PORTH +#define LCD_DB6_PIN 3 +#define LCD_DB7_PORT PORTH +#define LCD_DB7_PIN 4 + +#define LCD_RS_PORT PORTH +#define LCD_RS_PIN 5 + +#define LCD_DISPLAYS 1 + +#define LCD_DISPLAY_LINES 2 + +#define LCD_E_PORT PORTH +#define LCD_E_PIN 6 + +#endif /* HD44780_SETTINGS_H */ diff --git a/lib/hd44780_111/hd44780_settings_example.h b/lib/hd44780_111/hd44780_settings_example.h index 035fb96..21cca52 100755 --- a/lib/hd44780_111/hd44780_settings_example.h +++ b/lib/hd44780_111/hd44780_settings_example.h @@ -1,66 +1,66 @@ -#ifndef HD44780_SETTINGS_H -#define HD44780_SETTINGS_H - -#define F_CPU 8000000 // Set Clock Frequency - -#define USE_ADELAY_LIBRARY 0 // Set to 1 to use my ADELAY library, 0 to use internal delay functions -#define LCD_BITS 4 // 4 for 4 Bit I/O Mode, 8 for 8 Bit I/O Mode -#define RW_LINE_IMPLEMENTED 0 // 0 for no RW line (RW on LCD tied to ground), 1 for RW line present -#define WAIT_MODE 0 // 0=Use Delay Method (Faster if running <10Mhz) - // 1=Use Check Busy Flag (Faster if running >10Mhz) ***Requires RW Line*** -#define DELAY_RESET 15 // in mS - -#if (LCD_BITS==8) // If using 8 bit mode, you must configure DB0-DB7 - #define LCD_DB0_PORT PORTC - #define LCD_DB0_PIN 0 - #define LCD_DB1_PORT PORTC - #define LCD_DB1_PIN 1 - #define LCD_DB2_PORT PORTC - #define LCD_DB2_PIN 2 - #define LCD_DB3_PORT PORTC - #define LCD_DB3_PIN 3 -#endif -#define LCD_DB4_PORT PORTC // If using 4 bit omde, yo umust configure DB4-DB7 -#define LCD_DB4_PIN 4 -#define LCD_DB5_PORT PORTC -#define LCD_DB5_PIN 5 -#define LCD_DB6_PORT PORTC -#define LCD_DB6_PIN 6 -#define LCD_DB7_PORT PORTC -#define LCD_DB7_PIN 7 - -#define LCD_RS_PORT PORTC // Port for RS line -#define LCD_RS_PIN 4 // Pin for RS line - -#define LCD_RW_PORT PORTC // Port for RW line (ONLY used if RW_LINE_IMPLEMENTED=1) -#define LCD_RW_PIN 6 // Pin for RW line (ONLY used if RW_LINE_IMPLEMENTED=1) - -#define LCD_DISPLAYS 1 // Up to 4 LCD displays can be used at one time - // All pins are shared between displays except for the E - // pin which each display will have its own - - // Display 1 Settings - if you only have 1 display, YOU MUST SET THESE -#define LCD_DISPLAY_LINES 2 // Number of Lines, Only Used for Set I/O Mode Command -#define LCD_E_PORT PORTC // Port for E line -#define LCD_E_PIN 5 // Pin for E line - -#if (LCD_DISPLAYS>=2) // If you have 2 displays, set these and change LCD_DISPLAYS=2 - #define LCD_DISPLAY2_LINES 2 // Number of Lines, Only Used for Set I/O Mode Command - #define LCD_E2_PORT PORTC // Port for E line - #define LCD_E2_PIN 5 // Pin for E line -#endif - -#if (LCD_DISPLAYS>=3) // If you have 3 displays, set these and change LCD_DISPLAYS=3 - #define LCD_DISPLAY3_LINES 2 // Number of Lines, Only Used for Set I/O Mode Command - #define LCD_E3_PORT PORTC // Port for E line - #define LCD_E3_PIN 5 // Pin for E line -#endif - -#if (LCD_DISPLAYS>=4) // If you have 4 displays, set these and change LCD_DISPLAYS=4 - #define LCD_DISPLAY4_LINES 2 // Number of Lines, Only Used for Set I/O Mode Command - #define LCD_E4_PORT PORTC // Port for E line - #define LCD_E4_PIN 5 // Pin for E line -#endif - -#endif - +#ifndef HD44780_SETTINGS_H +#define HD44780_SETTINGS_H + +#define F_CPU 8000000 // Set Clock Frequency + +#define USE_ADELAY_LIBRARY 0 // Set to 1 to use my ADELAY library, 0 to use internal delay functions +#define LCD_BITS 4 // 4 for 4 Bit I/O Mode, 8 for 8 Bit I/O Mode +#define RW_LINE_IMPLEMENTED 0 // 0 for no RW line (RW on LCD tied to ground), 1 for RW line present +#define WAIT_MODE 0 // 0=Use Delay Method (Faster if running <10Mhz) + // 1=Use Check Busy Flag (Faster if running >10Mhz) ***Requires RW Line*** +#define DELAY_RESET 15 // in mS + +#if (LCD_BITS==8) // If using 8 bit mode, you must configure DB0-DB7 + #define LCD_DB0_PORT PORTC + #define LCD_DB0_PIN 0 + #define LCD_DB1_PORT PORTC + #define LCD_DB1_PIN 1 + #define LCD_DB2_PORT PORTC + #define LCD_DB2_PIN 2 + #define LCD_DB3_PORT PORTC + #define LCD_DB3_PIN 3 +#endif +#define LCD_DB4_PORT PORTC // If using 4 bit omde, yo umust configure DB4-DB7 +#define LCD_DB4_PIN 4 +#define LCD_DB5_PORT PORTC +#define LCD_DB5_PIN 5 +#define LCD_DB6_PORT PORTC +#define LCD_DB6_PIN 6 +#define LCD_DB7_PORT PORTC +#define LCD_DB7_PIN 7 + +#define LCD_RS_PORT PORTC // Port for RS line +#define LCD_RS_PIN 4 // Pin for RS line + +#define LCD_RW_PORT PORTC // Port for RW line (ONLY used if RW_LINE_IMPLEMENTED=1) +#define LCD_RW_PIN 6 // Pin for RW line (ONLY used if RW_LINE_IMPLEMENTED=1) + +#define LCD_DISPLAYS 1 // Up to 4 LCD displays can be used at one time + // All pins are shared between displays except for the E + // pin which each display will have its own + + // Display 1 Settings - if you only have 1 display, YOU MUST SET THESE +#define LCD_DISPLAY_LINES 2 // Number of Lines, Only Used for Set I/O Mode Command +#define LCD_E_PORT PORTC // Port for E line +#define LCD_E_PIN 5 // Pin for E line + +#if (LCD_DISPLAYS>=2) // If you have 2 displays, set these and change LCD_DISPLAYS=2 + #define LCD_DISPLAY2_LINES 2 // Number of Lines, Only Used for Set I/O Mode Command + #define LCD_E2_PORT PORTC // Port for E line + #define LCD_E2_PIN 5 // Pin for E line +#endif + +#if (LCD_DISPLAYS>=3) // If you have 3 displays, set these and change LCD_DISPLAYS=3 + #define LCD_DISPLAY3_LINES 2 // Number of Lines, Only Used for Set I/O Mode Command + #define LCD_E3_PORT PORTC // Port for E line + #define LCD_E3_PIN 5 // Pin for E line +#endif + +#if (LCD_DISPLAYS>=4) // If you have 4 displays, set these and change LCD_DISPLAYS=4 + #define LCD_DISPLAY4_LINES 2 // Number of Lines, Only Used for Set I/O Mode Command + #define LCD_E4_PORT PORTC // Port for E line + #define LCD_E4_PIN 5 // Pin for E line +#endif + +#endif +