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 without interrupt handler

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



Joined: 29 Jul 2009
Posts: 1

View user's profile Send private message

I2C slave without interrupt handler
PostPosted: Tue Nov 10, 2009 7:42 am     Reply with quote

Hi all,
can you help me with I2C for slave without interrupt handler? I have this code for it (chip is PIC18F4480), but it doesn't works:

Code:

#include <18F4480.h>

#device ADC=10

// Configuration bits
#fuses INTRC_IO
#fuses NOPROTECT
#fuses NOLVP
#fuses NOWDT

// Oscillator frequency 8MHz
#use delay(clock=8000000)

// UART configuration
#use RS232(baud=19200,xmit=PIN_C6,rcv=PIN_C7,bits=8,parity=N)
#use I2C(slave,scl=PIN_C3,sda=PIN_C4,force_hw)

void main() {
  char command[20];
  int1 process;

  process = FALSE;
  SSPCON1 = 0x36;
  SSPCON2 = 0x00;

  for(;;) {
    if(SSPSTATbits.BF) {
      int word;
      int index;

      memset(command,0,sizeof(command));
      index = 0;
      do {
        word = i2c_read();
        PIR1bits.SSPIF = 0;
        command[index++] = word;
        if(word == 0)
          break;
      } while(SSPSTATbits.BF);
      process = TRUE;
    }
    if(process) {
      printf("Cmd=%s\r\n",command);
      process = FALSE;
    }
  }
}


It receive address byte and then stuck.

Master send message in ASCII format (example): "DF_123\0"
'\0' = 0 ... it means end of message (NULL terminated string).

Thanks.
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Nov 10, 2009 8:20 am     Reply with quote

Quote:
It receive address byte and then stuck.
Yes, most likely with a receive overflow.

Why do you think, that while(SSPSTATbits.BF) will allow you to receive all transmitted characters at once? After receiving the address byte, BF is low for a while and your code hastily truncates the reception. You must either know the number of transmitted characters and wait until they all come in or implement a timeout of at least one I2C character frame.
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Tue Nov 10, 2009 9:29 am     Reply with quote

First of all, why would you NOT want to use the ISR? It's there for a reason and it makes things very easy.

Looking at your code, if the BF bit is true you call a function memset() and inside that you call sizeof(). Your data, on the I2C bus, is coming in very fast. The calls, to these two functions, are going to take WAY more time that you can afford and WILL lose data.

You might want to re-think what you want to accomplish.

Ronald
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Nov 10, 2009 1:10 pm     Reply with quote

Quote:
The calls, to these two functions, are going to take WAY more time that you can afford and WILL lose data.

sizeof() always evaluates to a constant, it's no true function.
memset() would be a problem with a fast (400 kHz) I2C, it should be still O.K. at low speed (100 kHz).
Ttelmah
Guest







PostPosted: Tue Nov 10, 2009 3:58 pm     Reply with quote

There are a whole lot more comments to make:

Though we have been shown the 'slave' end, no 'master' has been given.

The I2C_hardware_, requires, an address byte. No address is specified for the slave setup shown. The SSPBUF, won't be loaded, till an address match has occured. Then the direction of the following bus transfer, is determined by the low bit of this address byte. The behaviour of the SSPBUF.BF bit, is determined by this direction bit for subsequent transactions.

So:
Add the address to the I2C setup. Make sure this is a legitimate standard address (>0xF, and even).
Ensure the master sends a start, address, (with the low bit being 0), and then sends the data, followed by a stop.
Modify the receive code, to check the data/address bit, and only start reading the data, once this is set.

I suspect the receive is not starting, since there is never an address match.

If you simply want to send data in one direction, without addressing, start, stop etc., then why not just use two wire SPI instead.....

Best Wishes
FvM



Joined: 27 Aug 2008
Posts: 2337
Location: Germany

View user's profile Send private message

PostPosted: Tue Nov 10, 2009 5:32 pm     Reply with quote

Why do you expect, that no valid address has been sent? Without it, no BF would be seen.

You can't be sure, that the I2C data have been completely correct, but from the post, there's no indication of an actual problem in this regard.
Wayne_



Joined: 10 Oct 2007
Posts: 681

View user's profile Send private message

PostPosted: Wed Nov 11, 2009 3:47 am     Reply with quote

I see a couple of issues.
Because we can't see the master code the firstproblem is your command termination.
'\0' or null is the normal string terminator in C. If your transmision code does something like:-
Code:

//assume str="DF_123\0"
for (i=0; i < strlen(str); i++)
{
  putc(str[i]);
}
// Or you just use
putc(str);

Because this code and putc both look for the termination char of '\0' (strlen will use your inserted '\0' as the string terminator) it will never send the '\0'!

Secondly.
if a character does NOT fill the buffer between the i2c_read() and the while(SSPSTATbits.BF) then it will drop out of the loop. this will most likely happen for each char so that when you print you will get a line
Cmd=c where c is the character recieved for each character.

Also, I am pretty sure that the first character read after an address match is the address! now if your address happens to be a printable character then fine otherwise you would get a coruppted output.

You do not show your definition of SSPSTATbits.BF either.
I presume it is in <18F4480.h>

Could you also show what output you do get.

What makes you think it has recieved the correct address and matched ?

just my thoughts.
Ttelmah
Guest







PostPosted: Wed Nov 11, 2009 4:21 am     Reply with quote

The point I was making about the address, is that he is not loading one anywhere. It is not in the #use I2C shown, and is not being done manually later. The default SSPADD value, on power on, is 0, which is not a standard address. Addresses below 0xF, are defined in I2C, as special control addresses, and '0' is a general call address. The chip may well not behave normally for this address. Also, since this will be the first byte read, the code will terminate if this is the address being used....

Best Wishes
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