Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

problems with I2C communication

Status
Not open for further replies.

vasiliugeo

Newbie level 4
Joined
May 15, 2008
Messages
7
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,390
pickit2 i2c

Hy to everybody, I'm new here. I'm woerking right now at my diploma project: I want to make a I2C communication between a Explorer 16 board from Microchip which has a dsPic33fj256gp710(I want to be the master one) and a pickit2 which has a pic16f887(the slave one). I wrote the folowing code for the master(dsPic33) but when I'm using the osciloscope is nothing to see, not even the clock. Please help me somehow.

include <p33FJ256GP710.h>

unsigned char Hbyte,Lbyte, x;

#define SCL1 TRISGbits.TRISG2 //cu ac. selectam I sau O
#define SDA1 TRISGbits.TRISG3 //-------//--------

#define SCL_VAL PORTGbits.RG2 // VALORILE BITILOR DE IESIRE SDA SI SCL
#define SDA_VAL PORTGbits.RG3

#define trisd3 TRISAbits.TRISA0 //
#define d3 PORTAbits.RA0 //

void i2c1_init(void);
void transmit(void);

void i2c1_init()
{
SCL1 = 0; //SELECTAM SDA SI SCL CA FIIND IESIRI
SDA1 = 0;

SCL_VAL = 0; //SELECTAM VALORILE LUI SCL SI SDA IN HIGH
SDA_VAL = 0;

trisd3 = 0;

//ODCG = 0xFFFF; //open drain control register

I2C1BRG = 0x016B;// SETTING THE CLOCK RATES 100KHZ

I2C1CON = 0x8000; //Enable I2C1 module; A10M=0 7-bit address

// I2C1ADD = 0x70; // 7-bit I2C slave address must be initialised here.
//(0x08-0x77 Valid 7-bit addresses)
I2C1ADD = 0x05;
I2C1CONbits.STREN = 1;

Hbyte = 0x00;
Lbyte = 0x08;
}

int main(void)
{
while (PORTDbits.RD6 ) continue;
i2c1_init();
while(1)
{
// i2c1_init();
/* wait here until switch S3 is pressed */


// I2C1CONbits.STREN = 1;
// I2C1CONbits.SCLREL = 0;

// for (x=0; x< 100; x++);

I2C1STATbits.S = 1; //setari inainte de start condition
I2C1STATbits.P = 0;
I2C1CONbits.SEN = 1; // Start condition
while(!_MI2C1IF) continue; //MI2CxIF interrupt is generated at completion of the Start condition.
// while(!_MI2C1IF);
_MI2C1IF = 0;
I2C1TRN = 0x0070; // slave adress with the R/W bit=0 am ales adresa la intamplare
while(I2C1STATbits.TBF)continue; //TBF=0 Transmit complete, I2CxTRN is empty(verific daca s-a incarcat reg I2C1TRN)
I2C1STATbits.TBF = 0;
while(I2C1STATbits.ACKSTAT) continue;//verific daca s-a receptionat de catre slave primul byte
I2C1TRN = Hbyte; //incarc registrul de trensmisie al masterului cu partea high a adresei deunde vreau sa citesc
while (I2C1STATbits.ACKSTAT) continue;//verific daca s-a receptionat aceast byte
I2C1TRN = Lbyte; //incarc registrul de transmisie cu partea low
while(I2C1STATbits.ACKSTAT) continue; //verific daca a fost receptionat


I2C1CON = I2C1CON&0xFFE0;
I2C1STATbits.S = 1; // generate a repeated start bus event
I2C1STATbits.P = 0;
I2C1CONbits.RSEN = 1; //setam bitul de restart

I2C1TRN = 0x0071; //slave adress with the R/W bit=1(read);
while(I2C1STATbits.ACKSTAT) continue;

/*
I2C1CON = I2C1CON&0xFFE0; //The lower 5 bits of the I2CxCON register must be ?0? before attempting to set
//the RCEN bit.This ensures the master logic is inactive.


I2C1CONbits.RCEN = 1; //Receive Enable bit
//while(!I2C1STATbits.RBF); //asteptam ca sa se receptioneze datele de la slave

I2C1CON = I2C1CON&0xFFE0;
I2C1CONbits.ACKEN = 1; //enables generation of a master Acknowledge sequence.
I2C1CONbits.ACKDT = 0; //Send ACK during Acknowledge

I2C1CON = I2C1CON&0xFFE0;
I2C1CONbits.PEN = 1; //stop contidion
while(!_MI2C1IF) continue; //The module generates the MI2CxIF interrup at the end of stop event
*/
d3= 1;


}


}


Sorry for my english:(
 

i2c1statbits.ackstat

I dont think yo should use a delay or ack in between sending higher and lower data. You seem to violate I2c rules.
Could you please confirm if you are using 8 bit or 10 bit addressing in I2C.
 

i2c1add

The new PICkit2 2.50 software includes a 3 channel logic analyzer, very handy for watching those I2C signals.
 

i2c1con dspic

i'm using 7-bit adressing, and i'm waiting there for the ack I think it is ok there. Can I see with the Pickit 2 analizer the signals from the bus? I did some modifications :


#include <p33FJ256GP710.h>

unsigned char Hbyte,Lbyte, x;

#define SCL1 TRISGbits.TRISG2 //cu ac. selectam I sau O
#define SDA1 TRISGbits.TRISG3 //-------//--------

#define SCL_VAL PORTGbits.RG2 // VALORILE BITILOR DE IESIRE SDA SI SCL
#define SDA_VAL PORTGbits.RG3

#define trisd3 TRISAbits.TRISA0 //
#define d3 PORTAbits.RA0 //

void i2c1_init(void);

void i2c1_init()
{
SCL1 = 0;//SELECTAM SDA SI SCL CA FIIND IESIRI
SDA1 = 0;

SCL_VAL = 1; //SELECTAM VALORILE LUI SCL SI SDA IN HIGH
SDA_VAL = 1;

trisd3 = 0;

//ODCG = 0xFFFF; //open drain control register

I2C1BRG = 0x016B;// SETTING THE CLOCK RATES 100KHZ

I2C1CON = 0x8000; //Enable I2C1 module; A10M=0 7-bit address

I2C1ADD = 0x70; // 7-bit I2C slave address must be initialised here.
//(0x08-0x77 Valid 7-bit addresses)

Hbyte = 0x00;
Lbyte = 0x08;
}

int main(void)
{ /* wait here until switch S3 is pressed */
while (PORTDbits.RD6 ) continue;
i2c1_init();
while(1)
{


I2C1STATbits.S = 1; //setari inainte de start condition
I2C1STATbits.P = 0;

I2C1CONbits.SEN = 1; // Start condition
while(!_MI2C1IF) continue; //MI2CxIF interrupt is generated at completion of the Start condition.
_MI2C1IF = 0;
I2C1CON = I2C1CON&0xFFE0;

I2C1TRN = 0x0070; // slave adress with the R/W bit=0 am ales adresa la intamplare
while(I2C1STATbits.TBF)continue; //TBF=0 Transmit complete, I2CxTRN is empty(verific daca s-a incarcat reg I2C1TRN)
while(I2C1STATbits.ACKSTAT) continue;//verific daca s-a receptionat de catre slave primul byte
while(!_MI2C1IF) continue;
_MI2C1IF = 0;

I2C1TRN = Hbyte; //incarc registrul de trensmisie al masterului cu partea high a adresei deunde vreau sa citesc
while(I2C1STATbits.TBF)continue;
while (I2C1STATbits.ACKSTAT) continue;//verific daca s-a receptionat aceast byte
while(!_MI2C1IF) continue;
_MI2C1IF = 0;

I2C1TRN = Lbyte ; //incarc registrul de transmisie cu partea low
while(I2C1STATbits.TBF)continue;
while(I2C1STATbits.ACKSTAT) continue; //verific daca a fost receptionat
while(!_MI2C1IF) continue;
_MI2C1IF = 0;


I2C1CON = I2C1CON&0xFFE0;
// generate a repeated start bus event
I2C1CONbits.RSEN = 1; //setam bitul de restart
while(!_MI2C1IF) continue; //MI2CxIF interrupt is generated at completion of the Start condition.
_MI2C1IF = 0;

I2C1TRN = 0x0071; //slave adress with the R/W bit=1(read);
while(I2C1STATbits.TBF)continue; //TBF=0 Transmit complete, I2CxTRN is empty(verific daca s-a incarcat reg I2C1TRN)
while(I2C1STATbits.ACKSTAT) continue;//verific daca s-a receptionat de catre slave primul byte
while(!_MI2C1IF) continue;
_MI2C1IF = 0;



I2C1CON = I2C1CON&0xFFE0; //The lower 5 bits of the I2CxCON register must be ?0? before attempting to set
//the RCEN bit.This ensures the master logic is inactive.
I2C1CONbits.RCEN = 1; //Receive Enable bit
while(!I2C1STATbits.RBF); //asteptam ca sa se receptioneze datele de la slave
while(!_MI2C1IF) continue;
_MI2C1IF = 0;

I2C1CON = I2C1CON&0xFFE0;
I2C1CONbits.ACKDT = 0; //Send ACK during Acknowledge
I2C1CONbits.ACKEN = 1; //enables generation of a master Acknowledge sequence.
while(!_MI2C1IF) continue;
_MI2C1IF = 0;


I2C1CON = I2C1CON&0xFFE0;
I2C1CONbits.PEN = 1; //stop contidion
while(!_MI2C1IF) continue;
_MI2C1IF = 0; //The module generates the MI2CxIF interrup at the end of stop event

d3= 1; // just light one led


}


}
 

dspic33 i2c problem

Since the comments are not in english I could not make out anything, but as per the rules of 12c. you need to send stop bit after completing the writing of data into the slave.

then again send start bit, along with dummy write in write mode, and then you need to read the data from the slaves with proper acknowledgement.
I think you have missed the stop bit after writing and there is no dummy write before reading.
dummy write is required because while in write mode the PC may be pointing to some location in the memory. dummy write brings the PC to required location or 00 and then we need to give read. If we dont give dummy write then PC will read the next location where there would no be no data so you wont get anything even if you read.
Moreover you should have a high resolution oscilloscope to measure the pulses. they are very fast and very difficult to capture it on CRO.
 

problems with i2c communication

I'm not familiar with dsPIC33xx and would have to learn the register definitions to check your code in detail. However, from your report, I understand a very basic problem that should be verified.

Basically, it's meaningful to test the I2C master standalone first. You told, you don't see a clock at all. There are only a few possible reasons, to my opinion:
1. You didn't setup the I2C master properly.
2. You issued no I2C command.
3. You didn't connect the right pins at the dsPIC.
4. You omitted the I2C pullup resistors.
5. You shorted the I2C lines.

The first step would be to get the master interface operate at all. Then you can try to communicate with a slave. It may be more easy to use an existing I2C chip as test object rather than programming the slave by yourself for first test.
 

i2c1brg

this microcontroler hasn't a register to setup it like a master properly, I am using the pull-up resistors. Today I will use a osciloscope and I will let you know guys if it works. Thanks.
 

i2c1con

is not working, when I wrote the code I folowed the chapre :Communicating as a single master.. from the atached document :(( Help me please
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top