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 on PIC18F4431

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



Joined: 06 Jun 2006
Posts: 7
Location: UK

View user's profile Send private message

I2C Slave on PIC18F4431
PostPosted: Tue Jun 06, 2006 8:10 am     Reply with quote

Hi,

I am trying to get a PIC18F4431 to be a slave device. However, I cannot get it to respond to messages sent over the bus. I have regressed to to using a modified EX_SLAVE.c file (only changed to match my PIC type and slave address) but there is no evidence of the PIC receiving anything. I have also noticed that the #use i2c command doesn't setup any of the SSP registers, and I have to explicitly set these myself. (This still doesn't get it to work).

Using a scope I can see that all the data being sent is correct, the start condition is OK and the levels are right. The code sending the data successfully talked to a 24LC64 eeprom, so I'm sure it's ok.

I've attached the code I'm using in case there is anything obviously wrong that I can't see.

I know it won't do much but I should be able to break in the interrupt when something has been received.

Code:
#include <18F4431.h>
#fuses HS,NOWDT,NOPROTECT,NOLVP
#use delay(clock=40000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7)

#use i2c(SLAVE, SDA=PIN_D2, SCL=PIN_D3, address=0x04, FORCE_HW)

#byte SSPCON    =   0xFC6
#byte SSPSTAT   =   0xFC7
#byte SSPADD    =   0xFC8
#byte SSPBUF    =   0xFC9

BYTE address, buffer[0x10];

#INT_SSP
void ssp_interupt ()
{
   BYTE incoming, state;

   state = i2c_isr_state();

   if(state < 0x80)              //Master is sending data
   {
      incoming = i2c_read();
      if(state == 1)         //First received byte is address
         address = incoming;
      if(state == 2)         //Second received byte is data
         buffer[address] = incoming;
   }
   if(state == 0x80)         //Master is requesting data
   {
      i2c_write(buffer[address]);
   }
}

void main ()
{
   SSPCON = 0b00100110; /* Enable, Slave, 7-bit addressing */
   SSPADD = 0x04;       
   enable_interrupts(GLOBAL);
   enable_interrupts(INT_SSP);

   while (TRUE) {}
}



If anyone has any ideas what migh be wrong or why the #use i2c command doesn't set the registers then please let me know.


Compiler Version 3.249
MPLAB 7.20, ICD 2
Ttelmah
Guest







PostPosted: Tue Jun 06, 2006 8:38 am     Reply with quote

Try adding 'SSP_RD' to the fuses, and see if it then sets up the registers itself. On the 4431, the I2C pins, can be selected to be C2/C3, or C4/C5. This is the fuse to select the former, and unless the selection is right, the compiler will 'know' that the hardware is not on these pins (and hence will not setup the hardware), and the hardware won't work.

Best Wishes
rnielsen



Joined: 23 Sep 2003
Posts: 852
Location: Utah

View user's profile Send private message

PostPosted: Tue Jun 06, 2006 8:42 am     Reply with quote

Make sure which pins are actually being used for SDA and SCL. There is a bit SSPMX that decides which pins are muxed with these signals. CONFIG3H is the register that contains this bit. I've never used this part so I'm not sure if the compiler sets this bit properly.

Personally, I don't like using the built-in functions for i2c Slaves. I like monitoring the registers and doing things manually. There are several examples of this on the forums. Start by simply trying to get the Slave to ACK back. i2c_start(), i2c_write() and i2c_stop(). These commands should get the Slave to ACK. If not you might be using the wrong pins, wrong addressing, wrong electrons(just kidding) Wink ... a number of things could mess it up. Or simply that the compiler isn't doing things right. Shocked

Start extremely simple and then build on that.

Ronald
Paul Rine
Guest







I2C on 18F4431
PostPosted: Wed Jun 07, 2006 1:05 am     Reply with quote

Thanks for the help guys. I had just come accross the SSPMX bit in the manual and hadn't figured out how to set it.

With regards getting the compiler to set the SSP registers I have noticed that if I use SSP_RC in the #fuses directive and select the relevant pins (C4 and C5) in the #use I2C command, the registers are set. (In fact, using C4 and C5 works without the SSP_RC command presumably because the processor defaults to this state). However, by replacing these with the SSP_RD, D2 and D3 respectively, the registers are not set. Is this a bug or am I missing something?
Ttelmah
Guest







PostPosted: Wed Jun 07, 2006 2:09 am     Reply with quote

Probably a bug. It sounds as if the compiler then decides that the hardware is not present on the pins it expects...

Best Wishes
Paul Raine



Joined: 06 Jun 2006
Posts: 7
Location: UK

View user's profile Send private message

PostPosted: Wed Jun 07, 2006 3:46 am     Reply with quote

I have my version of EX_SLAVE.c working now, so thanks for all your help. Very Happy
Bill R
Guest







Similar problems with I2C on 18F4431
PostPosted: Thu Jun 22, 2006 3:46 pm     Reply with quote

I am running into similar difficulty on the 4431 with the slave. The folks at CCS have verified there is a bug in the compiler when attempting to use the alternate I2C pins. The register assignments are not handled correctly, but they tell me it will be corrected in the next release of the compiler. This applies to both master and slave modes when using the hardware. I got around it by using the SW mode on the master, but need the hardware mode on this board.

I'm still running into a problem getting the 4431 to work as a slave, even using the port C I2C pins. How did you resolve your problems with 4431 functioning as a slave ? Thanks
Paul Raine



Joined: 06 Jun 2006
Posts: 7
Location: UK

View user's profile Send private message

PostPosted: Thu Jun 29, 2006 7:22 am     Reply with quote

I used the following configuration

Code:
#use I2C (SLAVE, SDA=PIN_C4, SCL=PIN_C5, ADDRESS=0x04, FORCE_HW, FAST = 1000000)


and then the standard CCS functions in the interrupt i.e i2c_isr_state, i2c_write, i2c_read.

My implemenation is relatively simple, as I only request the same data from the PIC, so I have no worries of sending an address to read from etc.

The main change was using the pins shown above and not the Port D pins

Hope this helps
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