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
- Committer:
- RodColeman
- Date:
- 2013-10-15
- Revision:
- 9:16c12a5da0ac
- Parent:
- 8:4816fdd57607
File content as of revision 9:16c12a5da0ac:
/* mbed I2CTextLCD Library
* Copyright (c) 2007-2009 sford
* Copyright (c) 2010 Wim De Roeve changed to work with I2C PCF8575
* Released under the MIT License: http://mbed.org/license/mit
*/
#include "I2CTextLCD.h"
#include "mbed.h"
#include "error.h"
using namespace mbed;
I2CTextLCD::I2CTextLCD(PinName sda, PinName scl, int i2cAddress , int columns, int rows,
bool backlight) : _i2c(sda, scl) {
_i2cAddress = i2cAddress;
_columns = columns;
_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
//RC:2011-11-23: Newhaven 20x4 OLED data sheet method
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
wait(0.05);
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
wait(0.05);
writeCommand(0x6); // entry mode set
wait(0.05);
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*/
wait(0.015); // Wait 15ms to ensure powered up
}
int I2CTextLCD::_putc(int value) {
if (value == '\n') {
newline();
}
else {
writeData(value);
}
return value;
}
int I2CTextLCD::_getc() {
return 0;
}
/* void I2CTextLCD::backlight(bool status) {
_backlight=status;
if (_backlight)
writeI2CByte(BACKLIGHT_ON | E1_ON);
else
writeI2CByte(E1_ON);
}
*/
void I2CTextLCD::newline() {
_column = 0;
_row++;
if (_row >= _rows) {
_row = 0;
}
locate(_column, _row);
}
void I2CTextLCD::locate(int column, int row) {
if (column < 0 || column >= _columns || row < 0 || row >= _rows) {
error("locate(%d,%d) out of range on %dx%d display", column, row, _columns, _rows);
return;
}
_row = row;
_column = column;
int address = 0x80;
if (row==0){
address = 0x80+_column;
}
else if (row==1){
address= 0xc0+_column;
}
else if (row==2){
address=0x94+_column;
}
else if(row==3){
address=0xd4+_column;
}
/*
int address = 0x80 + (_row * 40) + _column; // memory starts at 0x00, and is 40 chars long per row
Set bit 7 also, to signify ADDRESS SET mode.
// pc_LCD.traceOut("locate %dx%d\r\n", column, row);
*/
writeCommand(address); // must set bit 7 to indicate address SET command
wait(0.004); // takes 1.5ms on Winstar LCD 20x4
}
void I2CTextLCD::cls() {
writeCommand(0x01); // Clear Display
wait(0.01f); // This command takes 1.64 ms (LCD), 6.2ms for Winstar OLED
locate(0, 0);
}
void I2CTextLCD::reset() {
cls();
}
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);
cmd[0]=cmd[0]&0x3d; //E=0, RS preserved in bit 0
_i2c.write( _i2cAddress, cmd,1);
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); ** 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);
// ****** RECOVERY TIME:
wait_us(300); // specified max. recovery time for all operations, except cls(), is 600us
}
void I2CTextLCD::writeCommand(int command) {
// RS = 0;
writeByte(command,false);
}
void I2CTextLCD::writeData(int data) {
//RS = 1
writeByte(data,true);
_column++;
if (_column >= _columns) {
newline();
}
}