EmbeddedRelated.com
Forums

NXP PCF8576C Segmented LCD Controller Interface Problems

Started by one00100100 February 1, 2013
I am using I2C to interface to the lcd controller. We are using the MSP430F5438A chip and the full IAR workbench. I have a scope on the data and clk lines. The scope seems to verify that start and stop conditions are correct. Further, when I send the slave address, the scope shows data signals l,h,h,h,l,l,l,l when clk is h (high). I am sending 0x70 which is 01110000. This all seems correct, but I do not get an ack. If I send 0x68 or 0x74, which are incorrect, I get an ack. According to their data sheet, the slave address is: 011100 (sao) and the r/w bit is set to 0. We have sao tied to ground, so it should be 0, giving 01110000 as the correct slave address. Does anyone see what I'm doing wrong?

Their literature is not at all clear (at least, to me) but it seems to say that the first thing I should send to this device is the slave address, then the device select command with the continuation bit clear, (0x60). (A0, A1, and A0 are tied to ground.), then send the data bytes. Has anyone had experience with this device that might help me with this?

Thanks,
Mike Raines

Beginning Microcontrollers with the MSP430

> I am using I2C to interface to the lcd controller. We are using the
> MSP430F5438A chip and the full IAR workbench. I have a scope on the data
> and clk lines. The scope seems to verify that start and stop conditions
> are correct. Further, when I send the slave address, the scope shows data
> signals l,h,h,h,l,l,l,l when clk is h (high). I am sending 0x70 which is
> 01110000. This all seems correct, but I do not get an ack. If I send
> 0x68 or 0x74, which are incorrect, I get an ack. According to their data
> sheet, the slave address is: 011100 (sao) and the r/w bit is set to 0.
> We have sao tied to ground, so it should be 0, giving 01110000 as the
> correct slave address. Does anyone see what I'm doing wrong?

This is (almost) the same device as used on the Olimex MOD-LCD-1x9:

https://www.olimex.com/Products/Modules/LCD/MOD-LCD-1x9/

I've had this working very nicely on a Kinetis KL25Z, a Stellaris LM3S, a
Mega328P, and more importantly for you, an MSP430F5510.

This is configured, correctly, at 8-bit address 0x70.

> Their literature is not at all clear (at least, to me) but it seems to say
> that the first thing I should send to this device is the slave address,

SAD+W, correct. The slave will then acknowledge.

> then the device select command with the continuation bit clear, (0x60).

Wellllll, no. First you need to use a MODE SET command.

> (A0, A1, and A0 are tied to ground.), then send the data bytes. Has
> anyone had experience with this device that might help me with this?

I can only say what I have seen: the PCF8576 works pretty well as far as I
can tell. To update the display, you send the DEVICE SELECT command, then
send the LOAD DATA POINTER command, and splat down your segments. I keep a
RAM buffer of segment states and just blat the whole thing down
periodically.

CTL_STATUS_t
olimex_mod_lcd1x9_initialize(OLIMEX_MOD_LCD1x9_t *self, CTL_I2C_BUS_t *bus)
{
CTL_STATUS_t stat;

// Initialize display driver.
stat = pcf8576d_write_command(bus, PCF8576D_MODE_SET |
PCF8576D_MODE_SET_ENABLE |
PCF8576D_MODE_SET_HALF_BIAS |
PCF8576D_MODE_SET_1_4_MULTIPLEX);
if (stat < CTL_NO_ERROR)
return stat;

// Blink off.
stat = pcf8576d_write_command(bus, PCF8576D_BLINK_SELECT);
if (stat < CTL_NO_ERROR)
return stat;

// Initialize.
self->bus = bus;

// Set up buffer with initial command.
self->buffer[0] = PCF8576D_LOAD_DATA_POINTER | 0;

// Flush display.
return olimex_mod_lcd1x9_flush(self);
}

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
SolderCore Development Platform http://www.soldercore.com

Thank you Paul for the reply.
I have discovered that if I send start, mode select == 0xC8 first, I then get an ack for it and also when I send the slave address == 0x70. Before, I got an ack for incorrect slave addresses but not for the correct one. I then send stop.

The above is sent during my startup code. When I want to update the display, I am sending start, device select == 0x60, load data pointer == 0x00, followed by 21 bytes of data, then stop. I get an ack after each byte, but no segments are lit on the lcd. Can anyone see what I'm doing wrong?
Thanks,
Mike Raines

________________________________
From: m... [mailto:m...] On Behalf Of one00100100
Sent: Friday, February 01, 2013 10:35 AM
To: m...
Subject: [msp430] NXP PCF8576C Segmented LCD Controller Interface Problems

I am using I2C to interface to the lcd controller. We are using the MSP430F5438A chip and the full IAR workbench. I have a scope on the data and clk lines. The scope seems to verify that start and stop conditions are correct. Further, when I send the slave address, the scope shows data signals l,h,h,h,l,l,l,l when clk is h (high). I am sending 0x70 which is 01110000. This all seems correct, but I do not get an ack. If I send 0x68 or 0x74, which are incorrect, I get an ack. According to their data sheet, the slave address is: 011100 (sao) and the r/w bit is set to 0. We have sao tied to ground, so it should be 0, giving 01110000 as the correct slave address. Does anyone see what I'm doing wrong?

Their literature is not at all clear (at least, to me) but it seems to say that the first thing I should send to this device is the slave address, then the device select command with the continuation bit clear, (0x60). (A0, A1, and A0 are tied to ground.), then send the data bytes. Has anyone had experience with this device that might help me with this?

Thanks,
Mike Raines



Hi,

> Thank you Paul for the reply.
> I have discovered that if I send start, mode select == 0xC8 first, I then
> get an ack for it and also when I send the slave address == 0x70. Before,
> I got an ack for incorrect slave addresses but not for the correct one. I
> then send stop.
>
> The above is sent during my startup code. When I want to update the
> display, I am sending start, device select == 0x60, load data pointer ==
> 0x00, followed by 21 bytes of data, then stop. I get an ack after each
> byte, but no segments are lit on the lcd. Can anyone see what I'm doing
> wrong?

At a minimum you should send:

S 0x70 0x48 P
/* 0x70 = slave address
0x48 = enable, 1/2 bias, 1:4 multiplex for my display
If you don't send the above, the LCD is not enabled. */

S 0x70 0x70 P
/* 0x70 = slave address
0x70 = no blinking */

Then to illuminate all segments:

S 0x70 0x60 P
/* 0x70 = slave address
0x60 = device select */

S 0x70 0x00 0xFF 0xFF .... 0xFF P
/* 0x70 = slave address
0x00 = load data pointer, start at zero
0xFF = segment data, all illuminated. */

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
SolderCore Development Platform http://www.soldercore.com

Thanks again, Paul,
I finally figured this out (actually just decided to try it as I was running out of ideas) from looking at the Olimex example code you pointed me to. I now have it working as you just described. Lots of segments are lit, but they are going on and off in a funny pattern. I'm sure I have something awry in the mapping. Anyway, many thanks for the help. At least I've got something happening now and some confidence that I'm communication with a functioning controller. This was about to drive me nuts.
Mike Raines
________________________________
From: m... [mailto:m...] On Behalf Of Paul Curtis
Sent: Friday, February 01, 2013 3:23 PM
To: m...
Subject: RE: [msp430] NXP PCF8576C Segmented LCD Controller Interface Problems

Hi,

> Thank you Paul for the reply.
> I have discovered that if I send start, mode select == 0xC8 first, I then
> get an ack for it and also when I send the slave address == 0x70. Before,
> I got an ack for incorrect slave addresses but not for the correct one. I
> then send stop.
>
> The above is sent during my startup code. When I want to update the
> display, I am sending start, device select == 0x60, load data pointer => 0x00, followed by 21 bytes of data, then stop. I get an ack after each
> byte, but no segments are lit on the lcd. Can anyone see what I'm doing
> wrong?

At a minimum you should send:

S 0x70 0x48 P
/* 0x70 = slave address
0x48 = enable, 1/2 bias, 1:4 multiplex for my display
If you don't send the above, the LCD is not enabled. */

S 0x70 0x70 P
/* 0x70 = slave address
0x70 = no blinking */

Then to illuminate all segments:

S 0x70 0x60 P
/* 0x70 = slave address
0x60 = device select */

S 0x70 0x00 0xFF 0xFF .... 0xFF P
/* 0x70 = slave address
0x00 = load data pointer, start at zero
0xFF = segment data, all illuminated. */

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
SolderCore Development Platform http://www.soldercore.com



Hi Mike,

> Thanks again, Paul,
> I finally figured this out (actually just decided to try it as I was
> running out of ideas) from looking at the Olimex example code you pointed
> me to.

Actually, I wrote my own code. :-)

> I now have it working as you just described. Lots of segments are
> lit, but they are going on and off in a funny pattern.

Mapping could be an issue. As long as you're driving the display and it's
steady, then you probably have the drive setup correct.

> I'm sure I have
> something awry in the mapping. Anyway, many thanks for the help. At
> least I've got something happening now and some confidence that I'm
> communication with a functioning controller. This was about to drive me
> nuts.

--
Paul Curtis, Rowley Associates Ltd http://www.rowley.co.uk
SolderCore Development Platform http://www.soldercore.com