CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Help on i2C Master mode

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
Guest








Help on i2C Master mode
PostPosted: Tue May 18, 2004 7:39 am     Reply with quote

Hi,

I am trying to read an external EEPROM using PIC 16F819
But I am unable to read correct value .
I am using debugging LEDs to detect this condition

Here is my Code . I have just pasted the relevant portion of the code

#include <16F819.h>
#use delay(clock=8000000) // 8 MHz internal oscillator, restart WDT on delays

#fuses HS,INTRC_IO,NOWDT,NOPROTECT,NOLVP,NOMCLR
#use i2c(Master, slow, sda=PIN_B1, scl=PIN_B4 )

/*****************************************************************
* main().
*****************************************************************/

byte data;
void main()
{

OSCCON=0x74;
set_tris_a(0x00); // Port A Output
set_tris_b(0x00); // Port B Output


/*****************************************************************
* i2C
*****************************************************************/
// write

output_low(SDATA_BUF);
output_low(SCLK_BUF);
output_low(LED5);

i2c_start();
i2c_write(0xa0); //device address lower 256 byte page
i2c_write(0x70); // word address 70
i2c_write(0x05); // data
i2c_read(0);
i2c_stop();


// read
i2c_start();
i2c_write(0xa1); // device address
i2c_write(0x70); // word address 70
data = i2c_read();
delay_us(10);
i2c_read(0);
i2c_stop();


while ( data == 0x05 )
{
output_high(LED5);
delay_ms(500);
output_low(LED5);
}

while( data != 0x05)
{
output_high(LED6);
delay_ms(500);
output_low(LED6);
delay_ms(500);
delay_ms(500);
delay_ms(500);

}

} // main()

//EOF

The EEPROM that I used is Philips PCF 8594 - 100Khz type
I have checked the waveform with this code & found to be Ok
However , if I include FORCE_HW in the #use i2c(..), I could not observe any clocks coming out.
The rise time of the clock was quite sharp & my pull up res value was 2.7K

Any thing wrong with my code??

Pl advice if you sense something strange

Thanks in advance & Best regards,
David
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Tue May 18, 2004 7:51 am     Reply with quote

Let me make sure I understand correctly...if you include force_hw nothing will work, however if you take that out you can see the proper waveforms, but the EEPROM still doesn't work?

Try setting pins B1 and B4 to inputs (as the datasheet suggests) and see if FORCE_HW works.
Guest








PostPosted: Tue May 18, 2004 8:36 am     Reply with quote

Hi Haplo,

Thanks your advice
I will try that

Before that one quick question..

Does it mean that i2c will work fine only with FORCE_HW option ?

Thanks in adavnce & Best regards,
David
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Tue May 18, 2004 8:46 am     Reply with quote

I'm not sure if this is the case, but if SDATA_BUF is the SDA pin and SCLK_BUF is the SCL pin then forcing these two pins low, in the order you are doing, will simulate an i2c_start() signal to the eeprom. If this is the case you should remove those two lines. I have used I2C without the force_hw option just fine. Just make sure that both of your I2C pins are setup as inputs.

Ronald
Guest








PostPosted: Tue May 18, 2004 8:50 am     Reply with quote

Hi Ronald ,

I had tried that before
With & without those 2 lines , the effect was the same
I was unable to read from the EEPROM properly

Thanks & BestRegards,
David
Chas
Guest







PostPosted: Tue May 18, 2004 9:50 am     Reply with quote

Check your external memory device read command requirements. The 24xx256 parts want a restart between the address write and the data read. You may need to add this call to have the reads work correctly.
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Tue May 18, 2004 9:52 am     Reply with quote

Try this:

Code:

main()
{
set_tris_b(0x12)// set I2C pins as inputs

  delay_ms(200);// allow power to settle and eeprom to initialize

  output_low(WP);// this is the WP pin of the eeprom, needs to be set low
  i2c_start();       // to enable a write sequence
  i2c_write(0xa0);
  i2c_write(0x70);
  i2c_write(0x05);
  i2c_stop();
  output_high(WP);// write protect the eeprom

  delay_ms(50);// give the eeprom time to finish the write cycle

  i2c_start();
  i2c_write(0xa0);
  i2c_write(0x70);
  i2c_start();
  i2c_write(0xa1);
  data = i2c_read(0);
  i2c_stop();

  while ( data == 0x05 )
  {
    output_high(LED5);
    delay_ms(500);
    output_low(LED5);
  }

  while( data != 0x05)
  {
    output_high(LED6);
    delay_ms(500);
    output_low(LED6);
    delay_ms(500);
    delay_ms(500);
    delay_ms(500);
  }

  while(1)
  {
    ;
  }

}//main


Make sure both of your address lines are tied to ground and not just floating. Also, assign a pin to drive the WP pin of the eeprom.

Hope this works.

Ronald
Guest








PostPosted: Tue May 18, 2004 9:55 am     Reply with quote

Thanks Ronald,

I will try this & post the findings tomorrow

Thanks again & Best regards,
David
Guest








PostPosted: Wed May 19, 2004 4:08 am     Reply with quote

Hi Ronald & Haplo

Thanks a lot
The problem is resolved
After chnaging the config of SDA & SCL from O/P to I/P
& changing read part of the code as suggested by Ronald
it is OK

Thanks a lot again

Thanks & Best regards,
David
Guest








PostPosted: Wed May 19, 2004 4:27 am     Reply with quote

Hi again

Just to add this,in my case if I put FORCE_HW it does not work
If don't use FORCE_HW it works fine

Thanks & best regards,
David
Haplo



Joined: 06 Sep 2003
Posts: 659
Location: Sydney, Australia

View user's profile Send private message

PostPosted: Wed May 19, 2004 4:31 am     Reply with quote

That's probably because those two PORTB pins are still configured as output. A software I2C changes them to input before performing any actions, but the hardware I2C requires them to already be configured as inputs.
Also make sure you don't have a setup_spi(FALSE); statement in your code as it messes up everything. If you are using SPI as well, make sure you set those pins back to inputs before switching to I2C.

If you have debugging capabilites, set your code to FORCE_HW, run the code until it gets stuck, halt and check TRISB. If those pins are not inputs then you'll have to debug your code line by line to see what is changing them.
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Wed May 19, 2004 12:29 pm     Reply with quote

Quote:
I am trying to read an external EEPROM using PIC 16F819.

Quote:
Just to add this,in my case if I put FORCE_HW it does not work
If don't use FORCE_HW it works fine.


Hardware i2c will not work with the 16F819 because it doesn't
have a MSSP module. It only has a SSP module. You can
spot this by scanning down the Table of Contents of the data
sheet, on the left side of the Acrobat reader. It says:
SYNCHRONOUS SERIAL PORT (SSP) MODULE

If you read the i2c section of the data sheet it says how
master mode must be done: By bit banging:
Quote:
In Master mode operation, the SCL and SDA lines are
manipulated in firmware by clearing the corresponding
TRISB<4,1> bit(s).

That's what CCS does with their software i2c library code.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group