PDA

View Full Version : i2C with PIC16F87, need help



Lazuli
- 10th May 2011, 19:31
Hello,
I am struggling with I2C to communicate between PIC16F877A and a PIC16F87.
I have been looking at all the great examples in the forum and manage to get communication between two PIC16F877A but not when using a PIC16F87.
The problem I am having is during compilation which halt on the instruction:
SSPCON2 = 0
Checking the data sheet, I can see that this register is only available with PIC16F877A, so I tried to remove the instruction and compilation went through but it did not communicate.
So what do I need to do to make it work?
Just a quick overview of what I am doing. I want to have the PIC16F877A as a master and few other PIC as slave to either acquire data, or receive serial data and decode it. This is for a monitoring system on a boat, so it involves some sensors and NMEA data. Right now, most of the things work but only with the 877A when I could really use the 87.

I would really appreciate a code example for PIC16F87 in slave mode as I am stuck on this problem.
thanks,
Olivier

Acetronics2
- 10th May 2011, 19:57
Hi,

In the compiler examples ... here : http://melabs.com/samples/PBP-mixed/index.htm

you have I2C_Mast.bas and I2C_Slave.bas ...

that should help.

Alain

Lazuli
- 13th May 2011, 05:38
Hi,
I had looked at those examples before, but as I said in my question, this code does not compile with a PIC16F87 as the register SSPCON2 is not there.
So my question is what do I need to modify from this example.

mackrackit
- 14th May 2011, 01:36
Here is an example of hardware I2C, wrong chip, but you should get the idea.
http://www.picbasic.co.uk/forum/content.php?r=316-PIC-as-I2C-Master-Slaves

Demon
- 16th May 2011, 00:30
Here is an example of hardware I2C, wrong chip, but you should get the idea.
http://www.picbasic.co.uk/forum/content.php?r=316-PIC-as-I2C-Master-Slaves


It might not be a good example for a 16F87.



...
Like my other stuff, it ONLY works on 18F chips.
...

Demon
- 16th May 2011, 01:06
...
The problem I am having is during compilation which halt on the instruction:
SSPCON2 = 0
...



I have used I2C a lot, mainly on 16F628, 16F877, MCP23016 and external eeproms, and don't recall having to bother with that instruction.

Here are I2C-related instructions from one of my 16F628 programs. It reads from an MCP23016 I/O Expander, but the concept remains the same for all reads.



...
DEFINE OSC 16

DEFINE I2C_SLOW 1 ' Access I2C device above 8MHz
DEFINE I2C_HOLD 1 ' Permit I2C device to hold clock line low

pinSCL VAR PortA.2
pinSDA VAR PortA.3

varAddressI2C VAR BYTE
varCommandI2C VAR BYTE
varButtonsLeft VAR WORD ' MCP23016 chips have 16 I/O pins

conInLeftAddr CON %01000010 ' MCP23016 at hardware address "010"
conGenPurpRegI2C CON $00
...
Main:
varAddressI2C = conInLeftAddr
varCommandI2C = conGenPurpRegI2C
I2CREAD pinSDA,pinSCL,varAddressI2C,varCommandI2C,[varButtonsLeft]
...


Hope there's something in there that will help you get going.

EDIT: One last thing, I have 4K7 1/4W pull-up resistors on SCL and SDA.

mackrackit
- 16th May 2011, 02:00
It might not be a good example for a 16F87.
No, it is not a plug and play, but the OP is wanting to know how to use the hardware and I figured it would get him started.

He could use the software command as you pointed out butt there may be a reason why he can not.

Demon
- 16th May 2011, 03:42
It definitely can't hurt to look that's fur sure.

I don't know how many times I used bits and pieces from other designs and schematics when I was researching LCDs. They usually have particularities, but sometimes they share common techniques.

Charles Linquis
- 16th May 2011, 04:07
The confusing thing about I2C is there are MASTER reads and writes, and SLAVE reads and writes.

One of the definitions of an I2C MASTER is that the MASTER drives the clock.

I2CWRITE and I2CREAD are both master-side commands. That is, an I2CWRITE will write data to a slave, and an I2CREAD reads data from a slave.


So, you can't have communication between two PICs with I2CWRITE on one side and I2CREAD on the other. One side has to be the master and one side has to be the slave. Being a master is easy - you can start talking whenever you are ready. Being a slave is harder - you have to grab the data asynchronously, whenever it comes along. That is why it is best to have the slave be interrupt-driven as in my example.

I don't know for certain that the code won't run on a 16F part. I never use them. But I do know that it works great on an 18F2221, 18F2321 and an 18F8723.

Demon
- 16th May 2011, 04:18
...
Being a master is easy - you can start talking whenever you are ready. Being a slave is harder - you have to grab the data asynchronously, whenever it comes along.
...



And that would explain why I used USART to talk between Master-Slave PICs, and used I2C to talk to eeproms and I/O Expanders. lol

That project dates back to 2005-2006, it's been a while.

Demon
- 16th May 2011, 04:25
...
I am struggling with I2C to communicate between PIC16F877A and a PIC16F87.
...



Olivier,

Do you HAVE to use I2C?

Is there any reason why you couldn't use USART to communicate between the 16F877A and 16F87?

16F87 p.99 section 11 AUSART



The AUSART can be configured in the following
modes:
• Asynchronous (full-duplex)
• Synchronous – Master (half-duplex)
• Synchronous – Slave (half-duplex)


16F877A p.113 section 10 USART



The USART can be configured in the following modes:
• Asynchronous (full-duplex)
• Synchronous – Master (half-duplex)
• Synchronous – Slave (half-duplex)


The acronym is slightly different, but when you read the descriptions, they are the identical.

Charles Linquis
- 16th May 2011, 04:57
You can either use RS-232 or I2C or SPI or PSP or ... to talk between two PICs.

If you use RS-232, and you have only two chips in your little 'network' then it is trivial - just hook TXD to RXD and RXD to TXD. If you send two characters or less, you don't need interrupts - just check for PIR1.5 being set (that is what it is in 18F chips, anyway), then read the characters using HSERIN.

But the problem is - if your chips have only 1 RS-232 port, you have no RS-232 ports left. So, the solution is to use at least one chip that has two RS-232 ports, or to use a chip that has one RS-232 port and one I2C port. Your choice.

My example doesn't use bit-banging. It uses hardware. It uses real interrupts. It works on my chips.