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.
I2CTextLCD.cpp
00001 /* mbed I2CTextLCD Library 00002 * Copyright (c) 2007-2009 sford 00003 * Copyright (c) 2010 Wim De Roeve changed to work with I2C PCF8575 00004 * Released under the MIT License: http://mbed.org/license/mit 00005 */ 00006 00007 #include "I2CTextLCD.h" 00008 #include "mbed.h" 00009 #include "error.h" 00010 00011 using namespace mbed; 00012 00013 I2CTextLCD::I2CTextLCD(PinName sda, PinName scl, int i2cAddress , int columns, int rows, 00014 bool backlight) : _i2c(sda, scl) { 00015 00016 _i2cAddress = i2cAddress; 00017 _columns = columns; 00018 _rows = rows; 00019 _backlight=backlight; 00020 _i2c.frequency(70000); // RC:2011-12-1 put this back in 00021 00022 // Winstar 20x4 WH2004-NYG- needs 40ms after VDD> 4,5V 00023 //RC:2011-11-23: Newhaven 20x4 OLED data sheet method 00024 wait(0.055); 00025 init8574A(); // I2C chip PCF85774A init - E high - E falls with 0x2 on the D-nibble (set 4-bit mode command) 00026 writeCommand(0x2); // 4-bit mode 00027 wait(0.05); 00028 writeCommand(0x2); // 4-bit mode 00029 wait(0.05); 00030 writeCommand(0x2A); // 2012-6-22 RC: Russian font Table. was 0x28. display OFF, "Function Set". Newhaven say 0x08, but this loses 2 rows! 00031 wait(0.05); 00032 writeCommand(0x1); // display clear 00033 wait(0.05); 00034 writeCommand(0x6); // entry mode set 00035 wait(0.05); 00036 writeCommand(0x2); // 4-bit mode 00037 wait(0.05); 00038 writeCommand(0x0C); // ON-OFF ctrl: turns display ON, no cursor. Use 0x0E for cursor ON. 00039 /* 0x28 also works for Winstar WEH002004ALPP5N00000 OLED display. 0x29= westEuro fon table, 0x2A = UK/Russian*/ 00040 wait(0.015); // Wait 15ms to ensure powered up 00041 } 00042 00043 int I2CTextLCD::_putc(int value) { 00044 if (value == '\n') { 00045 newline(); 00046 } 00047 else { 00048 writeData(value); 00049 } 00050 return value; 00051 } 00052 00053 int I2CTextLCD::_getc() { 00054 return 0; 00055 } 00056 00057 /* void I2CTextLCD::backlight(bool status) { 00058 _backlight=status; 00059 if (_backlight) 00060 writeI2CByte(BACKLIGHT_ON | E1_ON); 00061 else 00062 writeI2CByte(E1_ON); 00063 } 00064 */ 00065 00066 void I2CTextLCD::newline() { 00067 _column = 0; 00068 _row++; 00069 if (_row >= _rows) { 00070 _row = 0; 00071 } 00072 locate(_column, _row); 00073 } 00074 00075 void I2CTextLCD::locate(int column, int row) { 00076 if (column < 0 || column >= _columns || row < 0 || row >= _rows) { 00077 error("locate(%d,%d) out of range on %dx%d display", column, row, _columns, _rows); 00078 return; 00079 } 00080 _row = row; 00081 _column = column; 00082 int address = 0x80; 00083 if (row==0){ 00084 address = 0x80+_column; 00085 } 00086 else if (row==1){ 00087 address= 0xc0+_column; 00088 } 00089 else if (row==2){ 00090 address=0x94+_column; 00091 } 00092 else if(row==3){ 00093 address=0xd4+_column; 00094 } 00095 /* 00096 int address = 0x80 + (_row * 40) + _column; // memory starts at 0x00, and is 40 chars long per row 00097 Set bit 7 also, to signify ADDRESS SET mode. 00098 // pc_LCD.traceOut("locate %dx%d\r\n", column, row); 00099 */ 00100 writeCommand(address); // must set bit 7 to indicate address SET command 00101 wait(0.004); // takes 1.5ms on Winstar LCD 20x4 00102 } 00103 00104 void I2CTextLCD::cls() { 00105 writeCommand(0x01); // Clear Display 00106 wait(0.01f); // This command takes 1.64 ms (LCD), 6.2ms for Winstar OLED 00107 locate(0, 0); 00108 } 00109 00110 void I2CTextLCD::reset() { 00111 cls(); 00112 } 00113 void I2CTextLCD::init8574A(void) { // This puts the first command on the bus with E high 00114 // to prevent E going LOW at init with undef data lines, WS0010 does not like. 00115 char cmd[2]; 00116 cmd[0]=(0x2)<<2; // lower nibble 00117 cmd[0]=cmd[0] & 0x3c; // 3C = 0011 1100 00118 //RS = 0 for commands - and for init (only), we start with E high 00119 cmd[0]=cmd[0]|0x02; //E=1 00120 _i2c.write( _i2cAddress, cmd,1); 00121 cmd[0]=cmd[0]&0x3d; //E=0, RS preserved in bit 0 00122 _i2c.write( _i2cAddress, cmd,1); 00123 wait_us(1); 00124 } 00125 void I2CTextLCD::writeByte(int c, bool rs) { // This is the actual I2C transfer of the display data: 00126 char cmd[2]; 00127 cmd[0]=c>>2; // upper nibble 00128 cmd[0]=cmd[0] & 0x3c; // mask out bits other than 5:2 for data (RS and E are enabled separately, below:) 00129 cmd[1]=c<<2; // lower nibble 00130 cmd[1]=cmd[1] & 0x3c; // 3C = 0011 1100 00131 if (rs) { 00132 cmd[0]=cmd[0] | 0x01; // RS selects display DATA or a COMMAND. It's on bit 0: 00133 cmd[1]=cmd[1] | 0x01; 00134 } 00135 cmd[0]=cmd[0]|0x02; //E=1 00136 _i2c.write( _i2cAddress, cmd,1); 00137 //wait_us(1); ** delays between nibbles not needed. At 70kHz, the time for the I2C command writes is 114us per byte 00138 cmd[0]=cmd[0]&0x3d; //E=0, RS preserved in bit 0. Data latched on fall of E (tS(d) = 40ns; tH(d) = 20ns) 00139 _i2c.write( _i2cAddress, cmd,1); 00140 cmd[0]=cmd[1]; // prepare lower nibble 00141 cmd[0]=cmd[0]|0x02; //E=1 00142 _i2c.write( _i2cAddress, cmd,1); 00143 cmd[0]=cmd[0]&0x3d; //E=0, RS preserved in bit 0. this preserves E low beween cycles. 00144 _i2c.write( _i2cAddress, cmd,1); 00145 // ****** RECOVERY TIME: 00146 wait_us(300); // specified max. recovery time for all operations, except cls(), is 600us 00147 } 00148 00149 void I2CTextLCD::writeCommand(int command) { 00150 // RS = 0; 00151 writeByte(command,false); 00152 } 00153 00154 void I2CTextLCD::writeData(int data) { 00155 //RS = 1 00156 writeByte(data,true); 00157 00158 _column++; 00159 if (_column >= _columns) { 00160 newline(); 00161 } 00162 }
Generated on Thu Sep 22 2022 10:55:42 by
1.7.2