Jump to content
Sign in to follow this  
Netlab

I2c Data Handling

Recommended Posts

Hi

 

I am having trouble getting my 16f819 to read data from an existing I2C bus. I'm confident that my SSP setup is correct, but when I try to read the data being transmitted the PIC seems to crash/hang.

The master on the I2C bus is only transmitting data. There is no facility for feedback to the master (apart from the I2C ack signals).

 

Am I making any obvious mistakes?

 

My code is included below

 

//////////////////////////////////////////////////////////////////////////////////////////////
//	Michael Eaton, Adrian Brown and John Duffy												//
//////////////////////////////////////////////////////////////////////////////////////////////
//	This code is controlling a slave I2C device. It waits until it is addressed and then	//
//	receives 5 bytes of data. The first byte is the address and the following four are		//
//	to be stored in variables called data1 to data4.										//
//////////////////////////////////////////////////////////////////////////////////////////////


#include <system.h>
#include <i2c_driver.h>

#pragma CLOCK_FREQ 8000000	  //config clock to 8mhz.

#pragma DATA _CONFIG, _INTRC_IO & _WDT_OFF & _CP_OFF & _PWRTE_OFF &_LVP_OFF

unsigned char data0 = 0;		//variables for storing the data received
unsigned char data1 = 0;		//via I2C. 
unsigned char data2 = 0;		//unsigned char = 8bits
unsigned char data3 = 0;
unsigned char data4 = 0;

void main()
{
osccon = 0x74;		//Sets internal oscillator stable bit and internal frequancey to 8MHz
intcon=0b11000000;	//set GIE and PEIE interrupts.
pie1=0x08;			//sets SSPIE on and other interrupts off in this register.
trisb.1=1;			//set portb pin 1 as input for I2C reception
trisb.4=1;			//set portb pin 4 as input for I2C reception
sspadd = 0x50; 		//set address as 0101 0000 (address 8 on device config)(0100 000 + 8 + R/W bit)
sspstat=0x00;		//clears all sspstat bits. 
sspcon=0x36;		  //sets ssp register to 00110110 (36hex) for I2C
adcon1 = 0x06;		//Sets all A/D ports to digital
trisa=0;			//set porta as outputs 	 
porta=0;			//set porta to zero, because they initialize to ON automatically

while (1)				//loop infinitely
{
porta.1=1;			//turn on green led
delay_ms(100);

porta.1=0;			//turn off green led
delay_ms(100);
}
} 

void interrupt()		//The interrupt routine. This starts when I2C comms is detected.
{
intcon=0x00;			//disable all interrupts (GIE and PIE)
data0=sspbuf;			//transfer i2c buffer to data0 and clear the buffer full bit 
pir1.SSPIF=0;			//clear the interrupt flag
sspcon.SSPOV=0;			//clear the overflow bit
while (sspstat.BF==0);	//loop here while data is being received. Waits for the Buffer Full bit.

//Data byte 1
data1=sspbuf;			//save i2c buffer to data1 and clear the buffer full bit
while (pir1.SSPIF==0);	//loop here until I2C interrupt occurs. 
pir1.SSPIF=0;			//clear the interrupt flag
sspcon.SSPOV=0;			//clear the overflow bit

//Data byte 2
while (sspstat.BF==0);	//loop here while data is being received. Waits for the Buffer Full bit.
data2=sspbuf;			//save i2c buffer to data2 and clear the buffer full bit
while (pir1.SSPIF==0);	//loop here until I2C interrupt occurs. 
pir1.SSPIF=0;			//clear the interrupt flag
sspcon.SSPOV=0;			//clear the overflow bit

//Data byte 3
while (sspstat.BF==0);	//loop here while data is being received. Waits for the Buffer Full bit.
data3=sspbuf;			//save i2c buffer to data3 and clear the buffer full bit
while (pir1.SSPIF==0);	//loop here until I2C interrupt occurs. 
pir1.SSPIF=0;			//clear the interrupt flag
sspcon.SSPOV=0;			//clear the overflow bit

//Data byte 4
while (sspstat.BF==0);	//loop here while data is being received. Waits for the Buffer Full bit.
data4=sspbuf;			//save i2c buffer to data4 and clear the buffer full bit
while (pir1.SSPIF==0);	//loop here until I2C interrupt occurs. 
pir1.SSPIF=0;			//clear the interrupt flag
sspcon.SSPOV=0;			//clear the overflow bit

intcon=0b11000000;		//enable GIE and PIE interrupts.
}

Thanks

Mike

Edited by Netlab

Share this post


Link to post
Share on other sites

I don't know anything about I2C but one thing strikes me.

Why are you sitting around in the middle of an interrupt service routine waiting for another interrupt?

That is a sure way to get your program to tie itself into knots.

Share this post


Link to post
Share on other sites

Also, do you need to disable and re-enable interrupts in the interrupt? I thought that was done automatically. Let me know if I'm wrong on that count, but my interrupts work fine without the manual disable, re-enable.

 

Can't help on the I2C, I'm struggling on that myself.

Share this post


Link to post
Share on other sites

hmmm, I see where you're coming from.

 

I was under the impression that the I2C interrupt flag would occur whenever data was received.

But I think you're right it doesn't make sense for it to be there. I'll get rid of the line and see if

I have any more luck.

 

Thanks for the help, I guess I just didn't look at the code logically since I've been staring at it for

days

 

Mike

Share this post


Link to post
Share on other sites

Join the conversation

You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

×
×
  • Create New...