Click here to Skip to main content
15,868,016 members
Please Sign up or sign in to vote.
5.00/5 (1 vote)
See more:
Hi...I have a problem with c programming for pic32 microcontroller. i have problem programming for I2C using PIC32. i need to program I2C to communicate with ADC chip AD9883A. I can write to the chip in sending a byte. But i have problem sending in multiple byte.This is my codes.. i hope someone can help me correct or have better codes to help me. Thanks...

#include <plib.h>

#define SYS_FREQ    (80000000)
#define PBCLK       (SYS)_FREQ/2)
#define Fsck        375000
#define BRG_VAL     (PBCLK/2/Fsck)
#define DELAY       1024*1024

unsigned char SlaveAddress;
int DataSz;
unsigned char i2cData[4] = {0x98,0x01,0xAA};
unsigned char i2cData2[4] = {0xAA,0xAB,0xAC,0xAD};


void i2c_writemany ( unsigned char i, unsigned char k )
{
    while(1)
    {
        unsigned char a, b, c;
        a = 0x01;
        b = *i2cData2;
        for ( ; a<i; a++ )
        {
            i2cData[0] = 0x98;
            i2cData[1] = a;
            i2cData[2] = b;
            int Index = 0;
            DataSz = 3;
            StartI2C1();//Send the Start Bit
            IdleI2C1();//Wait to complete
            while ( DataSz )
            {
                MasterWriteI2C1( i2cData[Index++] );
                IdleI2C1();//Wait to complete

                DataSz--;

                if( I2C1STATbits.ACKSTAT )
                break;
            }
            StopI2C1();//Send the Stop condition
            IdleI2C1();//Wait to complete
            b++;
        }
    }
}

int main (void)
{
    SYSTEMConfig(SYS_FREQ, SYS_CFG_WAIT_STATES | SYS_CFG_PCACHE);
    mOSCSetPBDIV ( OSC_PB_DIV_8 );  //Set Periph
    OpenI2C1( I2C_EN, BRG_VAL );    //Enable I2C channel
    i2c_write(i2cData);
    /*while(1)
    {
        i2c_writemany(6,i2cData);
        DELAY;
    }
}


[edit]Improved title, used code block to preserve formatting OriginalGriff[/edit]
Posted
Updated 2-Dec-21 23:26pm
v2

Not tried I2C myself, but Microchip have a good software library of code examples: I2C examples here[^]
It is always worth checking the Microchip site first, as this question is a bit specialist for a general programming site.
 
Share this answer
 
Does the break after your test of
limwy wrote:
if( I2C1STATbits.ACKSTAT )
take you out of the while loop after the first Ack is recieved?
Multibyte transmission after sending the adress and receiving an Ack should be to send 8 bits and wait for an Ack on the 9th clock pulse then either send another 8 bits and wait for an Ack again on the 9th clock pulse and so on until after an Ack you send a Stop bit.
I've also seen it assumed that 'I2C' is just involves sending when all goes well. But it also includes, dealing with errors and problems. For example, the sender being able to cancel a part transmission and tell
the slave to return to waiting for a START again.
Another problem I've seen is a byte being places in the output buffer for transmission but not shifted out.

Try putting a sccope on the clock and data lines it will reveal everything.
 
Share this answer
 
v2
Hi,

I have had a quick look at your code and I think you need to tidy it up a bit - there a few inconsitencies. If you do that it will be alot easier to follow.

For example,

unsigned char i2cData[4] = {0x98,0x01,0xAA};


This array has 4 elements, but only 3 are loaded, then it is overwritten in the code and then never changed again.

b = *i2cData2;


This seems to be the only use of i2cData2, so what is it for? Were you trying to get the address of it then increment through it, I'm not sure?

DataSz is declared globally, but is only used in the 'writemany' function, is it used (or corrupted) anywhere else? Could it be local (that would be better)?

'a' is initialised but is it ever used?

Also, as previously suggested Microchip have a great forums, give it a look.

http://www.microchip.com/forums/Default.aspx?[^]

Getting these things working the first time is always the hardest bit :)

Good Luck :thumbsup:
 
Share this answer
 
limwy wrote:
But i have problem sending in multiple byte.


Would help if you can tell us what the problem exactly is.
Also what does IdleI2C1 do?

Most problems with i2c are caused by not handling all parts of the I2C specification(as someone else has already pointed out). For e.g. does the function IdleI2C1 release the SDA line and then wait for the slave to pull it low? Or is it a simple delay loop. Sometimes you might have to wait a little bit more for the device to acknowledge than what is specified.
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900