Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

I2c problem - rcen does not generate clock

Status
Not open for further replies.

electroRF

Member
Hi,

I have Master I2C (PIC18F4520) and Slave I2C (GLCD-Flexel).

I manage to write data into the GLCD and write to its display.

I don't manage to read data from it:

I connected a scope to the SCK line, and found that when I set RCEN=1, the SCK does not generate clock.

What could cause it?

Thank you very much.
 
Hi Ian,
Thanks a lot for your repsonse!

The GLCD Datasheet is here: http://web4robot.com/files/GLCD-FLEXEL.pdf

I use in the code the XC8 I2C functions, which makes it simple to read.

Below is how I write a cursor value and then read the cursor value.
However, instead of reading 0x15, I read 0x00.
I get zeros in SSPBUF.

I do get a clock on the SCK line when I set RCEN.
But I still read Zeros - Nothing happens on the SDA line.

Attached are the SCK line when RCEN =1 **broken link removed**
And the SCK line when I transmit a byte to the GLCD **broken link removed**

There's a large difference



// Set Cursor position
StartI2C();
putcI2C(GLCD_WRITE);
putcI2C(0xFE);
putcI2C(0x04);
putcI2C(0x15); //x cursor
putcI2C(0x15); //y cursor
StopI2C();


//Read 'y' Cursor Position from Slave
StartI2C();
putcI2C(GLCD_WRITE);
//0x8C
putcI2C(0xFE);
putcI2C(0x07);
RestartI2C();
putcI2C(GLCD_READ);
//0x8D
IdleI2C();
SSPCON2bits.RCEN=1; while(RCEN);
unsigned char i2cReadData;
i2cReadData = SSPBUF;
StopI2C();
 
Last edited:
SSPCON2bits.RCEN=1; while(RCEN);

Don't think this is a good idea.. You are setting the RCEN then the whole program stops.... You are the only one that can turn it off so the program will hang here..... You can set this to ON and leave it on for the duration...
If you put the SSPCON2bits.RCEN=1 at the beginning and leave the while() off... you should be good to go...
 
Hi Ian,
Thanks again!

The RCEN bit should be cleared automatically I believe after the 8th clock.

I tried removing it, however, what happened was that it messed up the setup of the I2C.

I couldn't write anything to the GLCD after the RCEN=1 (when I removed the While() part).

I was still not able to read data from the GLCD.
 
I use the pic18f4520 all the time... I use the I2C in every system I make..

I have NEVER waited until RCEN becomes 0. The SSPIF is set when I2C read is done
C:
//Get a byte from the slave
char ReceiveByte()
    {
    SSPCON2bits.RCEN=1;
    WaitSSP();
    return(SSPBUF);
    }

//Wait for the module to finish it's last action.
void WaitSSP()
    {
    while(PIR1bits.SSPIF==0);
    PIR1bits.SSPIF=0;
    }
 
Hi Ian,
Thank you again.
And thank you very much for sharing your code.

I modified the reading section in code according to your advice, please see code section below.
However, what happened was that:
1. I still didn't manage to read a value from the Slave (GLCD)
2. This modification caused that I couldn't communicate from that point with the GLCD anymore, and couldn't continue writing to it

Could you add your entire section where you write and read to and from the slave? (what is your slave btw?)

I'd like to see how you perform the reading.

For example, whether you use "Restart", and whether you send the Slave Address with the R/W bit set before setting the RCEN bit.

And whether you wait for an ACK from the Slave before you set the RCEN bit.

* This is what the GLCD datasheet says on reading from the GLCD:
I2C interface Read Data command includes two transactions:
First transaction sends a command to read the data from slave device (data request);
Second transaction read the data from slave device.


Thank you very much!

//READ y Cursor Position from Slave
StartI2C();
putcI2C(GLCD_WRITE);
//0x8C
putcI2C(0xFE);
putcI2C(0x07);
RestartI2C();
putcI2C(GLCD_READ);
//0x8D
IdleI2C();
SSPCON2bits.RCEN=1;
while(PIR1bits.SSPIF==0);
PIR1bits.SSPIF=0;
unsigned char i2cReadData;
i2cReadData = SSPBUF;
StopI2C();
 
Last edited:
Could you add your entire section where you write and read to and from the slave? (what is your slave btw?)

Oodles of devices.. The I2C bus is identical on every device...

Where are your I2C routines..... You may be waiting twice, thus halting the I2C bus....What compiler are you using?
 
Yes!! The code is the same... We write the functions to handle all eventualities.
No! The routines are built in to the compiler....

I have not done the I2C routines for the smaller chips.. I have in C18... I may do them in XC8 soon...
 
Hi Ian,
Thank you again!

I'm not sure what you mean by the routines.
I use the XC8 built in functions for the I2C communication (I wrote them in the code I added in previous posts).

I'd love to know whether you managed to read data from slave with the XC8 :)

Thanks a lot!
 
My routines are low level for my systems so they would need a bit of a re-write to use on the XC8 compiler.... I really need to do it as this is the new compiler and C18 will no longer be supported...
 
Thanks Ian!

You have an idea what I could possibly do in order to overcome a situation in which the GLCD Slave does not send data to the PIC Master?
(That is while writing goes well).

You have any suspicions?

Could it be Pull-up issue?

I currently rely on the internal Pull-Up Resistors that are in the GLCD, on the SDA and SCK lines.


BTW, when do you think you'll complete the imigration to XC8? :)
 
I currently rely on the internal Pull-Up Resistors that are in the GLCD, on the SDA and SCK lines.

What value are they? I mainly use 4k7... Have voltage translation 5v-3.3v and visa versa.... If your LCD is running at 3v it may not be enough to drive the micro..
 
Hi Ian,
What value are they? I mainly use 4k7...
The GLCD datasheet doesn't specify their value.
I think it's worth trying 4K7 pull-ups just in case.
--Edit--
I soldered 4K7 pull up resistor on each line (SDA, SCK), however it didn't have influence - writing still succeeds and reading still fails.

Have voltage translation 5v-3.3v and visa versa.... If your LCD is running at 3v it may not be enough to drive the micro..
PIC works at 5V.
GLCD has internal 3.3V Regulator, so it works on 3.3V.

I tried driving both GLCD and PIC at 3.5V.
The writing still worked well, but the Reading still failed.



What sense does it make that I manage to write send data to the GLCD but fails to get data from the GLCD?
 
Last edited:
You don't need the pullups..... As you said they are integral to the display...

The "Read" function is odd.... you need to END transmission.. Then start again not restart..
One confusion is the Arduino library issues 0x90 as the default address... not 0x8C as you are using..

That said... Try this

//READ y Cursor Position from Slave
StartI2C();
putcI2C(GLCD_WRITE); //0x8C
putcI2C(0xFE);
putcI2C(0x07);
StopI2C();

StartI2C();
putcI2C(GLCD_READ); //0x8D
IdleI2C();
SSPCON2bits.RCEN=1;
while(PIR1bits.SSPIF==0);
PIR1bits.SSPIF=0;
unsigned char i2cReadData; // not sure you can initialize variables like this...
i2cReadData = SSPBUF;
StopI2C();
 
You don't need the pullups..... As you said they are integral to the display...

The "Read" function is odd.... you need to END transmission.. Then start again not restart..
One confusion is the Arduino library issues 0x90 as the default address... not 0x8C as you are using..

That said... Try this

//READ y Cursor Position from Slave
StartI2C();
putcI2C(GLCD_WRITE); //0x8C
putcI2C(0xFE);
putcI2C(0x07);
StopI2C();

StartI2C();
putcI2C(GLCD_READ); //0x8D
IdleI2C();
SSPCON2bits.RCEN=1;
while(PIR1bits.SSPIF==0);
PIR1bits.SSPIF=0;
unsigned char i2cReadData; // not sure you can initialize variables like this...
i2cReadData = SSPBUF;
StopI2C();

Hi Ian
Thanks!

I tried this code out yesterday, but also tried it now.
I get no response from Slave, and additionally, using that code for reading, causes that I'm not able to communicate anymore with the Slave after that reading section.

I also tried out using 0x90 address now, with no luck :(
 
Hi Ian,
Thank you.

I tested with Scope whether the GLCD returns an Ack after I send it its Address with the R/W bit set.
It seems to return an Ack - at the 9th clock the SDA line goes low.

Scope image: **broken link removed**
**broken link removed**

Could you pleaes confirm?

(the GLCD Address with R/W set is 0x8D).

However, in the next step, when I set the RCEN to 1, the SCK generates 8 clock pulses, but the SDA remains zero during all these 8 pulses.
 
Last edited:
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top