![](templates/subSilver/images/CCSLogo.jpg) |
![CCS C Software and Maintenance Offers](templates/subSilver/images/forumAd6.jpg) |
View previous topic :: View next topic |
Author |
Message |
StevenO
Joined: 15 Jun 2010 Posts: 4 Location: Denmark
|
Strange I2C vs. 24LC256 problem! |
Posted: Fri Sep 17, 2010 5:58 am |
|
|
Hi all
I am currently working on a x,y-plotter based on four 18F2680, a µALFAT USB host controller and a 24LC256 eeprom. Until now i've been writing working i2c functions and respective slave-interrupts. I've now added the eeprom, and i'm using the ccs driver.
My problem: I can write and read as much data to/from the eeprom as i want without any problems. But after 24 writes, my slave i2c functions aren't working anymore?!
I've verified that the master is generating the pulses on SCL and SDA, but the slaves aren't somehow acknowledging this after the 24 eeprom writes. I can send as much data i want using these i2c functions, without writing to the eeprom...
All pics are running 8Mhz (internal osc) with i2c in standard-mode (HW). Pull-ups are 1.8kOhm. Im using MPLAB IDE v8.43, PicKit2 and CCS compiler.
i2c master:
Code: |
void i2c_x_send_mode(int mode)
{
i2c_start();
i2c_write(x_adr);
i2c_write(mode);
i2c_stop();
}
void i2c_x_send_speed(int mode, int speed_msb, int speed_lsb)
{
i2c_start();
i2c_write(x_adr);
i2c_write(mode);
i2c_write(speed_msb);
i2c_write(speed_lsb);
i2c_stop();
}
void i2c_x_send_data(int mode1, int dir, int angle_factor, int x_drive_msb, int x_drive_lsb, int mode2)
{
i2c_start();
i2c_write(x_adr);
i2c_write(mode1);
i2c_write(dir);
i2c_write(angle_factor);
i2c_write(x_drive_msb);
i2c_write(x_drive_lsb);
i2c_write(mode2);
i2c_stop();
}
void i2c_y_send_mode(int mode)
{
i2c_start();
i2c_write(y_adr);
i2c_write(mode);
i2c_stop();
}
void i2c_y_send_speed(int mode, int speed_msb, int speed_lsb)
{
i2c_start();
i2c_write(y_adr);
i2c_write(mode);
i2c_write(speed_msb);
i2c_write(speed_lsb);
i2c_stop();
}
void i2c_y_send_data(int mode1, int dir, int angle_factor, int y_drive_msb, int y_drive_lsb, int mode2)
{
i2c_start();
i2c_write(y_adr);
i2c_write(mode1);
i2c_write(dir);
i2c_write(angle_factor);
i2c_write(y_drive_msb);
i2c_write(y_drive_lsb);
i2c_write(mode2);
i2c_stop();
}
void i2c_io_send_mode(int mode)
{
i2c_start();
i2c_write(io_adr);
i2c_write(mode);
i2c_stop();
}
void write_ext_eeprom(long address, int data)
{
short int status;
i2c_start();
i2c_write(0xa0);
i2c_write(address>>8);
i2c_write(address);
i2c_write(data);
i2c_stop();
i2c_start();
status=i2c_write(0xa0);
while(status==1)
{
i2c_start();
status=i2c_write(0xa0);
}
i2c_stop();
delay_us(10);
}
int read_ext_eeprom(long address) {
int data;
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);
}
|
i2c slaves:
Code: |
void i2c_data_handler()
{
int recieve_buffer = 0;
state = i2c_isr_state();
recieve_buffer = i2c_read();
if(state == 1) {mode = recieve_buffer;}
if(state == 2 && mode == 3) {buffer1 = i2c_read();}
if(state == 3 && mode == 3) {buffer2 = i2c_read();}
if(state == 2 && mode == 12){dir = recieve_buffer;}
if(state == 3 && mode == 12){buffer1 = recieve_buffer;}
if(state == 4 && mode == 12){buffer2 = recieve_buffer;}
if(state == 5 && mode == 12){buffer3 = recieve_buffer;}
if(state == 6 && mode == 12){mode = recieve_buffer;}
}
#INT_SSP
void I2C_interrupt()
{
i2c_data_handler();
}
|
Thanks on behalf!
Greetings
Steven _________________ Steven Follmann
steven@follmann.dk
Bachelor Student Electronics
Technical University Of Denmark
@ Unigreen International ApS |
|
![](templates/subSilver/images/spacer.gif) |
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Fri Sep 17, 2010 10:52 am |
|
|
If the 18F2680 is talking to a 24LC256, this means the PIC is the i2c
Master, which means it does not need the #int_ssp interrupt routine.
Also, you're writing your own 24LC256 driver and that will probably
create bugs in the code. You should use an existing, working driver.
Here's the CCS driver location:
Quote: | c:\program files\picc\drivers\24256.c
|
|
|
![](templates/subSilver/images/spacer.gif) |
Ttelmah
Joined: 11 Mar 2010 Posts: 19365
|
|
Posted: Sat Sep 18, 2010 2:46 am |
|
|
I think he is talking about having four slave devices on the one I2C bus. A EEPROM, and three separate slave PICs.
Presumably the int_ssp, if for the slave PICs.
What are the addresses involved?. You use presumably 'defined' values, as 'x_addr', 'y_addr', and 'io_addr'. If these are 'defines', then switch to the 'C' standard, and use capitals for these. If they are not defines, but variables, are you sure the values are remaining correct...
Why, oh why, have the recieve code as a separate routine?. Does this imply you are calling this from somewhere else as well?. If so, then this could be the problem.
Post the I2C setup lines for each slave, the addresses used etc..
Best Wishes |
|
![](templates/subSilver/images/spacer.gif) |
StevenO
Joined: 15 Jun 2010 Posts: 4 Location: Denmark
|
|
Posted: Sun Sep 19, 2010 1:54 pm |
|
|
Thanks for answering Ttelmah! First of all you've read my thread correct, and corrected PCM programmer in the right direction as well!
I am using a PIC18F2680 as i2c master for three PIC18F2680 slaves, the eeprom and a USB host controller. The adresses are defined as:
Code: |
int y_adr = 0x12; //I2C adress for Y-motor PIC
int x_adr = 0x16; //I2C address for X-motor and lane PIC
int io_adr = 0x14; //I2C adrress for IO PIC
|
So i am not using 'defines' for these addresses (bad or good?!). The i2c setups are:
Code: |
#use i2c(master, sda=PIN_C4, scl=PIN_C3, FORCE_HW)
#use i2c(slave, address=0x14, sda=PIN_C4, scl=PIN_C3)
#use i2c(slave, sda=PIN_C4, scl=PIN_C3, address=0x12)
#use i2c(slave, sda=PIN_C4, scl=PIN_C3, address=0x16)
|
All config pins on the eeprom are grounded (A0,A1,A2), so the i2c address is: 0xA0. The i2c address for the USB host controller is 0xA4 (un-changeable).
I only made my recieve-routine seperate because I thought was 'doing too much' staying in the interrupt (i guess i'm not?). The routine posted, is the same for all the PIC slaves. I'm not calling i2c_data_handler elsewhere than the interrupt!
The eeprom routines are the exact same as from the CCS written driver.
I simply can't understand why i'm able to write (use the write routine) exactly 24 times before my i2c bus/functions/behaviour is acting wierd?! As mentioned i've scop'ed the i2c lines and they are both high (4,x volt) after the 24 writes, indicating the bus is acting normally regarding hardware (i guess?).
Do I have to use a delay between the writes? I'm supposing the while-loop in the write routine is taking care of this?
I could REALLY use the eeprom in the setup, due to a lot of things. I'm handing in my thesis/report on this project in 3 weeks
Best wishes to all, and again thanks Ttelmah!!! _________________ Steven Follmann
steven@follmann.dk
Bachelor Student Electronics
Technical University Of Denmark
@ Unigreen International ApS |
|
![](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
|