![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
homfray
Joined: 19 Nov 2003 Posts: 45 Location: Oxford
|
read_eeprom_byte |
Posted: Tue Mar 16, 2004 10:17 am |
|
|
PCH
pic18F452
40Mhz
fram FMc256
I have basically the following code
Code: |
if (in write mode)
adcValue = Read_ADC();
write_eeprom_byte(addr, adcValue);
addr++;
byteCnt=addr;
else if (in read mode)
for(noByte = 0; noByte < byteCnt; noByte++)
{
printf("Raddr:%xRdata:%X", noByte, read_eeprom_byte(noByte));
}
|
It seems to write the value ok but when I try to read the byte it just gives me back 00. I am using the code on the forum
Code: | // Read eeprom byte
char read_eeprom_byte(long addr)
{
char data;
output_bit(PIN_E2,1);
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write((char)(addr >> 8));
i2c_write((char)addr);
i2c_start();
i2c_write(EEPROM_I2C_READ_ADDR);
data = i2c_read(0);
i2c_stop();
output_bit(PIN_E2,0);
return data;
} |
can anyone see why i am only reading 0.
cheers |
|
![](templates/subSilver/images/spacer.gif) |
homfray
Joined: 19 Nov 2003 Posts: 45 Location: Oxford
|
|
Posted: Tue Mar 16, 2004 11:24 am |
|
|
I have got rid of all the rest of my code to this basic bit it seems to write to the eeprom properly but when read the result is always 0. Anyone any ideas??
Code: | //-------------------------------------------------------------------------
// INCLUDE FILES
#define Fosc 40000000 // I'm using a 40 MHz crystal
#include <18F452.h>
#device *=16 ADC=8
//------------------------------------------------------------------------
// DEFINES
#define EEPROM_PAGE_LEN 64 // Page length in bytes
#define EEPROM_PAGE_COUNT 512 // Nunber of pages in eeprom
#define EEPROM_I2C_WRITE_ADDR 0xA0
#define EEPROM_I2C_READ_ADDR 0xA1
//---------------------------------------------------------------------------
// COMPILER DIRECTIVES and HARDWARE CONFIGURATION
#fuses HS, NOWDT, NOPROTECT, PUT, BROWNOUT, NOLVP
#use delay(clock = Fosc)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(Master, SDA=PIN_C4, SCL=PIN_C3, FORCE_HW, slow) // Hardware i2c
#define SLOW ((Fosc / (4 * 100000)) -1) // 100 KHz i2c clock
#define FAST ((Fosc / (4 * 400000)) -1) // 400 KHz i2c clock
#define REALFAST ((Fosc / (4 * 1000000)) -1) // 1MHz i2c clock
#byte SSPSTAT = 0xFC7
#byte SSPCON1 = 0xFC6
#byte SSPADD = 0xFC8
//--------------------------------------------------------------------------
// GLOBALS
char page_write_buffer[EEPROM_PAGE_LEN];
char page_read_buffer[EEPROM_PAGE_LEN];
//---------------------------------------------------------------------------
// FUNCTION PROTOTYPES
void write_eeprom_byte(long addr, char data);
char read_eeprom_byte(long addr);
void erase_eeprom_page(long page);
void erase_eeprom(void);
//===========================================================================
void main()
{
long addr, i;
char byteCnt, the_value, c;
setup_port_a(RA0_RA1_ANALOG_RA3_REF);
setup_adc(ADC_CLOCK_INTERNAL);
set_adc_channel(1);
printf("\n\rErasing\n\r");
erase_eeprom();
SSPADD = REALFAST;
while(1)
{
if(kbhit())
{
c = getc() & 0x5F;
if(c == 'W') {
addr=0;
for(i=0; i<100; i++)
{
the_value = Read_ADC();
write_eeprom_byte(addr, the_value);
addr++;
byteCnt = addr;
}
printf("\n");
}
else if (c =='R')
{
for(i=0; i<byteCnt; i++)
{
printf("W-addr:%lx||data%x ",i, read_eeprom_byte(addr));
}
}
}
}
}
void erase_eeprom_page(long page)
{
char i;
long addr;
addr = (page << 6); // Convert page address to a byte address (multiply by 64)
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write((char)(addr >> 8));
i2c_write((char)addr);
for(i = 0; i < EEPROM_PAGE_LEN; i++)
{
i2c_write(0); // Fill page with all zeros
}
i2c_stop();
}
void erase_eeprom(void)
{
long page;
for(page = 0; page < EEPROM_PAGE_COUNT; page++)
{
erase_eeprom_page(page);
}
}
char read_eeprom_byte(long addr)
{
char data;
output_bit(PIN_E2,1);
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write((char)(addr >> 8));
i2c_write((char)addr);
i2c_start();
i2c_write(EEPROM_I2C_READ_ADDR);
data = i2c_read(0);
i2c_stop();
output_bit(PIN_E2,0);
return(data);
}
void write_eeprom_byte(long addr, char data)
{
printf("R-addr:%lx||data%x ",addr,data);
output_bit(PIN_B0,1);
i2c_start();
i2c_write(EEPROM_I2C_WRITE_ADDR);
i2c_write((char)(addr >> 8));
i2c_write((char)addr);
i2c_write(data);
i2c_stop();
output_bit(PIN_B1,0);
}
|
|
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Mar 16, 2004 11:36 am |
|
|
The first thing I noticed is that you're running the i2c at high speed.
SSPADD = REALFAST;
1. Does it work at 100 KHz and 400 KHz ?
2. Does it only fail at 1 MHz ?
3. Have you looked at the waveforms of the 1 MHz version
with an oscilloscope, and verified that the rise time is fast enough ?
4. What size of pull-up resistors are you using for the 1 MHz speed ?
5. Also, throughout your code, you have statements like this:
output_bit(PIN_B0,1);
and
output_bit(PIN_E2,1);
Are these statements just for debugging ?
Or, are these pins connected to the Write Protect pin on the FRAM chip ? |
|
![](templates/subSilver/images/spacer.gif) |
homfray
Joined: 19 Nov 2003 Posts: 45 Location: Oxford
|
|
Posted: Tue Mar 16, 2004 2:29 pm |
|
|
Quote: | 1. Does it work at 100 KHz and 400 KHz ?
2. Does it only fail at 1 MHz ? |
I will check both these things out tomorrow morning and send these details back to you
Quote: | 3. Have you looked at the waveforms of the 1 MHz version
with an oscilloscope, and verified that the rise time is fast enough ?
4. What size of pull-up resistors are you using for the 1 MHz speed ? |
I have checked the rise time of SCL on an osscilloscope and is high for long enough I have the resistors set to their maximum spec (can't remember now but it was in the data sheet i think they are around 2k2 but don't quote me on that), they rise as fast as they can. I have had the circuit board working for eeprom_read_block and eeprom_write_block and I have had it working beofre when I only write to address 00
Quote: | 5. Also, throughout your code, you have statements like this:
output_bit(PIN_B0,1);
and
output_bit(PIN_E2,1); |
Sorry thought I had taken them out they are there purely for me to time how quick a certain activity is done on an oscilloscope. The write protect pin has a weak pullup (or pull down can't remeber) so it is OK to leave it alone. |
|
![](templates/subSilver/images/spacer.gif) |
|
|
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
|