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

I2C slave not responding

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



Joined: 09 Jul 2004
Posts: 70

View user's profile Send private message

I2C slave not responding
PostPosted: Thu Jun 28, 2007 9:27 am     Reply with quote

I have been working on a project with an PIC16F819 running at a I2C slave for quite awhile now. I have had problems with the slave communication and was informed that there are errors in the ssp module of the device. I have added code to try to fix this. However, i am still seeing issues where the slave device does not always respond to the write request of the master. This happens about 10-20% of the time, the other 80% if gives back the correct information. I have stripped my code down to just the I2C routine and find that it is still having problems. I am trying to determine if i am still doing some thing incorrectly in my code or if i am battleing a problem with the chip. I have had micrchip look into this and they say that what i am doing should work and that it is most likely code/compiler issue. Could someone look at the following code and see if i am doing something incorrectly in my ssp_int that might cause me problems. It seems as if the PIC misses the command to write backt he data.
Compiler V 4.027
#include <16F819.h>
#device adc=10
#use delay(clock=8000000, RESTART_WDT)
#fuses WDT,INTRC_IO, PUT, MCLR, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG, NOPROTECT
#use i2c(SLAVE,FORCE_HW,fast,sda=PIN_B1,scl=PIN_B4,address=0x12,RESTART_WDT)
#include <math.h>

#use fast_io(A)
#define LED1 PIN_A0 //100% led
#define LED2 PIN_A1 //80% led
#define LED3 PIN_A2 //60% led
#define LED4 PIN_A3 //40% led
#define LED5 PIN_A4 //10-20% led, yellow
#define LED6 PIN_A6 //below 10% or fault led, red

#use fast_io(B)
#define sw_in PIN_B0 //switch
#define SMBD_E PIN_B1 //smbus data external
#define SMBD_I PIN_B2 //smbus data internal
#define SMBC_E PIN_B4 //smbus clock external
#define SMBC_I PIN_B5 //smbus clock internal

#define INTS_PER_SECOND 30
#BYTE SSPCON1 = 0x14




////////////////////////////////////////////////////////////////////////////////

int address,lsb_ch_crnt,lsb_percent,msb_status;
char i,int_count,bus_free,fault,change_current,chg_term=0,set=0;
int lsb_current,msb_current,count=0,msb,lsb_volt,lsb_status;
long time1,seconds,voltage,percent,status,ch_current;
long time_cnt=0,value,loop;
int32 new_val;
signed long current,temperature;
signed int i2c_temp,lsb_temp,lsb;


////////////////////////////////////////////////////////////////////////////////
#INT_SSP
void ssp_interupt (void) //detect external smbus activity
{
BYTE incoming, state;

state = i2c_isr_state();

if(state < 0x80) //Master is sending data
{
if(state == 1 ) //First received byte is address
{
incoming = i2c_read(1);
address = incoming;
bit_set(SSPCON1,4); //set to let clock float
}
if(state == 2) //Second received byte is data
{
incoming = i2c_read(1);
msb_current = incoming;
change_current=1;
}
}
if(state >= 0x80) //Master is requesting data
{
if(address==0x00)
lsb=lsb_status;
if(address==0x01) //i2c register
lsb=msb_status;
if(address==0x02) //i2c register
lsb=lsb_volt;
if(address==0x04) //i2c register
lsb=lsb_temp;
if(address==0x08) //i2c register
lsb=lsb_percent;
if(address==0x14) //smbus register
lsb=lsb_ch_crnt;
i2c_write(lsb); //write first byte
bit_set(SSPCON1,4); //set to let clock float
bit_clear(SSPCON1,5); //turn off serial
output_float(SMBC_E); //let go of clock line
output_float(SMBD_E); //let go of data line
bit_set(SSPCON1,5); //reanable serial
} //added due to errata with PIC

output_float(SMBC_E); //let go of clock line
output_float(SMBD_E); //let go of data line
}
#use delay(clock=8000000, RESTART_WDT)


//////////////////////////////////////////////////////////////////////////////
void main()
{

output_float(SMBC_I); //release data line
output_float(SMBD_I); //release clock line
output_float(SMBC_E); //release data line
output_float(SMBD_E); //release clock line
output_high(LED1); //turn led off
output_high(LED2); //turn led off
output_high(LED3); //turn led off
output_high(LED4); //turn led off
output_high(LED5); //turn led off
output_high(LED6); //turn led off
lsb_status=0x00;
msb_status=0x01;
lsb_volt=0x02;
lsb_temp=0x04;
lsb_percent=0x08;

setup_oscillator(osc_8mhz);
setup_adc_ports(NO_ANALOGS);
setup_wdt(WDT_36MS);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_256);
set_rtcc(0);
enable_interrupts(INT_RTCC);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
port_b_pullups(false); //added to see if this could be used on chg

set_tris_a(0b00000000);
set_tris_b(0b00010011);

int_count=INTS_PER_SECOND; //used for timer
seconds=0; //clear out variable
time1=15; //counter for time,30 seconds
loop=0;

while (TRUE)
{
output_float(SMBC_I); //release data line
output_float(SMBD_I); //release clock line
output_float(SMBC_E); //release data line
output_float(SMBD_E); //release clock line
output_high(LED1); //turn led off
output_high(LED2); //turn led off
output_high(LED3); //turn led off
output_high(LED4); //turn led off
output_high(LED5); //turn led off
output_high(LED6); //turn led off
//change smbus pins

}
}
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Thu Jun 28, 2007 9:55 am     Reply with quote

I've had problems with I2C acting up intermittently before. After scoping the signals and using LED's on various outputs to signal what's happening inside of the slave, I found that the timing was right on the edge of making it or not making it. I had to slow the master's signals down just a little to give the slave more time to do it's thing. I'm not sure if this is your situation but you could try to put delays between each command and see if it takes care of your problem. Then, start trimming the delays down until you get the correct timing that works 100%.

Using a scope and outputs, on the PIC, help tremendously in finding out how the PIC's timing is working.

Ronald
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