From ff519e7cac725fcdfbf5764dceba3f8723cbc6f7 Mon Sep 17 00:00:00 2001 From: Xoaquin Castrelo <xoaquin.cb@gmail.com> Date: Sun, 14 Nov 2021 02:29:27 +0000 Subject: [PATCH] Added an interface to control a 16x2 display. --- emb/display.cpp | 113 ++++++++++++++++++++++++++++++++++++++++++++++++ emb/display.hpp | 9 ++++ 2 files changed, 122 insertions(+) create mode 100644 emb/display.cpp create mode 100644 emb/display.hpp diff --git a/emb/display.cpp b/emb/display.cpp new file mode 100644 index 0000000..f0ad2ef --- /dev/null +++ b/emb/display.cpp @@ -0,0 +1,113 @@ +#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)); +} + diff --git a/emb/display.hpp b/emb/display.hpp new file mode 100644 index 0000000..8e23da0 --- /dev/null +++ b/emb/display.hpp @@ -0,0 +1,9 @@ +#ifndef DISPLAY_H +#define DISPLAY_H + +void initDisplay(); +void writeDisplay(uint8_t value); +void setDisplayCursor(uint8_t col, uint8_t row); +void clearDisplay(); + +#endif /* DISPLAY_H */ -- GitLab