# [PIC]SPI and I2C on same controller

Status
Not open for further replies.

Dear all

In my project, i have to get I2C data from 3 slaves and after processing, out to SPI pins of PIC.
Available PIC is 16f877A that allow either SPI or I2C (not both simultaneously since pins are common)
While searching over net, I found that it is possible by implementing I2C on software but not sure how to do it for 3 slaves

Any idea?

#### barry

3 slaves or 100 slaves or 1 slave, it doesn't matter; the protocol is the same. The master sends out an address and only the slave whose address matches is allowed to drive the bus.
This might help
https://en.wikipedia.org/wiki/I²C

As stated, how to implement it in software since pins are used for SPI out

#### barry

You can't use pins for both SPI and I2C at the same time. Well, you're going to have to write the code to implement I2C, or else find it somewhere on the web. Somebody has probably already done this. You need to have pins that are open-drain in order to implement I2C.

#### Gorgon

##### Full Member level 6
Since the SPI functionality is easier to bit bang, you may use the I2C controller, and do the SPI in software, as long as you are the SPI master.

#### spudboy488

##### Full Member level 5
With all due respect Gorgon, I would (and have) done the opposite. Since SPI can run at much higher speed then I2C, I implement SPI in hardware and I2C in software. There are plenty examples of I2C in software that can be found with a little research.

To make things easy, use 2 pins that are NOT part of the SPI module to bit bang I2C.

Last edited:

#### Gorgon

##### Full Member level 6
From my point of view, you use the hardware controller for the protocol that is most used. In this case there are a factor of 3:1 for I2C:SPI, so I would have used the I2C controller.

Or, to be honest I would have used a bigger microcontroller with both protocols in hardware.

Whatever the outcome, it is up to the OP to select.

#### FvM

##### Super Moderator
Staff member
Looks like a trade-off, speed against software complexity. That's the point where you should leave the decision to the OP. You e.g. don't want to implement a protocol in software that's over your head. Or you say, it's no problem to gather the information from the internet and write the code from the scratch.

With all due respect Gorgon, I would (and have) done the opposite. Since SPI can run at much higher speed then I2C, I implement SPI in hardware and I2C in software. There are plenty examples of I2C in software that can be found with a little research.

To make things easy, use 2 pins that are NOT part of the SPI module to bit bang I2C.

Since controller is PIC-16f877A, i intend to use two pins for I2C (software) and SPI in hardware.
How could data flow will be from Input (I2C) to out (SPI)?
I have implemented both but never use them for same application

Regards

#### spudboy488

##### Full Member level 5
You will need to define a register (or variable) for the I2C routine you write. Use SSPBUF for SPI. You can then use them like any other register.

#### FvM

##### Super Moderator
Staff member
How could data flow will be from Input (I2C) to out (SPI)?
I'm not sure if I understand the question correctly. (And the answer not at all).
I would expect a set of functions like
Code:
i2c_start()
i2c_stop()
i2c_write()
which are implemented as bit-banging actions and called in the part of code that does the I2C slave interface.

"Data flow" also asks for the overall I2C and SPI activity schedule. There would be a continuously repeated sequence of I2C reads and SPI writes, possibly slowed down by a timer to a reasonable data rate.

#### spudboy488

##### Full Member level 5
If I can explain my answer a bit more, the register (or variable) for the I2C routine is the read value that would come from your listed i2c_read() function. For the one I wrote for my use, it would be
Code:
unsigned char I2C_IN;
SSPBUF is the register used for SPI transactions. The OP has routines for both I2C and SPI. They just need to get the data byte from the I2C routine and send it to the SPI routine. Maybe I'm not reading enough into the question.

Status
Not open for further replies.