View previous topic :: View next topic |
Author |
Message |
Guest
|
Help on i2C Master mode |
Posted: Tue May 18, 2004 7:39 am |
|
|
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
|
|
Posted: Tue May 18, 2004 7:51 am |
|
|
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
|
|
Posted: Tue May 18, 2004 8:36 am |
|
|
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
|
|
Posted: Tue May 18, 2004 8:46 am |
|
|
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
|
|
Posted: Tue May 18, 2004 8:50 am |
|
|
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
|
|
Posted: Tue May 18, 2004 9:50 am |
|
|
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
|
|
Posted: Tue May 18, 2004 9:52 am |
|
|
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
|
|
Posted: Tue May 18, 2004 9:55 am |
|
|
Thanks Ronald,
I will try this & post the findings tomorrow
Thanks again & Best regards,
David |
|
|
Guest
|
|
Posted: Wed May 19, 2004 4:08 am |
|
|
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
|
|
Posted: Wed May 19, 2004 4:27 am |
|
|
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
|
|
Posted: Wed May 19, 2004 4:31 am |
|
|
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
|
|
Posted: Wed May 19, 2004 12:29 pm |
|
|
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. |
|
|
|