Continue to Site

Welcome to our site!

Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

  • Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.

PIC communication

Status
Not open for further replies.
Hi there

I need some help to understand and build this I²C hello world project.
I have two PIC16F819 with I²C hardware on pin 7 and 10 (right?)
I want them to communicate and send two bytes from the slave to the master. I want to know if my code is right and how to identify the right slave from the master. How to select the right slave if 10 slaves are connected? Do I need to send an adress and make the right slave respond to that - please show an example code.

Here are my small codes (mikroC is used, hope you'll understand)
The schematic is attached

Code:
 //SLAVE
 int data_array[2] = {0b10110010,0b11110100};

 void main() {
 TRISB = 0x00;
 PORTB = 0x00;

 I2C_Init(100000);         // Clock frequency
 I2C_Start();              // I2C start signal

 //????? Send an address

 I2C_Wr(data_array[1]);             // Write one byte to master
 I2C_Wr(data_array[2]);             // Write next byte to master
 I2C_Stop();
 }

Code:
 //MASTER
 int data_array[2] = {0,0};

 void main() {
 TRISB = 0xFF;
 PORTB = 0x00;

 I2C_Init(100000);         // Clock frequency
 I2C_Start();              // I2C start signal
 
 //????? To which slave
 
 I2C_Rd(data_array[1]);             // Read one byte from slave
 I2C_Rd(data_array[2]);             // Read next byte from slave
 I2C_Stop();
 }
 

Attachments

  • I2C PIC.PNG
    I2C PIC.PNG
    21.4 KB · Views: 270
You really ought to do a little research about the I2C bus. No offense, but you're way off in several areas, and it gives the impression that you don't even know the basics of the protocol - which you really need to know in order to implement it correctly. I2C isn't an incredibly complicated bus, however you have to realize that it's not like (for example) rs232 where you can just pump bytes out anytime you feel like it - there's a distinct master/slave relationship, and communication is more controlled. It's more work to deal with, but since the whole point is that it's a bus that many devices can be connected to, it's necessary for there to be control and arbitration.
The specification:
https://www.electro-tech-online.com/custompdfs/2007/02/39340011.pdf

You should probably clarify whether these proprietary I2C routines you are using are actually using the hardware modules, or bit-banging things, etc... Since I don't use MikroC I have no idea what they are actually doing.

Where to begin...
First, yes, you need to use an address, every packet starts with the master addressing a certain slave.

Second, I2C is bi-directional, both devices need to be able to drive the data line, and in some cases the slave needs to be able to control the clock line temporarily as well. Your schematic shows transistors as buffers, making that impossible.

Third, you have your slave sending start and stop conditions, sending data when the master isn't requesting it, and apparently generating a clock signal - basically acting all on its own - these are ALL wrong. The master always generates the clock signal (except in the special case of clock stretching, and that's only temporary), the master generates all start/stop conditions, and the slave never does anything unless the master is telling it to - even when the master is reading from the slave, it still starts the transaction to request data.

There's also a lot of other things you need to consider, especially on the slave side (in short, the slave needs to be responsive as fast as possible any time the master requests anything), but you need to fix these more important issues and understand the bus better before you deal with those...
 
Last edited:
Due to your reply I have redesigned the circuit and the code, hope you'll have another look (don't bother the mikroC code, just the generel use). I have also read some of the pdf file - and yes I don't know much about the I2C protocol yet. Thats why I need to try this first.

I changed my code so that the master sends an adress to the slave, if approved it'll send it back, and the master will light up a LED on RA0 - very simple I hope.

Code:
//MASTER
void main() {

int address = 0b11111110; // 7-bit address

//Initialize I2C bus
I2C_Init(100000);         // Clock frequency
TRISB = 0;
PORTB = 0;

//Write the data
I2C_Start();              // I2C start signal
I2C_Wr(address);          // Write address to slave
PORTB = 0;
TRISB = 0xFF;

//Get address back
do{
   int new_address = I2C_Rd(0);
   if(new_address == address)
      I2C_Stop();
      PORTA.F0 = 1;
  }while(1);
}

Code:
//SLAVE
void main() {

int address = 0b11111110; // 7-bit address

//Initialize I2C bus
I2C_Init(100000);         // Clock frequency
PORTB = 0;
TRISB = 0xFF;

do{
  if(I2C_Rd(0) == address)
    {
    TRISB = 0;
    PORTB = 0;
    I2C_Wr(address);
    I2C_Stop();
    }
  }while(1);
}
 

Attachments

  • I2C new.PNG
    I2C new.PNG
    16 KB · Views: 236
This is a prime example of why I always recommend that people NOT use functions proprietary to their compiler, especially when they're poorly documented...

I still can't help you very much since you're using proprietary functions - exactly what values does I2C_Init write to the appropriate configuration registers? Why are you giving it a clock frequency value on the slave? exactly what does I2C_Rd do? why are you playing with the PORTB and TRISB values during execution? (once set correctly, the I2C Hardware module will take care of its own I/O)

Since you are using I2C_Rd and I2C_Wr on both devices, one can only assume that they behave the same way on both, which means that you're still trying to make both PICs do things that ONLY the master should be doing - plus I see you're still telling the slave to send a stop bit, which, once again, is something only the master is supposed to do.

I highly recommend that you either A) find some existing, working example programs written for your exact compiler that actually use those proprietary functions properly so you're not just guessing, or B) (and this is much preferable) write non-proprietary code to interface the I2C hardware module yourself - take the time to read the PIC datasheet to learn how to use the hardware modules, and take the time to understand the I2C protocol in general.

It really doesn't make much sense to try and make it work before you actually understand how it's supposed to work...
 
Status
Not open for further replies.

Latest threads

New Articles From Microcontroller Tips

Back
Top