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 Over 16F690 x 16F877a

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



Joined: 27 Apr 2008
Posts: 167

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

I2C Over 16F690 x 16F877a
PostPosted: Sun Feb 05, 2012 4:17 pm     Reply with quote

Hi all.

I used to have a pretty good routine to interface two 16F877A, one as i2c master and the other one as slave. Now I need to put one 16F690 in the game, and I simply cannot put my slave routine to work on the 16F690.
Code:

#INT_SSP
void SSP_isr()
   {
   state=i2c_isr_state();
   if(state>=0x80)i2c_write(buffer[state-0x80]);
   else if(state>0)buffer[state-1]=i2c_read();
   if(state==0x07)i2c_message=1;
   }


It simply don't work, is it possible that the ENHANCED UART of 16F690 is doing something that I can't figure out?

Please help me.

Regards.
jeremiah



Joined: 20 Jul 2010
Posts: 1346

View user's profile Send private message

PostPosted: Sun Feb 05, 2012 6:50 pm     Reply with quote

I'm pretty surprised that work for two reasons:

1. Your not reading when state == 0x00 and you should
2. Your not reading when state == 0x80 and you should

You want something like (untested mind you):

Code:


if(state <= 0x80){  //reads incoming data
   buffer[state]=i2c_read();   //I changed state-1 to just state for now
}
if(state >= 0x80){  //writes incoming data
   i2c_write(buffer[state-0x80]);
}
if(state == 0x07){
   i2c_message=1;
}
rudy



Joined: 27 Apr 2008
Posts: 167

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

PostPosted: Mon Feb 06, 2012 3:01 pm     Reply with quote

Hi.

It is not working....

I made the following changes:

Code:

#INT_SSP
void SSP_isr()
   {
    state=i2c_isr_state();
     if(state <= 0x80)  //reads incoming data
      {
      buffer[aux]=i2c_read();   //I changed state-1 to just state for now
      aux++;
      }
   if(state >= 0x80)  //writes incoming data
      {
         i2c_write(buffer[state-0x80]);
      }
   if(aux == 0x07)i2c_message=1;
   }


Then, when the i2c_message flag is set, I turn off the SSP interruptin and put the buffer in eeprom, to analize after.

I can only see 0x04 in all eeprom addres, that is the slave address.

The data I am sending from master are:

{0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07}

I am pretty shure that the 0x04 value in eeprom is the slave adress, because I changed to 0x02, and the value in eepron becomes all 0x02.

I really don´t know what is going wrong.
Ttelmah



Joined: 11 Mar 2010
Posts: 19506

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 3:43 pm     Reply with quote

Remember if you send 8 bytes, there will be _9_ reads necessary. The first byte received by I2C, is the device address. So you should receive:
address, 0, 1, 2, 3, 4, 5, 6, 7

Your read will therefore terminate one byte early, and the next time you enable the interrupt (you should really leave it enabled....), the device will interrupt immediately, for the extra byte, and be out of sync from then on.

The UART has nothing to do with SSP.
The 16F690, only has an SSP module, not an MSSP module, but this shouldn't affect slave operation (it doesn't support master operation in the hardware).

Best Wishes
rudy



Joined: 27 Apr 2008
Posts: 167

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

PostPosted: Mon Feb 06, 2012 4:29 pm     Reply with quote

Hi,

Yes I know, something is really strange. My suspicion is that, I don't know why yet, the state doesn't change. i2c_isr_state(); is always equal to zero.

I start to think that the slave clock speed is wrong, although I use clock=4000000, I will check and revert back again.

Best regards
rudy



Joined: 27 Apr 2008
Posts: 167

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

PostPosted: Mon Feb 06, 2012 6:23 pm     Reply with quote

Hi.
It is finally perfect.

Code:

void SSP_isr()
   {
    state=i2c_isr_state();
     if(state > 0 && state <= 0x80) 
      {
      buffer[i2c_count]=i2c_read();
      i2c_count++;
      }
   if(state > 0x80)i2c_write(buffer[state-0x80]);
   if(i2c_count == 0x03)
      {
      i2c_message=1;
      i2c_count=0;
      disable_interrupts(INT_SSP);
      }
   }


In fact, the code was right, the only mistake was:

Code:

   .
   .
   .
   .
   if(state <= 0x80)  //reads incoming data
   .
   .
   .

   if(state >= 0x80)  //writes incoming data
   .
   .
   


As you can see, <= 0x80 and >= 0x80, "equal" at the same time.

So I give up state = 0, this is the address match condition, and it means nothing to me in this simple application.

I really don´t need this line even;

Code:

   .
   .

   if(state >= 0x80)  //writes incoming data
   .
   .



I discovered that I cannot go FAST, but when I use SLOW directive, it is pretty fine. This may be because of the strong capacitance of the wires in my protoboard, when I get the PCB, I will give another try to go FAST.


Best regards, and thanks to all friends.
jeremiah



Joined: 20 Jul 2010
Posts: 1346

View user's profile Send private message

PostPosted: Mon Feb 06, 2012 9:13 pm     Reply with quote

That actually surprises me. The <= and >= overlapping was on purpose. I haven't done I2C in a while, but I thought you had to do i2c_read() when state==0 and that you should i2c_read() and i2c_write() when state ==0x80. It surprises me that you don't have to now, but again, I haven't messed with I2C in a while.
rudy



Joined: 27 Apr 2008
Posts: 167

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

PostPosted: Tue Feb 07, 2012 4:41 am     Reply with quote

Yes you can.
I made a lot of tests, always stopping SSP ISR and recording the values on eeprom. When state==0, it means that you match the slave address only, the others bytes that follows address, drive state to be different them zero, that´s why I just jump over state == 0, because this is a simple routine, I just want to send three bytes of data to a slave, them it automatic update the ports states, and consequently, the relays attached to them.
Thanks anyway, your tip was very much appreciated, it make start to understand what was wrong in my original code.

Regards.
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