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 interrupt routine

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








i2c slave interrupt routine
PostPosted: Fri Sep 09, 2005 1:13 am     Reply with quote

hi,
i have some difficulties in coding the interrupt routines when in slave mode reception. the master code is ok, it transmits but the slave cannot receive the data. any one help me with my small project- two pics are communicating with each other. i cannot get out of this...
Guest








PostPosted: Fri Sep 09, 2005 3:16 am     Reply with quote

master code -----------------------


#include <16F877.h>
#device adc=8
#use delay(clock=4000000)
#fuses NOWDT,XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use i2c(Master,slow,sda=PIN_C4,scl=PIN_C3)


void main()
{

port_b_pullups(FALSE);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);



set_tris_b(0x00);

output_high(pin_b7);
Delay_Ms(250);
Delay_Ms(250);
output_low(pin_b7);


i2c_start();

i2c_write(0xa0); // slave Device address

i2c_write(0x06); // port b adress in slave 16f877

i2c_write(0x04); // led on 3. bit

i2c_stop();




output_high(pin_b6); // shows i2c finished


}




slave code-------------------- the hard zone .. interrupt routine is taken from snibbe.. but it didnt work . pull ups were first 1.7 k then 5k . but no way. slow=50000 also wasnt accepted by compiler with a warning "bad " option. compiler is pcwh 3.206 .

help meeeeeee



slave code.............


#include <16F877.h>
#device adc=8
#use delay(clock=4000000)
#fuses NOWDT,XT, PUT, NOPROTECT, NOBROWNOUT, NOLVP, NOCPD, NOWRT, NODEBUG
#use i2c(Slave,Slow=50000,sda=PIN_C4,scl=PIN_C3,restart_wdt,address=0x0a)

unsigned char read_i2c(void);
void i2c_interrupt_handler(void);
void i2c_initialize(void);
void i2c_error(void);
void write_i2c(unsigned char transmit_byte);

#INT_SSP
void ssp_interupt ()
{
i2c_interrupt_handler();
}





#define RX_BUF_LEN 32


unsigned char slave_buffer[RX_BUF_LEN];
int buffer_index;
int comms_error;
int debug_state;


void i2c_interrupt_handler(void)
{

unsigned char i2c_mask = 0x2D; /* 0010 1101 */
unsigned char temp_sspstat;
unsigned char this_byte;
unsigned char tx_byte;
int x;

/* Mask out the unnecessary bits */
temp_sspstat = PIC_SSPSTAT & i2c_mask;

switch (temp_sspstat)
{
/* Write operation, last byte was an address, buffer is full */
case 0x09: /* 0000 1001 */
/* Clear the receive buffer */
for (x=0; x<RX_BUF_LEN; x++)
{
slave_buffer[x] = 0x00;
}
buffer_index = 0; /* Clear the buffer index */
this_byte = read_i2c(); /* Do a dummy read of PIC_SSPBUF */

debug_state = 1;
break;

/* Write operation, last byte was data, buffer is full */
case 0x29: /* 0010 1001 */
/* Point to the buffer */
this_byte = read_i2c(); /* Get the byte from the SSP */
slave_buffer[buffer_index] = this_byte; /* Put it into the buffer */
buffer_index++; /* Increment the buffer pointer */
/* Get the current buffer index */
/* Subtract the buffer length */
/* Has the index exceeded the buffer length? */
if (buffer_index >= RX_BUF_LEN)
{
buffer_index = 0; /* Yes, clear the buffer index. */
}
debug_state = 2;
break;

/* Read operation; last byte was an address, buffer is empty */
case 0x0C: /* 0000 1100 */
buffer_index = 0; /* Clear the buffer index */
/* Point to the buffer */
tx_byte = slave_buffer[buffer_index]; /* Get byte from the buffer */
write_i2c(tx_byte); /* Write the byte to PIC_SSPBUF */
buffer_index++; /* increment the buffer index */
debug_state = 3;
break;

/* Read operation; last byte was data, buffer is empty */
case 0x2C: /* 0010 1100 */
/* Get the current buffer index */
/* Subtract the buffer length */
/* Has the index exceeded the buffer length? */
if (buffer_index >= RX_BUF_LEN)
{
buffer_index = 0; /* Yes, clear the buffer index */
}
/* Point to the buffer */
/* Get the byte */
tx_byte = slave_buffer[buffer_index];
write_i2c(tx_byte); /* Write to PIC_SSPBUF */
buffer_index++; /* increment the buffer index */
debug_state = 4;
break;

/* A NACK was received when transmitting data back from the master. */
/* Slave logic is reset in this case. R_W=0, D_A=1, and BF=0. */
/* If we don't stop in this state, then something is wrong!! */
case 0x28: /* 0010 1000 */
debug_state = 5;
break;

/* Something went wrong!! */
default:
i2c_error();
break;
}
}

void i2c_error(void)
{
comms_error = 1;
}

void write_i2c(unsigned char transmit_byte)
{
unsigned char write_collision = 1;

while (PIC_SSPSTAT & PIC_SSPSTAT_BIT_BF) /* Is BF bit set in PIC_SSPSTAT? */
{
/* If yes, then keep waiting */
}

while (write_collision)
{
/* If not, then do the i2c_write. */
PIC_SSPCON1 &= ~PIC_SSPCON1_BIT_WCOL; /* Clear the WCOL flag */
PIC_SSPBUF = transmit_byte;

/* Was there a write collision? */
if (PIC_SSPCON1 & PIC_SSPCON1_BIT_WCOL)
{
/* Yes there was a write collision. */
write_collision = 1;
}
else
{
/* NO, there was no write collision. */
/* The transmission was successful */
write_collision = 0;
}
}
PIC_SSPCON1 |= PIC_SSPCON1_BIT_CKP; /* Release the clock. */
}

/* This function returns the byte in SSPBUF */
unsigned char read_i2c(void)
{
return PIC_SSPBUF;
}



void main()
{

port_b_pullups(FALSE);
setup_adc_ports(NO_ANALOGS);
setup_adc(ADC_OFF);
setup_psp(PSP_DISABLED);
setup_timer_0(RTCC_INTERNAL|RTCC_DIV_1);
setup_timer_1(T1_DISABLED);
setup_timer_2(T2_DISABLED,0,1);
enable_interrupts(INT_SSP);
enable_interrupts(GLOBAL);

set_tris_b(0x00);
output_high(pin_b7);
debug_state = 0;

while(1);


}
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Fri Sep 09, 2005 6:55 am     Reply with quote

First thing, register and then log in so that we know who you are and so that you can edit your posts.

Second, post code using the code button. It make it much easier to read and you might get more responses.

Third, since the code wasn't posted using the code button, I am not going to look through all of it but I did check a couple of things and found this

Master code
Code:

i2c_write(0xa0); // slave Device address

Slave code
Code:

#use i2c(Slave,Slow=50000,sda=PIN_C4,scl=PIN_C3,restart_wdt,address=0x0a)


Now look at the addresses. They are different.
Ttelmah
Guest







PostPosted: Fri Sep 09, 2005 7:27 am     Reply with quote

Add a couple of other little comments.
The reason the 'rate' won't work with the slow function is that this was only added about half a dozen compiler versions ago. However you don't want the 'rate' on the slave anyway. It is the I2C master that sets the speed the bus runs, so setting this in the slave is pointless...
You talk about driving an LED, yet the slave code just puts the data into a buffer, and does nothing with this to control the LED, so even if the address was right, not much is going to happen as shown.

Best Wishes
Guest








PostPosted: Fri Sep 09, 2005 2:18 pm     Reply with quote

leds are driven by an ic of maxim. so the slave is maxim(max6964). the ic drives the leds.

the main problem is the interrupt routine for the slave in fact this is not i am going to do. i will use ma6964 as a slave so i dont need interrupt routine for the future.

the step for now is to provide the communication between microcontrollers.

can you send me shorter version of an interrupt routine???
Guest








PostPosted: Sun Sep 11, 2005 1:45 am     Reply with quote

friends !!!

i am not done yet. i ve changed the addresses but it doesnt work properly yet. master cannot transmit. the bus stays always at 5V.

do you think the code is true?
Mark



Joined: 07 Sep 2003
Posts: 2838
Location: Atlanta, GA

View user's profile Send private message Send e-mail

PostPosted: Sun Sep 11, 2005 7:00 am     Reply with quote

Mark wrote:
First thing, register and then log in so that we know who you are and so that you can edit your posts.

Second, post code using the code button. It make it much easier to read and you might get more responses.

Third, since the code wasn't posted using the code button, I am not going to look through all of it but I did check a couple of things and found this



Don't like to follow suggestions? Notice how many responses that you have received? There's probably a reason.

One other thing is that you do not have a while(1) loop in your main.

http://www.ccsinfo.com/forum/viewtopic.php?t=24313
asunca



Joined: 09 Sep 2005
Posts: 36

View user's profile Send private message

PostPosted: Sun Sep 11, 2005 1:15 pm     Reply with quote

hey i got you. but i am newbie you know that.

and iam really in trouble.
iwill follow the suggestions. see you
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