Hot!PIC Interface with MCP3425

Page: < 123 Showing page 3 of 3
Author
JorgeF
Super Member
  • Total Posts : 2912
  • Reward points : 0
  • Joined: 2011/07/09 11:56:58
  • Location: PT/EU @ Third rock from the Sun
  • Status: offline
Re: PIC Interface with MCP3425 2018/04/17 15:15:43 (permalink)
+1 (1)
Hi
 
I've found the time to do a quick review of the datasheet of the MCP3425.
I noticed that with this device things are very simplified, it doesn't implements internal addressable registers (like an RTCC for example), but it always outputs a full data set, ADC result followed by a status byte, so the reading is simpler than my conceptual example in the previous post.
 
This would be a conceptual approach to fetching all the data from the MCP3425 slave:

=== Read data packet from MCP3425====
// Store received data in buffer - buffer must be at least 3 bytes in size
// Return 1-> Sucess or 0-> Failure
bit I2c_Read_MCP3425(unsigned char *rx_buffer)
{
    // Master set start condition
    i2c_driver_start();
    mssp1_waitForEvent(0);
    mssp1_clearIRQ();
    // Master send slave device address for reading
    i2c1_driver_TXData(SLAVE_ADDR | 0x01); // slave address with LSB = 1 (read)
    mssp1_waitForEvent(0);
    mssp1_clearIRQ();
    // Check ACK from the slave
    if(i2c1_driver_isNACK()
        {
        i2c1_driver_stop();
        return 0; // Slave did not ACK the address --> Abort with error
        }
    // Master reads --- generates clocks for slave to send data
    i2c1_driver_startRX();
    mssp1_waitForEvent(0);
    mssp1_clearIRQ();
    // Received first data byte --- High ADC result ---
    buffer[0] = i2c1_driver_getRXData();
    // Master send ACK to the slave
    i2c1_driver_sendACK();
    mssp1_waitForEvent(0);
    mssp1_clearIRQ();
    // Master reads --- generates clocks for slave to send data
    i2c1_driver_startRX();
    mssp1_waitForEvent(0);
    mssp1_clearIRQ();
    // Received second data byte --- Low ADC result ---
    buffer[1] = i2c1_driver_getRXData();
    // Master send ACK to the slave
    i2c1_driver_sendACK();
    mssp1_waitForEvent(0);
    mssp1_clearIRQ();
    // Master reads --- generates clocks for slave to send data
    i2c1_driver_startRX();
    mssp1_waitForEvent(0);
    mssp1_clearIRQ();
    // Received third data byte --- STATUS ---
    buffer[2] = i2c1_driver_getRXData();
    // Last byte received send NACK to the slave (terminates communication)
    i2c1_driver_sendNACK();
    mssp1_waitForEvent(0);
    mssp1_clearIRQ();
    // Master set stop condition
    i2c_driver_stop();
    return 1; // success
}

Again, it was copy-paste-edit on-the-fly, so don't expect it to work out of the box.
 
#41
ajitnayak87
Senior Member
  • Total Posts : 150
  • Reward points : 0
  • Joined: 2017/06/20 03:53:02
  • Location: 0
  • Status: offline
Re: PIC Interface with MCP3425 2018/04/17 16:01:37 (permalink)
0
 Thanks for support provided. These are test i have conducted already
 
 
Now code modified to read only operation
 
 
void Read_MCP3425()
{
  i2c1_driver_restart();
  i2c1_driver_TXData(0XD1);// slave read operation
  i2c1_driver_startRX();
  ADCValue[0]=i2c_read(0);
      i2c1_driver_sendACK();
  ADCValue[1]=i2c_read(1);
      i2c1_driver_sendACK();
  I2C_Master_Wait();
  i2c1_driver_stop();
    
}

 
As per read operation  it should send like  Start  11010001 Slave_ack  higher byte master_ack  lower_byte master_ack Stop , But its not happening.
At jorgeF i have tested code it wont generate any I2c pulse itself. so i tested in commenting line by line
 
It will generate Start pulse after while sending read operation next pulse wont generate i tried putting write operation In place it wont pulse. The method of intilazation is correct either you can use 
i2c1_driver_open()
or
I2c1_Intialize()

Code hangs for below line
mssp1_waitForEvent(0);
    mssp1_clearIRQ();
i2c1_driver_TXData(SLAVE_ADDR | 0x01);

 
 
As soon as i send i2c1_driver_TXData(0XD1); function I2c Stop responding and creating waveform . It will generate waveform if input is i2c1_driver_TXData(0XD0);
post edited by ajitnayak87 - 2018/04/18 03:23:59

Attached Image(s)

#42
JorgeF
Super Member
  • Total Posts : 2912
  • Reward points : 0
  • Joined: 2011/07/09 11:56:58
  • Location: PT/EU @ Third rock from the Sun
  • Status: offline
Re: PIC Interface with MCP3425 2018/04/18 03:15:36 (permalink)
0
Hi
ajitnayak87
As soon as i send i2c1_driver_TXData(0XD1); function I2c Stop responding and creating waveform.

This is an address for read, after it you must call "i2c_driver_startRX()" so the master generates the clock pulses that allow the slave to send the data beeing read. Don't forget that the slave never generates the clock signal, its allways the master.
OTOH the data line is shared bettwen the master and the slave. After sending the read address the master releases the data line for use by the slave but keeps controling the clock line in order to generate the clocks that the slave needs to output its data. (*)
 
ajitnayak87
It will generate waveform if input is i2c1_driver_TXData(0XD0);

This is a address for writing, so the master remains in control of data line and sends whatever data it has to send.
 
If you look at the code generated by MCC, in the file "i2c_driver.c" you will see that the "mssp1_waitForEvent()" function simply waits for the SSP1IF flag to become active, meaning that the last operations has been completed, so you can proceed with the next one.
But it don't clears the SSP1IF flag, so it must be cleared (mssp1_clearIRQ()) in order not to gave a false "operation complete signals" on the next operation.
 
In the PIC datasheet, figure 26-29 at page 464 shows the timeline of a master reading 2 bytes from the slave. All actions from master and slave are commented as all the actions on the MSSP control flags and buffer.
You can cross check this picture with the sequence of operations in the code and the actions behind each function generated by the MCC ().
 
Also compare this picture with the signals you see in your scope/logic analyzer, this way you can spot exactly in what point things went wrong.
 
HIH
 
 
EDIT ADD:
(*) Don't forget that if the slave is not ready to send the requested data it can do a "clock stretch" until its ready to send its data. in this case the slave will keep the clock line low until its ready and things will seems to have stopped. If everything seems good until the moment the slave should start its data out, then set the logic analyzer/scope for a larger sample and see if something happens after a while (several miliseconds). I once had to cope with a temperature sensor that needed more than 700ms to finish a reading and be ready to send the data.
 
 
 
Best regards
Jorge
 
 
post edited by JorgeF - 2018/04/18 03:25:46
#43
ajitnayak87
Senior Member
  • Total Posts : 150
  • Reward points : 0
  • Joined: 2017/06/20 03:53:02
  • Location: 0
  • Status: offline
Re: PIC Interface with MCP3425 2018/04/18 03:23:20 (permalink)
0
Thanks George for support . The code started working after few changes , Its problem with address
#44
JorgeF
Super Member
  • Total Posts : 2912
  • Reward points : 0
  • Joined: 2011/07/09 11:56:58
  • Location: PT/EU @ Third rock from the Sun
  • Status: offline
Re: PIC Interface with MCP3425 2018/04/18 06:22:15 (permalink)
0
Hi
ajitnayak87
....The code started working after few changes, Its problem with address...



Good news, you are making progress.
 
BTW, I think you should read the third byte from the MCP3425. Its important because the flags in it are important to know if the previous 2 bytes are a valid result from the ADC.
 
 
Best regards
Jorge
 
#45
Page: < 123 Showing page 3 of 3
Jump to:
© 2018 APG vNext Commercial Version 4.5