Updated for more display types. Fixed memoryaddress confusion in address() method. Added new getAddress() method. Added support for UDCs, Backlight control and other features such as control through I2C and SPI port expanders and controllers with native I2C and SPI interfaces. Refactored to fix issue with pins that are default declared as NC.
Dependents: GPSDevice TestTextLCD SD to Flash Data Transfer DrumMachine ... more
Fork of TextLCD by
Example
Hello World! for the TextLCD
#include "mbed.h" #include "TextLCD.h" // Host PC Communication channels Serial pc(USBTX, USBRX); // tx, rx // I2C Communication I2C i2c_lcd(p28,p27); // SDA, SCL // SPI Communication SPI spi_lcd(p5, NC, p7); // MOSI, MISO, SCLK //TextLCD lcd(p15, p16, p17, p18, p19, p20); // RS, E, D4-D7, LCDType=LCD16x2, BL=NC, E2=NC, LCDTCtrl=HD44780 //TextLCD_SPI lcd(&spi_lcd, p8, TextLCD::LCD40x4); // SPI bus, 74595 expander, CS pin, LCD Type TextLCD_I2C lcd(&i2c_lcd, 0x42, TextLCD::LCD20x4); // I2C bus, PCF8574 Slaveaddress, LCD Type //TextLCD_I2C lcd(&i2c_lcd, 0x42, TextLCD::LCD16x2, TextLCD::WS0010); // I2C bus, PCF8574 Slaveaddress, LCD Type, Device Type //TextLCD_SPI_N lcd(&spi_lcd, p8, p9); // SPI bus, CS pin, RS pin, LCDType=LCD16x2, BL=NC, LCDTCtrl=ST7032_3V3 //TextLCD_I2C_N lcd(&i2c_lcd, ST7032_SA, TextLCD::LCD16x2, NC, TextLCD::ST7032_3V3); // I2C bus, Slaveaddress, LCD Type, BL=NC, LCDTCtrl=ST7032_3V3 int main() { pc.printf("LCD Test. Columns=%d, Rows=%d\n\r", lcd.columns(), lcd.rows()); for (int row=0; row<lcd.rows(); row++) { int col=0; pc.printf("MemAddr(Col=%d, Row=%d)=0x%02X\n\r", col, row, lcd.getAddress(col, row)); // lcd.putc('-'); lcd.putc('0' + row); for (col=1; col<lcd.columns()-1; col++) { lcd.putc('*'); } pc.printf("MemAddr(Col=%d, Row=%d)=0x%02X\n\r", col, row, lcd.getAddress(col, row)); lcd.putc('+'); } // Show cursor as blinking character lcd.setCursor(TextLCD::CurOff_BlkOn); // Set and show user defined characters. A maximum of 8 UDCs are supported by the HD44780. // They are defined by a 5x7 bitpattern. lcd.setUDC(0, (char *) udc_0); // Show |> lcd.putc(0); lcd.setUDC(1, (char *) udc_1); // Show <| lcd.putc(1); }
Handbook page
More info is here
Diff: TextLCD.cpp
- Revision:
- 17:652ab113bc2e
- Parent:
- 16:c276b75e6585
- Child:
- 18:bd65dc10f27f
--- a/TextLCD.cpp Wed Feb 20 19:37:53 2013 +0000 +++ b/TextLCD.cpp Sat Mar 02 16:51:01 2013 +0000 @@ -3,6 +3,7 @@ * 2013, v01: WH, Added LCD types, fixed LCD address issues, added Cursor and UDCs * 2013, v02: WH, Added I2C and SPI bus interfaces * 2013, v03: WH, Added support for LCD40x4 which uses 2 controllers + * 2013, v04: WH, Added support for Display On/Off, improved 4bit bootprocess * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -151,6 +152,18 @@ wait_ms(20); // Wait 20ms to ensure powered up +#if(1) + // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus) + for (int i=0; i<3; i++) { + _writeNibble(0x3); + wait_ms(15); // this command takes 1.64ms, so wait for it + } + _writeNibble(0x2); // 4-bit mode + wait_us(40); // most instructions take 40us +#else +//Original code. Does not comply with specification and causes problems +//unless used right after power-on. + // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus) for (int i=0; i<3; i++) { _writeByte(0x3); @@ -158,6 +171,7 @@ } _writeByte(0x2); // 4-bit mode wait_us(40); // most instructions take 40us +#endif // Display is now in 4-bit mode switch (_type) { @@ -214,9 +228,9 @@ // S=0 (No display shift) // _writeCommand(0x0C); // Display Ctrl 0000 1 D C B -// // Display On, Cursor Off, Blink Off +// // Display On, Cursor Off, Blink Off setCursor(TextLCD::CurOff_BlkOff); - + setMode(TextLCD::DispOn); } @@ -228,7 +242,7 @@ _ctrl=TextLCD::_LCDCtrl_1; // Select 2nd controller // Second LCD controller Cursor always Off - _setCursor(TextLCD::CurOff_BlkOff); + _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff); // Second LCD controller Clearscreen _writeCommand(0x01); // cls, and set cursor to 0 @@ -248,7 +262,7 @@ // Restore cursormode on primary LCD controller when needed if(_type==LCD40x4) { - _setCursor(_currentCursor); + _setCursorAndDisplayMode(_currentMode,_currentCursor); } _row=0; // Reset Cursor location @@ -499,6 +513,22 @@ } +// Write a nibble using the 4-bit interface +// Used for mbed pins, I2C bus expander or SPI shifregister +void TextLCD::_writeNibble(int value) { + +// Enable is Low + _setEnable(true); + _setData(value & 0x0F); // Low nibble + wait_us(1); // Data setup time + _setEnable(false); + wait_us(1); // Datahold time + +// Enable is Low + +} + + // Write a byte using the 4-bit interface // Used for mbed pins, I2C bus expander or SPI shifregister void TextLCD::_writeByte(int value) { @@ -656,14 +686,15 @@ if (row<2) { // Test to see if we need to switch between controllers if (_ctrl != _LCDCtrl_0) { + // Second LCD controller Cursor Off - _setCursor(TextLCD::CurOff_BlkOff); + _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff); // Select primary controller _ctrl = _LCDCtrl_0; // Restore cursormode on primary LCD controller - _setCursor(_currentCursor); + _setCursorAndDisplayMode(_currentMode, _currentCursor); } return 0x00 + (row * 0x40) + column; @@ -673,13 +704,13 @@ // Test to see if we need to switch between controllers if (_ctrl != _LCDCtrl_1) { // Primary LCD controller Cursor Off - _setCursor(TextLCD::CurOff_BlkOff); + _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff); // Select secondary controller _ctrl = _LCDCtrl_1; // Restore cursormode on secondary LCD controller - _setCursor(_currentCursor); + _setCursorAndDisplayMode(_currentMode, _currentCursor); } return 0x00 + ((row-2) * 0x40) + column; @@ -784,37 +815,66 @@ } -void TextLCD::setCursor(TextLCD::LCDCursor show) { +// Set the Cursor Mode (Cursor Off & Blink Off, Cursor On & Blink Off, Cursor Off & Blink On, Cursor On & Blink On +void TextLCD::setCursor(TextLCD::LCDCursor cursorMode) { - // Save new cursor mode, needed when 2 controllers are in use - _currentCursor = show; + // Save new cursor mode, needed when 2 controllers are in use or when display is switched off/on + _currentCursor = cursorMode; - // Configure current LCD controller - _setCursor(_currentCursor); + // Configure only current LCD controller + _setCursorAndDisplayMode(_currentMode, _currentCursor); } -void TextLCD::_setCursor(TextLCD::LCDCursor show) { +// Set the Displaymode (On/Off) +void TextLCD::setMode(TextLCD::LCDMode displayMode) { + + // Save new displayMode, needed when 2 controllers are in use or when cursor is changed + _currentMode = displayMode; - // Configure current LCD controller - switch (show) { - case CurOff_BlkOff : _writeCommand(0x0C); // Cursor off and Blink Off - break; + // Select and configure second LCD controller when needed + if(_type==LCD40x4) { + if (_ctrl==TextLCD::_LCDCtrl_0) { + // Configure primary LCD controller + _setCursorAndDisplayMode(_currentMode, _currentCursor); - case CurOn_BlkOff : _writeCommand(0x0E); // Cursor on and Blink Off - break; + // Select 2nd controller + _ctrl=TextLCD::_LCDCtrl_1; + + // Configure secondary LCD controller + _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff); - case CurOff_BlkOn : _writeCommand(0x0D); // Cursor off and Blink On - break; + // Restore current controller + _ctrl=TextLCD::_LCDCtrl_0; + } + else { + // Select primary controller + _ctrl=TextLCD::_LCDCtrl_0; + + // Configure primary LCD controller + _setCursorAndDisplayMode(_currentMode, TextLCD::CurOff_BlkOff); + + // Restore current controller + _ctrl=TextLCD::_LCDCtrl_1; - case CurOn_BlkOn : _writeCommand(0x0F); // Cursor on and Blink char - break; + // Configure secondary LCD controller + _setCursorAndDisplayMode(_currentMode, _currentCursor); -// Should never get here. - default : - break; - } + } + else { + // Configure primary LCD controller + _setCursorAndDisplayMode(_currentMode, _currentCursor); + } + +} + + +// Set the Displaymode (On/Off) and Cursortype for current controller +void TextLCD::_setCursorAndDisplayMode(TextLCD::LCDMode displayMode, TextLCD::LCDCursor cursorType) { + + // Configure current LCD controller + _writeCommand(0x08 | displayMode | cursorType); }