LCD

Dependents:   stofzuigrobot

Files at this revision

API Documentation at this revision

Comitter:
firstsignupoftheweek
Date:
Wed Jul 03 09:51:08 2019 +0000
Commit message:
LCD

Changed in this revision

LiquidCrystal_I2C.cpp Show annotated file Show diff for this revision Revisions of this file
LiquidCrystal_I2C.h Show annotated file Show diff for this revision Revisions of this file
diff -r 000000000000 -r f363e3d1f212 LiquidCrystal_I2C.cpp
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LiquidCrystal_I2C.cpp	Wed Jul 03 09:51:08 2019 +0000
@@ -0,0 +1,283 @@
+#include "LiquidCrystal_I2C.h"
+#include "mbed.h"
+
+// When the display powers up, it is configured as follows:
+//
+// 1. Display clear
+// 2. Function set:
+//    DL = 1; 8-bit interface data
+//    N = 0; 1-line display
+//    F = 0; 5x8 dot character font
+// 3. Display on/off control:
+//    D = 0; Display off
+//    C = 0; Cursor off
+//    B = 0; Blinking off
+// 4. Entry mode set:
+//    I/D = 1; Increment by 1
+//    S = 0; No shift
+//
+// Note, however, that resetting the Arduino doesn't reset the LCD, so we
+// can't assume that its in that state when a sketch starts (and the
+// LiquidCrystal constructor is called).
+
+
+I2C _i2c(PB_3, PB_10); // SDA, SCL
+
+LiquidCrystal_I2C::LiquidCrystal_I2C(unsigned char lcd_addr, unsigned char lcd_cols, unsigned char lcd_rows, unsigned char charsize)
+{
+    _addr = lcd_addr;
+    _cols = lcd_cols;
+    _rows = lcd_rows;
+    _charsize = charsize;
+    _backlightval = LCD_BACKLIGHT;
+}
+
+void LiquidCrystal_I2C::begin() {
+    //Wire.begin();
+    _displayfunction = LCD_4BITMODE | LCD_1LINE | LCD_5x8DOTS;
+
+    if (_rows > 1) {
+        _displayfunction |= LCD_2LINE;
+    }
+
+    // for some 1 line displays you can select a 10 pixel high font
+    if ((_charsize != 0) && (_rows == 1)) {
+        _displayfunction |= LCD_5x10DOTS;
+    }
+
+    // SEE PAGE 45/46 FOR INITIALIZATION SPECIFICATION!
+    // according to datasheet, we need at least 40ms after power rises above 2.7V
+    // before sending commands. Arduino can turn on way befer 4.5V so we'll wait 50
+    wait_ms(50);
+
+    // Now we pull both RS and R/W low to begin commands
+    expanderWrite(_backlightval);   // reset expanderand turn backlight off (Bit 8 =1)
+    wait_ms(1000);
+
+    //put the LCD into 4 bit mode
+    // this is according to the hitachi HD44780 datasheet
+    // figure 24, pg 46
+
+    // we start in 8bit mode, try to set 4 bit mode
+    write4bits(0x03 << 4);
+    wait_us(4500); // wait min 4.1ms
+
+    // second try
+    write4bits(0x03 << 4);
+    wait_us(4500); // wait min 4.1ms
+
+    // third go!
+    write4bits(0x03 << 4);
+    wait_us(150);
+
+    // finally, set to 4-bit interface
+    write4bits(0x02 << 4);
+
+    // set # lines, font size, etc.
+    command(LCD_FUNCTIONSET | _displayfunction);
+
+    // turn the display on with no cursor or blinking default
+    _displaycontrol = LCD_DISPLAYON | LCD_CURSOROFF | LCD_BLINKOFF;
+    display();
+
+    // clear it off
+    clear();
+
+    // Initialize to default text direction (for roman languages)
+    _displaymode = LCD_ENTRYLEFT | LCD_ENTRYSHIFTDECREMENT;
+
+    // set the entry mode
+    command(LCD_ENTRYMODESET | _displaymode);
+
+    home();
+}
+
+/********** high level commands, for the user! */
+void LiquidCrystal_I2C::clear(){
+    command(LCD_CLEARDISPLAY);// clear display, set cursor position to zero
+    wait_us(2000);  // this command takes a long time!
+}
+
+void LiquidCrystal_I2C::home(){
+    command(LCD_RETURNHOME);  // set cursor position to zero
+    wait_us(2000);  // this command takes a long time!
+}
+
+void LiquidCrystal_I2C::setCursor(unsigned char col, unsigned char row){
+    int row_offsets[] = { 0x00, 0x40, 0x14, 0x54 };
+    if (row > _rows) {
+        row = _rows-1;    // we count rows starting w/0
+    }
+    command(LCD_SETDDRAMADDR | (col + row_offsets[row]));
+}
+
+// Turn the display on/off (quickly)
+void LiquidCrystal_I2C::noDisplay() {
+    _displaycontrol &= ~LCD_DISPLAYON;
+    command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+void LiquidCrystal_I2C::display() {
+    _displaycontrol |= LCD_DISPLAYON;
+    command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// Turns the underline cursor on/off
+void LiquidCrystal_I2C::noCursor() {
+    _displaycontrol &= ~LCD_CURSORON;
+    command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+void LiquidCrystal_I2C::cursor() {
+    _displaycontrol |= LCD_CURSORON;
+    command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// Turn on and off the blinking cursor
+void LiquidCrystal_I2C::noBlink() {
+    _displaycontrol &= ~LCD_BLINKON;
+    command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+void LiquidCrystal_I2C::blink() {
+    _displaycontrol |= LCD_BLINKON;
+    command(LCD_DISPLAYCONTROL | _displaycontrol);
+}
+
+// These commands scroll the display without changing the RAM
+void LiquidCrystal_I2C::scrollDisplayLeft(void) {
+    command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVELEFT);
+}
+void LiquidCrystal_I2C::scrollDisplayRight(void) {
+    command(LCD_CURSORSHIFT | LCD_DISPLAYMOVE | LCD_MOVERIGHT);
+}
+
+// This is for text that flows Left to Right
+void LiquidCrystal_I2C::leftToRight(void) {
+    _displaymode |= LCD_ENTRYLEFT;
+    command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This is for text that flows Right to Left
+void LiquidCrystal_I2C::rightToLeft(void) {
+    _displaymode &= ~LCD_ENTRYLEFT;
+    command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This will 'right justify' text from the cursor
+void LiquidCrystal_I2C::autoscroll(void) {
+    _displaymode |= LCD_ENTRYSHIFTINCREMENT;
+    command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// This will 'left justify' text from the cursor
+void LiquidCrystal_I2C::noAutoscroll(void) {
+    _displaymode &= ~LCD_ENTRYSHIFTINCREMENT;
+    command(LCD_ENTRYMODESET | _displaymode);
+}
+
+// Allows us to fill the first 8 CGRAM locations
+// with custom characters
+void LiquidCrystal_I2C::createChar(unsigned char location, unsigned char charmap[]) {
+    location &= 0x7; // we only have 8 locations 0-7
+    command(LCD_SETCGRAMADDR | (location << 3));
+    for (int i=0; i<8; i++) {
+        write(charmap[i]);
+    }
+}
+
+// Turn the (optional) backlight off/on
+void LiquidCrystal_I2C::noBacklight(void) {
+    _backlightval=LCD_NOBACKLIGHT;
+    expanderWrite(0);
+}
+
+void LiquidCrystal_I2C::backlight(void) {
+    _backlightval=LCD_BACKLIGHT;
+    expanderWrite(0);
+}
+bool LiquidCrystal_I2C::getBacklight() {
+  return _backlightval == LCD_BACKLIGHT;
+}
+
+
+/*********** mid level commands, for sending data/cmds */
+
+inline void LiquidCrystal_I2C::command(unsigned char value) {
+    send(value, 0);
+}
+
+inline int LiquidCrystal_I2C::write(unsigned char value) {
+    send(value, Rs);
+    return 1;
+}
+
+
+/************ low level data pushing commands **********/
+
+// write either command or data
+void LiquidCrystal_I2C::send(unsigned char value, unsigned char mode) {
+    unsigned char highnib=value&0xf0;
+    unsigned char lownib=(value<<4)&0xf0;
+    write4bits((highnib)|mode);
+    write4bits((lownib)|mode);
+}
+
+void LiquidCrystal_I2C::write4bits(unsigned char value) {
+    expanderWrite(value);
+    pulseEnable(value);
+}
+
+void LiquidCrystal_I2C::expanderWrite(unsigned char _data){
+    char data_write[2];
+    data_write[0] = _data | _backlightval;
+    //Wire.beginTransmission(_addr);
+    //Wire.write((int)(_data) | _backlightval);
+    //Wire.endTransmission();
+    _i2c.write(_addr, data_write, 1, 0);
+    _i2c.stop();
+}
+
+void LiquidCrystal_I2C::pulseEnable(unsigned char _data){
+    expanderWrite(_data | En);  // En high
+    wait_us(1);       // enable pulse must be >450ns
+
+    expanderWrite(_data & ~En); // En low
+    wait_us(50);      // commands need > 37us to settle
+}
+
+void LiquidCrystal_I2C::load_custom_character(unsigned char char_num, unsigned char *rows){
+    createChar(char_num, rows);
+}
+
+void LiquidCrystal_I2C::setBacklight(unsigned char new_val){
+    if (new_val) {
+        backlight();        // turn backlight on
+    } else {
+        noBacklight();      // turn backlight off
+    }
+}
+
+void LiquidCrystal_I2C::printstr(const char c[]){
+    //This function is not identical to the function used for "real" I2C displays
+    //it's here so the user sketch doesn't have to be changed
+    //print(c);
+}
+
+int LiquidCrystal_I2C::print(const char* text) {
+  
+  while (*text !=0) {
+    //_putc(*text);
+    send(*text, Rs);
+    text++;
+  }
+  return 0;
+}
+
+/*
+void lcd_dat(unsigned char p)
+{
+PORTC |= (1 << RS)|(1 << EN); // RS = 1, EN = 1 (начало записи команды в LCD)
+PORTD = p; // Вывод команды на шину DB0-7 LCD
+_delay_us(100); // Длительность сигнала EN
+PORTC &= ~(1 << EN); // EN = 0 (конец записи команды в LCD)
+_delay_us(100); // Пауза для выполнения команды
+}
+*/
\ No newline at end of file
diff -r 000000000000 -r f363e3d1f212 LiquidCrystal_I2C.h
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/LiquidCrystal_I2C.h	Wed Jul 03 09:51:08 2019 +0000
@@ -0,0 +1,165 @@
+#ifndef FDB_LIQUID_CRYSTAL_I2C_H
+#define FDB_LIQUID_CRYSTAL_I2C_H
+
+//#include <inttypes.h>
+//#include <Print.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
+
+// flags for backlight control
+#define LCD_BACKLIGHT 0x08
+#define LCD_NOBACKLIGHT 0x00
+
+#define En 0x04//B00000100  // Enable bit
+#define Rw 0x02 // B00000010  // Read/Write bit
+#define Rs 0x01 //B00000001  // Register select bit
+
+/**
+ * This is the driver for the Liquid Crystal LCD displays that use the I2C bus.
+ *
+ * After creating an instance of this class, first call begin() before anything else.
+ * The backlight is on by default, since that is the most likely operating mode in
+ * most cases.
+ */
+class LiquidCrystal_I2C  {
+public:
+    /**
+     * Constructor
+     *
+     * @param lcd_addr  I2C slave address of the LCD display. Most likely printed on the
+     *                  LCD circuit board, or look in the supplied LCD documentation.
+     * @param lcd_cols  Number of columns your LCD display has.
+     * @param lcd_rows  Number of rows your LCD display has.
+     * @param charsize  The size in dots that the display has, use LCD_5x10DOTS or LCD_5x8DOTS.
+     */
+    LiquidCrystal_I2C(unsigned char lcd_addr, unsigned char lcd_cols, unsigned char lcd_rows, unsigned char charsize = LCD_5x8DOTS);
+
+    /**
+     * Set the LCD display in the correct begin state, must be called before anything else is done.
+     */
+    void begin();
+
+     /**
+      * Remove all the characters currently shown. Next print/write operation will start
+      * from the first position on LCD display.
+      */
+    void clear();
+
+    /**
+     * Next print/write operation will will start from the first position on the LCD display.
+     */
+    void home();
+
+     /**
+      * Do not show any characters on the LCD display. Backlight state will remain unchanged.
+      * Also all characters written on the display will return, when the display in enabled again.
+      */
+    void noDisplay();
+
+    /**
+     * Show the characters on the LCD display, this is the normal behaviour. This method should
+     * only be used after noDisplay() has been used.
+     */
+    void display();
+
+    /**
+     * Do not blink the cursor indicator.
+     */
+    void noBlink();
+
+    /**
+     * Start blinking the cursor indicator.
+     */
+    void blink();
+
+    /**
+     * Do not show a cursor indicator.
+     */
+    void noCursor();
+
+    /**
+     * Show a cursor indicator, cursor can blink on not blink. Use the
+     * methods blink() and noBlink() for changing cursor blink.
+     */
+    void cursor();
+
+    void scrollDisplayLeft();
+    void scrollDisplayRight();
+    void printLeft();
+    void printRight();
+    void leftToRight();
+    void rightToLeft();
+    void shiftIncrement();
+    void shiftDecrement();
+    void noBacklight();
+    void backlight();
+    bool getBacklight();
+    void autoscroll();
+    void noAutoscroll();
+    void createChar(unsigned char, unsigned char[]);
+    void setCursor(unsigned char, unsigned char);
+    virtual int write(unsigned char);
+    void command(unsigned char);
+
+    inline void blink_on() { blink(); }
+    inline void blink_off() { noBlink(); }
+    inline void cursor_on() { cursor(); }
+    inline void cursor_off() { noCursor(); }
+
+// Compatibility API function aliases
+    void setBacklight(unsigned char new_val);             // alias for backlight() and nobacklight()
+    void load_custom_character(unsigned char char_num, unsigned char *rows);    // alias for createChar()
+    void printstr(const char[]);
+    int print(const char* text);
+private:
+    void send(unsigned char, unsigned char);
+    void write4bits(unsigned char);
+    void expanderWrite(unsigned char);
+    void pulseEnable(unsigned char);
+    unsigned char _addr;
+    unsigned char _displayfunction;
+    unsigned char _displaycontrol;
+    unsigned char _displaymode;
+    unsigned char _cols;
+    unsigned char _rows;
+    unsigned char _charsize;
+    unsigned char _backlightval;
+};
+
+#endif // FDB_LIQUID_CRYSTAL_I2C_H
\ No newline at end of file