|
|
View previous topic :: View next topic |
Author |
Message |
Guest
|
i2c slave interrupt routine |
Posted: Fri Sep 09, 2005 1:13 am |
|
|
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
|
|
Posted: Fri Sep 09, 2005 3:16 am |
|
|
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
|
|
Posted: Fri Sep 09, 2005 6:55 am |
|
|
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
|
|
Posted: Fri Sep 09, 2005 7:27 am |
|
|
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
|
|
Posted: Fri Sep 09, 2005 2:18 pm |
|
|
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
|
|
Posted: Sun Sep 11, 2005 1:45 am |
|
|
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
|
|
Posted: Sun Sep 11, 2005 7:00 am |
|
|
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
|
|
Posted: Sun Sep 11, 2005 1:15 pm |
|
|
hey i got you. but i am newbie you know that.
and iam really in trouble.
iwill follow the suggestions. see you |
|
|
|
|
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
|