Skip to content
Snippets Groups Projects
display.cpp 2.36 KiB
#include <util/delay.h>
#include <avr/io.h>

// 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_lo() PORTD &= ~(1 << PORTD2)
#define RS_hi() PORTD |=  (1 << PORTD2)
#define EN_lo() PORTD &= ~(1 << PORTD3)
#define EN_hi() PORTD |=  (1 << PORTD3)

void send(uint8_t value)
{
    PORTD &= 0x0F;
    PORTB &= 0xF0;
    
    PORTD |= value & 0xF0;
    PORTB |= value & 0x0F;
    
    EN_hi();
    _delay_us(1);
    EN_lo();
    _delay_us(50);
}

void command(uint8_t value)
{
    RS_lo();
    send(value);
}

void writeDisplay(uint8_t value)
{
    RS_hi();
    send(value);
}

void clearDisplay()
{
    command(LCD_CLEARDISPLAY);
    _delay_us(2000);
}

void initDisplay()
{
    DDRD |= 0xF0 | (1 << DDD3) | (1 << DDD2);
    DDRB |= 0x0F;
    
    uint8_t _displayfunction = LCD_8BITMODE | LCD_2LINE | LCD_1LINE | LCD_5x8DOTS;
    
    _delay_ms(50);
    
    RS_lo();
    EN_lo();
    
    command(LCD_FUNCTIONSET | _displayfunction);
    _delay_us(4500);
    command(LCD_FUNCTIONSET | _displayfunction);
    _delay_us(150);
    command(LCD_FUNCTIONSET | _displayfunction);
    command(LCD_FUNCTIONSET | _displayfunction);
    
    uint8_t _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
    command(LCD_DISPLAYCONTROL | _displaycontrol);
    
    clearDisplay();
    
    uint8_t _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
    command(LCD_ENTRYMODESET | _displaymode);
}

void setDisplayCursor(uint8_t col, uint8_t row)
{
    row &= 1;
    
    command(LCD_SETDDRAMADDR | (col + row * 0x40));
}