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.
Diff: I2CTextLCD.cpp
- Revision:
- 9:16c12a5da0ac
- Parent:
- 8:4816fdd57607
--- a/I2CTextLCD.cpp Thu Dec 01 13:34:17 2011 +0000
+++ b/I2CTextLCD.cpp Tue Oct 15 10:44:20 2013 +0000
@@ -10,32 +10,6 @@
using namespace mbed;
-/*
- * useful info found at http://www.a-netz.de/lcd.en.php
- *
- *
- * Initialisation
- * ==============
- *
- * After attaching the supply voltage/after a reset, the display needs to be brought in to a defined state
- *
- * - wait approximately 15 ms so the display is ready to execute commands
- * - Execute the command 0x30 ("Display Settings") three times (wait 1,64ms after each command, the busy flag cannot be queried now).
- * - The display is in 8 bit mode, so if you have only connected 4 data pins you should only transmit the higher nibble of each command.
- * - If you want to use the 4 bit mode, now you can execute the command to switch over to this mode now.
- * - Execute the "clear display" command
- *
- * Timing
- * ======
- *
- * Nearly all commands transmitted to the display need 40us for execution.
- * Exceptions are the commands "Clear Display and Reset" and "Set Cursor to Start Position"
- * These commands need 1.64ms for execution. These timings are valid for all displays working with an
- * internal clock of 250kHz. But I do not know any displays that use other frequencies. Any time you
- * can use the busy flag to test if the display is ready to accept the next command.
- *
- */
-
I2CTextLCD::I2CTextLCD(PinName sda, PinName scl, int i2cAddress , int columns, int rows,
bool backlight) : _i2c(sda, scl) {
@@ -44,52 +18,33 @@
_rows = rows;
_backlight=backlight;
_i2c.frequency(70000); // RC:2011-12-1 put this back in
- // Winstar 20x4 WH2004-NYG- needs 40ms after VDD> 4,5V
- /*
- wait(0.5);
- writeCommand(0x2); // 4-bit mode
- wait(0.05);
- writeCommand(0x28); // Function set 001 BW N F - -
- wait(0.05);
- */
+
+ // Winstar 20x4 WH2004-NYG- needs 40ms after VDD> 4,5V
//RC:2011-11-23: Newhaven 20x4 OLED data sheet method
- writeCommand(0x2); // 4-bit mode
+ wait(0.055);
+ init8574A(); // I2C chip PCF85774A init - E high - E falls with 0x2 on the D-nibble (set 4-bit mode command)
+ writeCommand(0x2); // 4-bit mode
wait(0.05);
- writeCommand(0x2); // 4-bit mode
+ writeCommand(0x2); // 4-bit mode
wait(0.05);
- writeCommand(0x28); // display OFF, "Function Set". Newhaven say 0x08, but this loses 2 rows!
+ writeCommand(0x2A); // 2012-6-22 RC: Russian font Table. was 0x28. display OFF, "Function Set". Newhaven say 0x08, but this loses 2 rows!
wait(0.05);
- writeCommand(0x1); // display clear
+ writeCommand(0x1); // display clear
wait(0.05);
- writeCommand(0x6); // entry mode set
+ writeCommand(0x6); // entry mode set
wait(0.05);
- writeCommand(0x2); // 4-bit mode
+ writeCommand(0x2); // 4-bit mode
wait(0.05);
writeCommand(0x0C); // ON-OFF ctrl: turns display ON, no cursor. Use 0x0E for cursor ON.
- /* 0x28 also works for Winstar WEH002004ALPP5N00000 OLED display. 0x29= westEuro fon table, 0x2A = UK/Russian
-*/
- // Added RC 2011-8-11
- /*
- writeCommand(0x05); // clear display RAM all to 00
- wait(0.05); // 6.2ms specified for OLED display to recover from RAM clear
-
- writeCommand(0x06); // Entry mode Set. Cursor Direction and Display Shift : 0000 01 CD S (CD 0-left, 1-right S(hift) 0-no, 1-yes
- wait(0.05);
- writeCommand(0x14); // OLED display shift disable etc
- wait(0.05);
- writeCommand(0x17); // disable graphic mode, power ON
- //cls();
- wait(0.05);
- writeCommand (0x01); //clear entire display.
- wait(0.07);
-*/
-
+ /* 0x28 also works for Winstar WEH002004ALPP5N00000 OLED display. 0x29= westEuro fon table, 0x2A = UK/Russian*/
+ wait(0.015); // Wait 15ms to ensure powered up
}
int I2CTextLCD::_putc(int value) {
if (value == '\n') {
newline();
- } else {
+ }
+ else {
writeData(value);
}
return value;
@@ -155,51 +110,41 @@
void I2CTextLCD::reset() {
cls();
}
-
-void I2CTextLCD::writeByte(int c, bool rs) { // This is the actual I2C transfer of the display data:
- char cmd[2]; //led = 1;
- cmd[0]=c>>2; // upper nibble
- cmd[0]=cmd[0] & 0x3c; // mask out bits other than 5:2 for data (RS and E are enabled separately, below:)
- cmd[1]=c<<2; // lower nibble
- cmd[1]=cmd[1] & 0x3c;
- if (rs) {
- cmd[0]=cmd[0] | 0x01; // RS selects display DATA or a COMMAND. It's on bit 0:
- cmd[1]=cmd[1] | 0x01;
- }
- _i2c.write( _i2cAddress,cmd,1); // E=0, write upper nibble. E's on bit 1!
- wait_us(1);
+void I2CTextLCD::init8574A(void) { // This puts the first command on the bus with E high
+ // to prevent E going LOW at init with undef data lines, WS0010 does not like.
+ char cmd[2];
+ cmd[0]=(0x2)<<2; // lower nibble
+ cmd[0]=cmd[0] & 0x3c; // 3C = 0011 1100
+ //RS = 0 for commands - and for init (only), we start with E high
cmd[0]=cmd[0]|0x02; //E=1
_i2c.write( _i2cAddress, cmd,1);
- wait_us(1);
cmd[0]=cmd[0]&0x3d; //E=0, RS preserved in bit 0
_i2c.write( _i2cAddress, cmd,1);
wait_us(1);
- cmd[0]=cmd[1]; //E=0, write lower nibble
- wait_us(1);
+ }
+void I2CTextLCD::writeByte(int c, bool rs) { // This is the actual I2C transfer of the display data:
+ char cmd[2];
+ cmd[0]=c>>2; // upper nibble
+ cmd[0]=cmd[0] & 0x3c; // mask out bits other than 5:2 for data (RS and E are enabled separately, below:)
+ cmd[1]=c<<2; // lower nibble
+ cmd[1]=cmd[1] & 0x3c; // 3C = 0011 1100
+ if (rs) {
+ cmd[0]=cmd[0] | 0x01; // RS selects display DATA or a COMMAND. It's on bit 0:
+ cmd[1]=cmd[1] | 0x01;
+ }
cmd[0]=cmd[0]|0x02; //E=1
_i2c.write( _i2cAddress, cmd,1);
- wait_us(1);
- cmd[0]=cmd[0]&0x3d; //E=0, RS preserved in bit 0
+ //wait_us(1); ** delays between nibbles not needed. At 70kHz, the time for the I2C command writes is 114us per byte
+ cmd[0]=cmd[0]&0x3d; //E=0, RS preserved in bit 0. Data latched on fall of E (tS(d) = 40ns; tH(d) = 20ns)
+ _i2c.write( _i2cAddress, cmd,1);
+ cmd[0]=cmd[1]; // prepare lower nibble
+ cmd[0]=cmd[0]|0x02; //E=1
+ _i2c.write( _i2cAddress, cmd,1);
+ cmd[0]=cmd[0]&0x3d; //E=0, RS preserved in bit 0. this preserves E low beween cycles.
_i2c.write( _i2cAddress, cmd,1);
- _i2c.write ( _i2cAddress,cmd,1);
- // led = 0;
- wait_us(1);
+ // ****** RECOVERY TIME:
+ wait_us(300); // specified max. recovery time for all operations, except cls(), is 600us
}
- // This is the original authors method:
- //void I2CTextLCD::writeByte(int data, bool rs) {
-
-
-/*
- writeNibble(data >> 4 , rs);
- writeNibble(data >> 0 , rs);
- RC 2011-8-11. change to d4..d7 - PCF8574 ports P2 .. P5
-*/
-//data = data>>2;
-//data = data & 0x3c;
-//writeNibble(data , rs);
-//data = data<<2;
-//data = data & 0x3c;
-//writeNibble(data , rs);
void I2CTextLCD::writeCommand(int command) {
// RS = 0;
@@ -214,17 +159,4 @@
if (_column >= _columns) {
newline();
}
-}
-
-/* void I2CTextLCD::writeI2CByte(int data) {
- char cmd[2];
- cmd[0] = (data & 0xFF);
- cmd[1] = (data >> 8);
- _i2c.write(_i2cAddress, cmd, 2);
-*/
-
-
-
-
-
-
+}
\ No newline at end of file