Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
TextLCD.cpp
00001 /* mbed I2CTextLCD Library, for a 4-bit LCD driven by I2C and a PCF8574 00002 * Copyright (c) 2007-2010, sford, rcocking 00003 * 00004 * Permission is hereby granted, free of charge, to any person obtaining a copy 00005 * of this software and associated documentation files (the "Software"), to deal 00006 * in the Software without restriction, including without limitation the rights 00007 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 * copies of the Software, and to permit persons to whom the Software is 00009 * furnished to do so, subject to the following conditions: 00010 * 00011 * The above copyright notice and this permission notice shall be included in 00012 * all copies or substantial portions of the Software. 00013 * 00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 * THE SOFTWARE. 00021 */ 00022 00023 /* This is a hack of Simon Ford's direct-driven TextLCD code. 00024 * It should be refactored to extract a common superclass 00025 * but my C++ isn't yet good enough :) 00026 * 00027 * The code assumes the following connections between the PCF8574 00028 * and the LCD 00029 * 00030 * nc - D0 00031 * nc - D1 00032 * nc - D2 00033 * nc - D3 00034 * P0 - D4 00035 * P1 - D5 00036 * P2 - D6 00037 * P3 - D7 00038 * P4 - E 00039 * P5 - nc 00040 * P6 - nc 00041 * P7 - RS 00042 * gnd - R/W 00043 * 00044 * D0-3 of the LCD are not connected because we work in 4-bit mode 00045 * R/W is hardwired to gound, as we only ever write to the LCD 00046 * A0-2 on the PCF8574 can be set in any combination; you will need to modify 00047 * the I2C address in the I2CTextLCD constructor. 00048 * Remember that the mbed uses 8-bit addresses, which should be 00049 * in the range 0x40-0x4E for the PCF8574 00050 */ 00051 #include "TextLCD.h" 00052 #include "mbed.h" 00053 00054 TextLCD::TextLCD(PinName sda, PinName scl, int i2cAddress, LCDType type) : _i2c(sda, scl), 00055 _type(type) { 00056 _i2cAddress = i2cAddress; 00057 wait(0.015); // Wait 15ms to ensure powered up 00058 00059 // send "Display Settings" 3 times (Only top nibble of 0x30 as we've got 4-bit bus) 00060 for (int i=0; i<3; i++) { 00061 writeByte(0x3, false); 00062 wait(0.00164); // this command takes 1.64ms, so wait for it 00063 } 00064 writeByte(0x2, false); // 4-bit mode 00065 wait(0.000040f); // most instructions take 40us 00066 00067 writeCommand(0x28); // Function set 001 BW N F - - 00068 writeCommand(0x0C); 00069 writeCommand(0x6); // Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes 00070 cls(); 00071 } 00072 00073 void TextLCD::character(int column, int row, int c) { 00074 int a = address(column, row); 00075 writeCommand(a); 00076 writeData(c); 00077 } 00078 00079 void TextLCD::cls() { 00080 writeCommand(0x01); // cls, and set cursor to 0 00081 wait(0.00164f); // This command takes 1.64 ms 00082 locate(0, 0); 00083 } 00084 00085 void TextLCD::locate(int column, int row) { 00086 _column = column; 00087 _row = row; 00088 } 00089 00090 int TextLCD::_putc(int value) { 00091 if (value == '\n') { 00092 _column = 0; 00093 _row++; 00094 if (_row >= rows()) { 00095 _row = 0; 00096 } 00097 } else { 00098 character(_column, _row, value); 00099 _column++; 00100 if (_column >= columns()) { 00101 _column = 0; 00102 _row++; 00103 if (_row >= rows()) { 00104 _row = 0; 00105 } 00106 } 00107 } 00108 return value; 00109 } 00110 00111 int TextLCD::_getc() { 00112 return -1; 00113 } 00114 00115 void TextLCD::writeI2CByte(int data) { 00116 // equivalent to writeI2CByte 00117 char * cmd = new char[1]; 00118 cmd[0] = data; 00119 _i2c.write(_i2cAddress, cmd, 1); 00120 } 00121 00122 void TextLCD::writeNibble(int data, bool rs) { 00123 if (rs) { 00124 data = data | RS_ON; // set rs bit 00125 } 00126 data |= E_ON; // E on 00127 writeI2CByte(data); 00128 data ^= E_ON; // E off 00129 wait_us(1); 00130 writeI2CByte(data); 00131 wait_us(1000); 00132 } 00133 00134 void TextLCD::writeByte(int data, bool rs) { 00135 writeNibble(data >> 4, rs); 00136 writeNibble(data & 0x0F, rs); 00137 } 00138 00139 void TextLCD::writeCommand(int command) { 00140 // equivalent to ard commandWrite 00141 writeByte(command, false); 00142 } 00143 00144 void TextLCD::writeData(int data) { 00145 00146 writeByte(data, true); 00147 } 00148 00149 int TextLCD::address(int column, int row) { 00150 switch (_type) { 00151 case LCD20x4: 00152 switch (row) { 00153 case 0: 00154 return 0x80 + column; 00155 case 1: 00156 return 0xc0 + column; 00157 case 2: 00158 return 0x94 + column; 00159 case 3: 00160 return 0xd4 + column; 00161 } 00162 case LCD16x2B: 00163 return 0x80 + (row * 40) + column; 00164 case LCD16x2: 00165 case LCD20x2: 00166 default: 00167 return 0x80 + (row * 0x40) + column; 00168 } 00169 } 00170 00171 int TextLCD::columns() { 00172 switch (_type) { 00173 case LCD20x4: 00174 case LCD20x2: 00175 return 20; 00176 case LCD16x2: 00177 case LCD16x2B: 00178 default: 00179 return 16; 00180 } 00181 } 00182 00183 int TextLCD::rows() { 00184 switch (_type) { 00185 case LCD20x4: 00186 return 4; 00187 case LCD16x2: 00188 case LCD16x2B: 00189 case LCD20x2: 00190 default: 00191 return 2; 00192 } 00193 }
Generated on Tue Jul 12 2022 12:54:10 by
1.7.2