View previous topic :: View next topic |
Author |
Message |
gordon111
Joined: 05 Jul 2007 Posts: 18
|
eeprom! |
Posted: Thu Jul 05, 2007 12:24 pm |
|
|
I have been trying to program 'n EEPROM ( 24LC128 ) for the whole week, but i am not succeeding.
my code follows:
include <16F883.h>
//#fuses HS, NOWDT, PROTECT, BROWNOUT, PUT, NOLVP
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(MASTER, sda=PIN_C3, scl=PIN_C4)
#case
unsigned int8 address;
unsigned char data;
unsigned char value;
// Writes to the slave board from the master.
void write_ext_eeprom(unsigned int8 address, unsigned char data)
{
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
}
// Read from the slave board and display the data.
unsigned int16 read_ext_eeprom(unsigned int8 address )
{
i2c_start();
i2c_write(0xA0);
i2c_write(address>>8);
i2c_write(address);
i2c_start();
i2c_write(0xA1);
data = i2c_read(0);
i2c_stop();
return data;
}
//====================================
void main()
{
TRISA = 0x0A; // Port A Direction
// RA0 : Sensor Input (0)
// RA1 : Sensitivity Input (1)
// RA2 : Not used (0)
// RA3 : Not used (1)
// RA4 : Not used (0)
// RA5 : Not used (0)
TRISB = 0x00; // Port B Direction
// RB0 : Not used (0)
// RB1 : RS-485 Direction Output (0)
// RB2 : LED1 Output (0)
// RB3 : LED2 Output (0)
// RB4 : LED3 Output (0)
// RB5 : RUN LED Output (0)
// RB6 : Not used (0)
// RB7 : Not used (0)
TRISC = 0x80; // Port C Direction
// RC0 : Not used (0)
// RC1 : Not used (0)
// RC2 : Relay Output (0)
// RC3 : SCLK (0)
// RC4 : SDAT (0)
// RC5 : Not used (0)
// RC6 : Serial Transmit (0)
// RC7: Serial Recieve {1)
while(1)
{
write_ext_eeprom(1,100);
read_ext_eeprom(1);
value = data;
printf("\r\n\-----> Tempratuur_waarde = 0x%D", value );
}
}
my result is, 255 or 0xff.
please help! |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Thu Jul 05, 2007 12:32 pm |
|
|
Your driver routines are not correct. The 24LC128 uses two bytes
for the address. Your functions only accept one byte (int8) as the
address.
Also, it takes time to complete the write operation. At then end of
the write routine, you need to either put in a fixed delay time of at
least 5 ms (this is in the data sheet) or do "ack polling" (this is also
in the data sheet).
Also, in your read routine, you don't declare the 'data' variable
as a local variable. You need to do that. Don't use a global.
Look at other CCS eeprom drivers for examples. |
|
|
gordon111
Joined: 05 Jul 2007 Posts: 18
|
eeprom |
Posted: Thu Jul 05, 2007 12:46 pm |
|
|
thanx alot for the help,
must i state somewhere that i am using a 24LC128 in my code?Or is this not necessary? |
|
|
gordon111
Joined: 05 Jul 2007 Posts: 18
|
eeprom! |
Posted: Fri Jul 06, 2007 3:18 am |
|
|
Hey,
I have made all the changes you said, and it still doesn't return the correct values. Please help!
Code: |
#include <16F883.h>
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(MASTER, sda=PIN_C4, scl=PIN_C3)
#case
// Writes to the slave board from the master.
void write_ext_eeprom(unsigned int16 address, unsigned char data)
{
i2c_start();
i2c_write(0xA0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
delay_ms(5);
i2c_stop();
}
// Read from the slave board and display the data.
unsigned int16 read_ext_eeprom(unsigned int16 address )
{
unsigned char data_read;
i2c_start();
i2c_write(0xA0);
i2c_write(address>>8);
i2c_write(address);
i2c_start();
i2c_write(0xA1);
data_read = i2c_read(0);
delay_ms(5);
i2c_stop();
return data_read;
}
//====================================
void main()
{
TRISA = 0x0A; // Port A Direction
// RA0 : Sensor Input (0)
// RA1 : Sensitivity Input (1)
// RA2 : Not used (0)
// RA3 : Not used (1)
// RA4 : Not used (0)
// RA5 : Not used (0)
TRISB = 0x00; // Port B Direction
// RB0 : Not used (0)
// RB1 : RS-485 Direction Output (0)
// RB2 : LED1 Output (0)
// RB3 : LED2 Output (0)
// RB4 : LED3 Output (0)
// RB5 : RUN LED Output (0)
// RB6 : Not used (0)
// RB7 : Not used (0)
TRISC = 0x80; // Port C Direction
// RC0 : Not used (0)
// RC1 : Not used (0)
// RC2 : Relay Output (0)
// RC3 : SCLK (0)
// RC4 : SDAT (0)
// RC5 : Not used (0)
// RC6 : Serial Transmit (0)
// RC7: Serial Recieve {1)
while(1)
{
unsigned char data_read;
unsigned int16 address;
unsigned char value;
write_ext_eeprom(0x01,0x12);
read_ext_eeprom(0x01);
value = data_read;
printf("\r\n\-----> Tempratuur_waarde = 0x%X", value );
}
}
|
Any help will be appreciated
Elsebi |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Jul 06, 2007 4:22 am |
|
|
Code: | read_ext_eeprom(0x01);
value = data_read;
printf("\r\n\-----> Tempratuur_waarde = 0x%X", value ); | You are not doing anything with the value returned by read_ext_eeprom(). The local variable data_read is not initialized and will contain a random value.
Change to: Code: | value = read_ext_eeprom(0x01);
printf("\r\n\-----> Tempratuur_waarde = 0x%X", value ); |
Just a few remarks:
Code: | unsigned int16 address | An int16 is by definition unsigned so your declaration of unsigned is double and not required.
Code: | i2c_write(address>>8);
i2c_write(address); | You are here depending on implicit casts. You know it works on this compiler version, but it might fail on another future compiler version. It is better programming practice to write explicit casts like Code: | i2c_write( (int8)(address>>8));
i2c_write( (int8)address); |
|
|
|
vanSittert Guest
|
eeprom |
Posted: Fri Jul 06, 2007 5:11 am |
|
|
After making all the changes you suggested, the only value that is returned is 0xFF!
i do not know, what i am doing wrong at all!
Code: |
#include <16F883.h>
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)
#use i2c(MASTER, sda=PIN_C4, scl=PIN_C3)
#case
// Writes to the slave board from the master.
void write_ext_eeprom(int16 address, unsigned char data)
{
i2c_start();
i2c_write(0xA0);
i2c_write((int8)(address>>8));
i2c_write((int8)address);
i2c_write(data);
delay_ms(5);
i2c_stop();
}
// Read from the slave board and display the data.
unsigned char read_ext_eeprom(int16 address )
{
unsigned char data_read;
i2c_start();
i2c_write(0xA0);
i2c_write( (int8)(address>>8));
i2c_write( (int8)address);
i2c_start();
i2c_write(0xA1);
data_read = i2c_read(0);
delay_ms(5);
i2c_stop();
return data_read;
}
//====================================
void main()
{
TRISA = 0x0A; // Port A Direction
// RA0 : Sensor Input (0)
// RA1 : Sensitivity Input (1)
// RA2 : Not used (0)
// RA3 : Not used (1)
// RA4 : Not used (0)
// RA5 : Not used (0)
TRISB = 0x00; // Port B Direction
// RB0 : Not used (0)
// RB1 : RS-485 Direction Output (0)
// RB2 : LED1 Output (0)
// RB3 : LED2 Output (0)
// RB4 : LED3 Output (0)
// RB5 : RUN LED Output (0)
// RB6 : Not used (0)
// RB7 : Not used (0)
TRISC = 0x80; // Port C Direction
// RC0 : Not used (0)
// RC1 : Not used (0)
// RC2 : Relay Output (0)
// RC3 : SCLK (0)
// RC4 : SDAT (0)
// RC5 : Not used (0)
// RC6 : Serial Transmit (0)
// RC7: Serial Recieve {1)
while(1)
{
//unsigned char data = 0;
unsigned char value = 0;
write_ext_eeprom(1 , 199 );
value = read_ext_eeprom( 1 );
printf("\r\n\-----> Tempratuur_waarde = 0x%X", value );
}
}
|
Thanx alot for the help!
Gordon |
|
|
Ttelmah Guest
|
|
Posted: Fri Jul 06, 2007 5:17 am |
|
|
Obvious comment, but I have not seen it made so far in the thread. You have got the pull up resistors on the SCL/SDA lines?...
Best Wishes |
|
|
gordon111
Joined: 05 Jul 2007 Posts: 18
|
eeprom |
Posted: Fri Jul 06, 2007 5:32 am |
|
|
Hey,
Obvious and well noted comment, thanx, but i checked i have 2k7 pull up to Vcc on both! |
|
|
ckielstra
Joined: 18 Mar 2004 Posts: 3680 Location: The Netherlands
|
|
Posted: Fri Jul 06, 2007 7:24 am |
|
|
I don't know the difference, but have you checked the 24C128 driver in the CCS program directory?
One important difference is that in your code you have a 5ms delay in the write routine but at the wrong place, just before the i2c_stop while it should be after the i2c_stop instruction: Code: | i2c_write(data);
delay_ms(5); <-- move this to after the i2c_stop() call.
i2c_stop();
} |
|
|
|
gordon111
Joined: 05 Jul 2007 Posts: 18
|
|
Posted: Fri Jul 06, 2007 8:05 am |
|
|
Thank you again for the advice, this was an obvious error, unfortuanetly this didn't fixs the problem! |
|
|
Ttelmah Guest
|
|
Posted: Fri Jul 06, 2007 9:26 am |
|
|
Other obvious comment, how have you got the address lines wired?. Address A0, requires all the lines to be held low.
Best Wishes |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Fri Jul 06, 2007 1:06 pm |
|
|
For now, try placing actual values for the address into your functions, instead of trying to pass the address value. This might help to confirm if the communication is working between the master and the eeprom. Also, try to place an if() in there to see if the eeprom is talking properly. Something like:
Code: | if(!i2c_write(0xA0))
{
i2c_write(0);
i2c_write(1);
// and so forth, placing numbers here instead of passing values
} |
The if() statement will skip the rest of the code and you might could put an else() to set some kind of flag to let you know that the eeprom didn't ACK back. Something like that might help troubleshoot what's going on.
I, usually, put an if() statement to check if the slave ACK's back. It's good programming to check the ACK bit whenever you're communicating with a device. If you 'assume' that everything is talking back like it should you will end up getting yourself into trouble down the road.
Ronald |
|
|
gordon111
Joined: 05 Jul 2007 Posts: 18
|
|
Posted: Mon Jul 09, 2007 12:15 pm |
|
|
Hey,
Thanks for all the help, it finally work.I wrote the wrong control byte,
A2 = 0, A1 = 0 and A0= 0 was accually all pulled up high to VCC
Thanks again for all the help.
Gordon |
|
|
|