Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- The circuit:
- * LCD RS pin to digital pin 11
- * LCD R/W pin to digital pin 12
- * LCD Enable pin to digital pin 13
- * LCD D0 pin to digital pin 0
- * LCD D1 pin to digital pin 1
- * LCD D2 pin to digital pin 2
- * LCD D3 pin to digital pin 3
- * LCD D4 pin to digital pin 4
- * LCD D5 pin to digital pin 5
- * LCD D6 pin to digital pin 6
- * LCD D7 pin to digital pin 7
- */
- // commands
- #define LCD_CLEARDISPLAY 0x01
- #define LCD_RETURNHOME 0x02
- #define LCD_ENTRYMODESET 0x04
- #define LCD_DISPLAYCONTROL 0x08
- #define LCD_CURSORSHIFT 0x10
- #define LCD_FUNCTIONSET 0x20
- #define LCD_SETCGRAMADDR 0x40
- #define LCD_SETDDRAMADDR 0x80
- // flags for display entry mode
- #define LCD_ENTRYRIGHT 0x00
- #define LCD_ENTRYLEFT 0x02
- #define LCD_ENTRYSHIFTINCREMENT 0x01
- #define LCD_ENTRYSHIFTDECREMENT 0x00
- // flags for display on/off control
- #define LCD_DISPLAYON 0x04
- #define LCD_DISPLAYOFF 0x00
- #define LCD_CURSORON 0x02
- #define LCD_CURSOROFF 0x00
- #define LCD_BLINKON 0x01
- #define LCD_BLINKOFF 0x00
- // flags for display/cursor shift
- #define LCD_DISPLAYMOVE 0x08
- #define LCD_CURSORMOVE 0x00
- #define LCD_MOVERIGHT 0x04
- #define LCD_MOVELEFT 0x00
- // flags for function set
- #define LCD_8BITMODE 0x10
- #define LCD_4BITMODE 0x00
- #define LCD_2LINE 0x08
- #define LCD_1LINE 0x00
- #define LCD_5x10DOTS 0x04
- #define LCD_5x8DOTS 0x00
- #define RS 0x08
- #define RW 0x10
- #define EN 0x20
- #define LCD_4_BITS
- #ifdef LCD_4_BITS
- #define LCD_X_BITMODE LCD_4BITMODE
- #else
- #define LCD_X_BITMODE LCD_8BITMODE
- #endif
- uint8_t initCmd = LCD_FUNCTIONSET | LCD_X_BITMODE | LCD_2LINE | LCD_5x8DOTS;
- uint8_t displayOn = LCD_DISPLAYCONTROL | LCD_DISPLAYON;// | LCD_BLINKON | LCD_CURSORON;
- uint8_t displayMode = LCD_ENTRYMODESET | LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
- void command(uint8_t cmd);
- void write4bits(uint8_t data, uint8_t cmd, bool noWait);
- void write(uint8_t data, uint8_t rs = RS, bool noWait = false);
- void clearDisplay(bool hwClear = false);
- void setup()
- {
- // Set all relevant pins as output
- #ifdef LCD_4_BITS
- DDRD = 0xF0;
- #else
- DDRD = 0xFF;
- #endif
- PORTD &= 0x0F;
- DDRB |= 0x3E;
- PORTB = (PORTB & 0xC1) | 0x6;
- initLcd();
- }
- uint8_t startChar = 0;
- void loop()
- {
- unsigned long time = micros();
- command(LCD_SETDDRAMADDR);
- waitLcdBusy();
- time = micros() - time;
- time = micros();
- for (uint8_t i = 0; i < 80; i++)
- write(startChar + i);
- time = micros() - time;
- // Set LCD write direction to right to left so that the numbers are printed in the correct order.
- command(LCD_ENTRYMODESET);
- command(LCD_SETDDRAMADDR|0x45);
- write(' ');
- do {
- unsigned long m = time;
- time /= 10;
- uint8_t c = m - 10 * time;
- write(c + '0');
- } while(time);
- write(' ');
- command(LCD_ENTRYMODESET | LCD_ENTRYLEFT);
- startChar++;
- if (startChar >= 49)
- startChar = 0;
- delay(1000);
- }
- void initLcd()
- {
- // Initialization sequence
- delay(50);
- #ifdef LCD_4_BITS
- write4bits(0x03, 0, true);
- delayMicroseconds(4500);
- write4bits(0x03, 0, true);
- delayMicroseconds(150);
- write4bits(0x03, 0, true);
- delayMicroseconds(150);
- write4bits(0x02, 0, true);
- delayMicroseconds(150);
- #else
- write(initCmd, 0, true);
- delayMicroseconds(4500);
- write(initCmd, 0, true);
- delayMicroseconds(150);
- write(initCmd, 0, true);
- delayMicroseconds(150);
- #endif
- write(initCmd, 0, true);
- delayMicroseconds(150);
- command(LCD_DISPLAYCONTROL | LCD_DISPLAYOFF);
- command(LCD_CLEARDISPLAY);
- command(displayMode);
- // ----------------------------
- command(displayOn);
- command(LCD_RETURNHOME);
- }
- void command(uint8_t cmd)
- {
- write(cmd, 0);
- }
- void write4bits(uint8_t data, uint8_t cmd, bool noWait)
- {
- cmd |= EN;
- // While LCDs DB7 pin is high, busy-wait.
- if (!noWait) waitLcdBusy();
- // Write data.
- PORTD = (PORTD & 0x0F) | (data & 0xF0);
- // Issue Enable
- PORTB = (PORTB & 0xC7) | cmd;
- delayMicroseconds(1);
- PORTB &= ~cmd;
- }
- void write(uint8_t data, uint8_t cmd, bool noWait)
- {
- #ifdef LCD_4_BITS
- write4bits(data, cmd, noWait);
- delayMicroseconds(1);
- write4bits(data << 4, cmd, true);
- #else
- cmd |= EN;
- // While LCDs DB7 pin is high, busy-wait.
- if (!noWait) waitLcdBusy();
- // Write data.
- PORTD = data;
- // Issue Enable
- PORTB = (PORTB & 0xC7) | cmd;
- delayMicroseconds(1);
- PORTB &= ~cmd;
- #endif
- }
- void waitLcdBusy()
- {
- bool ret = false;
- // Set bit 7 of portD as input.
- DDRD &= ~0x80;
- PORTB = (PORTB & 0xC7) | RW;
- do
- {
- // Read busy flag from DB7.
- PORTB |= EN;
- delayMicroseconds(1);
- ret = (PIND & 0x80) != 0;
- PORTB &= ~EN;
- #ifdef LCD_4_BITS
- // Read AC3 - as per HD44780 Datasheet, page 32 Interfacing the HD47780U - 4 bit mode.
- delayMicroseconds(1);
- PORTB |= EN;
- delayMicroseconds(1);
- PORTB &= ~EN;
- #endif
- } while (ret);
- PORTB &= ~RW;
- // Set bit 7 of portD to output.
- DDRD |= 0x80;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement