|
|
View previous topic :: View next topic |
Author |
Message |
Paul Raine
Joined: 06 Jun 2006 Posts: 7 Location: UK
|
I2C Slave on PIC18F4431 |
Posted: Tue Jun 06, 2006 8:10 am |
|
|
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
|
|
Posted: Tue Jun 06, 2006 8:38 am |
|
|
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
|
|
Posted: Tue Jun 06, 2006 8:42 am |
|
|
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) ... a number of things could mess it up. Or simply that the compiler isn't doing things right.
Start extremely simple and then build on that.
Ronald |
|
|
Paul Rine Guest
|
I2C on 18F4431 |
Posted: Wed Jun 07, 2006 1:05 am |
|
|
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
|
|
Posted: Wed Jun 07, 2006 2:09 am |
|
|
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
|
|
Posted: Wed Jun 07, 2006 3:46 am |
|
|
I have my version of EX_SLAVE.c working now, so thanks for all your help. |
|
|
Bill R Guest
|
Similar problems with I2C on 18F4431 |
Posted: Thu Jun 22, 2006 3:46 pm |
|
|
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
|
|
Posted: Thu Jun 29, 2006 7:22 am |
|
|
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 |
|
|
|
|
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
|