|
|
View previous topic :: View next topic |
Author |
Message |
Will Reeve
Joined: 30 Oct 2003 Posts: 209 Location: Norfolk, England
|
I2C slave help please, seems to get stuck in the interrupt. |
Posted: Mon Feb 07, 2005 2:40 pm |
|
|
I�ve got a bit of a strange problem with I2C communications. I have two PICs, one Master and the other Slave. It�s the slave which is a problem I think! At the moment I just want to get a byte back from the slave! The master is a 18F452 the slave a 16F873. I am using compiler 3.212.
Master setup:
Code: | #use i2c(master, slow, sda=PIN_C4, scl=PIN_C3, FORCE_HW) |
I have set the master to do this at the press off a button.
Code: | i2c_start();
i2c_write(0x1F);
temp = i2c_read();
i2c_stop(); |
slave setup:
Code: | #use i2c(slave,sda=PIN_C4,scl=PIN_C3,force_hw,address=0x1F,slow) |
The slave does this in the int_ssp interrupt
Code: | #byte SSPCON = 0x14
#bit SSPOV = SSPCON.6
#int_SSP
SSP_isr() {
If (SSPOV) output_high(PIN_A0); // turn on LED if an overflow
if (i2c_poll() == FALSE)
i2c_write(0x16);
else
rxdata1 = i2c_read();
} // SSP_isr( | )
On the first press of the button, all works perfectly, the master gets the 0x16 byte but the slave enters the interrupt twice and get�s stuck there. The slave now holds the SLA line LOW.
Even stranger the second press (to run the master code again) does nothing (but the master now gets stuck!) the third press of the button (after reseting the master) causes the slave to �magically� return SDA line high, and leave the interrupt, and the forth press of the button works as the first, and so on. I can�t see any reference in the datsheet where the slave would hold SDA low like this? All the bits look �clean� on the �scope so I think the hardware is OK.
I think I must be missing something simple�my head hurts, any ideas? I�ve not used the I2C compiler commands for a slave before. |
|
|
Guest
|
|
Posted: Tue Feb 08, 2005 2:37 am |
|
|
Did you search the forum?
Try 'i2c slave' as search term. |
|
|
Will Reeve
Joined: 30 Oct 2003 Posts: 209 Location: Norfolk, England
|
|
Posted: Tue Feb 08, 2005 3:50 am |
|
|
Yep, everone seems to do it themselves (which I am now going to have a stab at this morning!). I try and use the inbuilt ccs functions where possible but it seems that in the case of i2c slave this is a bad idea? I can't even get EX_SLAVE to work correctly!
Keep well,
Will |
|
|
picer
Joined: 25 Jan 2005 Posts: 28 Location: Taxahoma
|
|
Posted: Tue Feb 08, 2005 9:11 am |
|
|
I cannot get ex_slave to work either on a 819, it acts like its working by putting in data but always reads back 00 in the example. |
|
|
rnielsen
Joined: 23 Sep 2003 Posts: 852 Location: Utah
|
|
Posted: Tue Feb 08, 2005 12:24 pm |
|
|
First of all, the address for your slave needs to be an even number. The LSB is used to determine if your a Reading or Writing to the slave. I believe the valid addresses (for 7bit addressing), according to the I2C standard from Philips, is from 0x10 - 0xEE. I could have read their table wrong but there are certain addresses that are reserved just in case you want to stay withing specs of the I2C standard.
Here is an ISR that I have used in a slave that works well.
Code: |
#include <16F87.h>
#use i2c(Slave,fast,sda=PIN_B1,scl=PIN_B4,restart_wdt,address=0x90)
#byte SSPBUF = 0x13
#byte SSPSTAT = 0x94
#byte SSPCON = 0x14
//SSPCON bits
#bit CKP = SSPCON.4
#bit SSPOV = SSPCON.6
//SSPSTAT bits
#bit STOP = SSPSTAT.4
#int_SSP // I2C interrupt service routine
SSP_isr()
{
int8 data;
static int8 state = 0;
if(SSPOV)// Make sure the buffer has not overflowed
{
data= SSPBUF;// read the buffer
SSPOV=0; // Clear the register
return;
}
if(STOP)// if we have received a STOP bit then exit
{
return;
}
else
{
switch(SSPSTAT & 0x2D)// 0x2D filters out bits that we don�t need to look at
{
CASE 0x0C:// Master rx, slave address + 1
CKP = 0;// hold SCL low to give us time to respond
SSPBUF = stage[index];// stuff the buffer with the data to send
CKP = 1;// release the SCL line
break;
CASE 0x2C:// Master rx, send data with /ack
CKP = 0;
SSPBUF = stage[index];
CKP = 1;
break;
CASE 0x28:// Master rx, send data with no /ack
doyourthing = 1;
break;
default:
break;
}//end of switch()
}// end of else
}// end of SSP interrupt
|
Ronald |
|
|
Will Reeve
Joined: 30 Oct 2003 Posts: 209 Location: Norfolk, England
|
|
Posted: Thu Feb 10, 2005 10:39 am |
|
|
Thank you, thank you, thank you! It was the address not being an even number which was screwing me :-) |
|
|
e
Joined: 02 Feb 2005 Posts: 9 Location: New York City
|
|
Posted: Tue Feb 15, 2005 9:11 pm |
|
|
rnielsen, just curious, why do you use pins B1 and B4 rather than the C3/C4 hardware port? while on the subject, what are the advantages of those pins and FORCE_HW? |
|
|
|
|
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
|