Embed:
(wiki syntax)
Show/hide line numbers
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