Everything can't be okay with your code and circuit if SCK is not generating a clock ;-)
(Note that SCK is for SPI. SCL is the name for the I2C pin. So below the reference to SCL is what you are calling SCK)
This could be as you haven't configured the pins properly as Leon mentions, or possibly as you haven't added pullup resistors to your SDA/SCL lines.
If you show your circuit (or just let us know if there are pullups present) and any I2C initialisation code (e.g. what happens in OpenI2C) we can confirm what the problem is.
EDIT - Looking at your schematic it looks like you have no pullup on SCL, which would account for nothing being seen on it. The I2C lines are driven using open drain outputs, which means the pin can only sink current, not source it.
If you add a resistor (say, 2k to 10k) from SCL to Vdd you should see something.
EDIT 2 - I'm not sure where it says no pullup is needed on SCL. I just had a look in the datasheet and I found this (page 207):
Selection of any I
2
C mode with the SSPEN bit set
forces the SCL and SDA pins to be open-drain,
provided these pins are programmed as inputs by
setting the appropriate TRISC or TRISD bits. To ensure
proper operation of the module, pull-up resistors must
be provided externally to the SCL and SDA pins.
Are you using a real PIC here or simulating things in ISIS? If it's a simulation then it may be something do to with how it's setup.
Have you got the TRIS bits set accordingly? (both to 1)
Also for good measure, set the ADCCON1 registers bits 3:0 all to 1, to set all the pins as digital. You can do e.g. ADCCON1 |= 0x0F;
for this.
My guess is that the problem indeed is that you need to delay after the write.
The device will be busy for roughly 3-5 milliseconds after a write, during which it will not respond to any commands. If you issue a read during this time period, the device will ignore it, and the SDA line will remain high - which would indeed lead to a result of all ones being read on the clock pulses.
First off, try adding a delay after the write, perhaps 10 milliseconds or so.
If that works, check the datasheet chapter on acknowledge polling, to improve the performance. In short, acknowledge polling means sending a write command over and over until the device acknowledges it, at which point you know that the write cycle is complete.
Best Answer
If you want to embed it in your C code you can use the pragma
config
directive to set the fuses. From the PIC18 configuration settings addendum it looks like the PIC18F4520 has four code protect blocks so you'd need the following to protect those and the boot block: