Test of LCD code
lcd_i2c.cpp
- Committer:
- garyr
- Date:
- 2014-05-30
- Revision:
- 0:a4d44dfd2f03
File content as of revision 0:a4d44dfd2f03:
#include "mbed.h"
#include "lcd_i2c.h"
/*
LCD (Optrex DCM16230, DCM20261, etc.) via I2C using a PCF8574
Frequency (clks/sec) Frequency
Transfer rate = ------------------------------------------------ = ---------------- (characters/sec)
9 clks/write * 3 writes/nibble * 2 nibbles/character 54
*/
I2C i2c(p9, p10); // (sda, scl)
Serial pc2(USBTX, USBRX); // tx, rx
// PCF8574 output bits Px
#define RS BIT1
#define RW BIT2
#define E BIT3
#define DB4 BIT4
#define DB5 BIT5
#define DB6 BIT6
#define DB7 BIT7
char update[NUPDATE];
char cw, address;
int updateDisplay(char *str, int nchars)
{
char w, ch, *p;
int n, k, rc;
if (nchars > 20)
return 1;
n = 0;
p = update;
for (k = 0; k < nchars; k++)
{
// write most significant nibble
ch = *str++;
w = (ch & 0xf0) | cw;
*p++ = w;
*p++ = w | E;
*p++ = w;
// write least significant nibble
w = (ch << 4) | cw;
*p++ = w;
*p++ = w | E;
*p++ = w;
n += 6;
}
rc = i2c.write(address, update, n); // rc == 0 ==> ACK
return rc;
}
int write4Bits(char data)
{
char w;
int rc;
w = (data & 0xf0) | cw; // grab the left nibble
update[0] = w;
update[1] = w | E;
update[2] = w & ~ E;
rc = i2c.write(address, update, 3);
return rc;
}
int initLcd(int i2cAddress, int frequency)
{
typedef struct {
char cmd;
char numNibbles;
char delayMs;
//char testBF;
} INIT;
static const INIT initData[] = {
{3, 1, 5},
{3, 1, 1},
{3, 1, 1},
{2, 1, 1}, // Function set: 4-bit interface
{0x28, 2, 2}, // Function set: 2 lines, 5x7
{0x08, 2, 2}, // Display off
{0x01, 2, 16}, // Clear display
{0x06, 2, 2}, // Entry mode set: No increment, shift cursor
{0x0e, 2, 2}}; // Display on: cursor on, blink off
#define NINITD (sizeof(initData)/sizeof(initData[0]))
INIT *p;
int k, rc;
// Initialization must start at least 16 ms after power up.
i2c.frequency(frequency);
address = i2cAddress;
cw = 0;
p = (INIT *)initData;
for (k = 0; k < NINITD; k++)
{
//p = (INIT *)&initData[k];
if (p->numNibbles == 1)
rc = write4Bits(p->cmd << 4);
else
{
rc = write4Bits(p->cmd); // output the most significant nibble
wait_us(10); // this will need to be adjusted when printf stmts are removed
rc |= write4Bits(p->cmd << 4); // output the least significant nibble
}
if (rc)
break;
wait_ms(p->delayMs);
p++;
}
return rc;
}
int lcdWriteMsg(char *msg)
{ // msg must be a null-terminated string
char rc;
cw |= RS; // data
cw &= ~RW; // write
rc = updateDisplay(msg, strlen(msg));
return rc;
}
int lcdWriteCmd(char cmd, int delayMs)
{
int rc;
cw &= ~RS; // command
rc = write4Bits(cmd);
wait_us(10);
rc |= write4Bits(cmd << 4);
if (delayMs)
wait_ms(delayMs);
return rc;
}
int lcdPositionCursor(char row, char col)
{
// Code may not be correct for displays larger than 20 x 2
int x, rc;
x = 0x80 | ((row & 1)<<6) | (col & 0xf);
rc = lcdWriteCmd(x, 1);
return rc;
}
int lcdClearDisplay(void)
{
return lcdWriteCmd(1, 16);
}