Tutorial 38 I2C: Write multiple bytes

Home Forums MPLAB XC8 Tutorial Discussions Tutorial 38 I2C: Write multiple bytes

Viewing 12 reply threads
  • Author
    Posts
    • #5967
      NNEU
      Participant

      Dear StudentCompanion,

      I do have a question regarding your MPLAB I2C Tutorial (38).

      The MasterWrite example is clear. The example states that the I2C_MasterWrite command is used in the following way:

      I2C_MasterWrite(&byte, no. of bytes , I2C_ADDR, &status)

      The example you give, writes only one byte.

      My application needs to write two bytes, and I am not sure in which format these two bytes need to enter the function.

      It would be highly appreciated if you could give an example for a multiple byte write function.

      Best regards,

      Noel

    • #5968
      Bitahwa Bindu
      Keymaster

      Hi,

      Did you try to write in a loop? For example:

      for(counter=0; counter<blockSize; counter++)
      {
      // load address
      writeBuffer[0] = (uint8_t)(DS1307_DataAdd);
      writeBuffer[1] = *wrBuffer++;

      I2C1_MasterWrite(writeBuffer, 2, slaveDevAddr, &status);
      while(status == I2C1_MESSAGE_PENDING);

      DS1307_DataAdd++;
      }

       

    • #5979
      NNEU
      Participant

      Hi Bitahwa,

      Thanks for your quick reply!

      I can kind of understand the approach, yet I don’t fully understand where I can insert my parameters.

      Is DS1307_DataAdd one byte ? Where is the second byte ? And why would it be DS1307_DataAdd++ at the end ?

       

      I think it would help me to have an example for my specific application: some example parameters are:

       

      I2C_ADDR = 0x01 (this one is clear)

      byte one (register) = 0x00

      byte two (data) = 10001111

       

      It would also be nice to know how (or as what) the identifiers need to be declared (counter, blocksize )

       

      This is probably a piece of cake for someone who’s been working with PICs, but I still find it hard to wrap my head around, and would appreciate your help.

       

      Best regards,

      Noel

       

    • #5980
      Bitahwa Bindu
      Keymaster

      If you need to write to select first the register then to write the data, why do you want to send them in one write command?

      Write first the command to select the register, you will get the acknowledgement from the slave, then write the data to that register.

      That’s exactly what we did in this tutorial, first we sent the command to select the register using the first I2C_MasterRead(&TC74_cmd,1,I2C_Address,&I2C_status);

      Here TC74_cmd has the value of “0” to select the read temperature register.

      Once we are in this temperature register than we sent the new command to read the content of that register using the I2C_MasterRead() command in our code, but in your case than send another I2C_MasterRead() command now to write into that register, the first parameter will be your data.

      If you want to send a series of write commands in a sequence, then you can use the I2C_MasterTRBInsert() or I2C_MasterWriteTRB().

    • #5983
      NNEU
      Participant

      I tried that, using the following code:

      #define I2C_ADDR_DAC1 0x10

      #define I2C_ADDR_DAC2 0x12

      I2C2_MESSAGE_STATUS I2C_status = I2C2_MESSAGE_COMPLETE;

      void DAC_Initialize ()

      { // Control 1 register. Sets Auto MCLK & SF, I2S 32bit and RSTN=1

      uint8_t reg = 0x00;

      uint8_t cmd = 0x8F; //10001111

      I2C2_MESSAGE_STATUS status; I2C2_MasterWrite(&reg, 1, I2C_ADDR_DAC1, &status);

      while (I2C2_MESSAGE_PENDING == status); I2C2_MasterWrite(&cmd, 1, I2C_ADDR_DAC1, &status); while (I2C2_MESSAGE_PENDING == status); }
      vv
      However, that doesn’t give me the desired waveform

      Do you have any idea what could have gone wrong ?

      • This reply was modified 1 month, 3 weeks ago by NNEU.
      Attachments:
      You must be logged in to view attached files.
    • #5988
      Bitahwa Bindu
      Keymaster

      Are you receiving the acknowledgment from the slave when you access it register?

      Can you debug your code to find out if you are actually getting the correct status, your code can move the first loop. What values your variables are holding?

      Did you enable the interrupts?

    • #5989
      NNEU
      Participant

      I think I found the problem…

      The level shifter responsible for translating 5V logic to 3.3 is dead.

      Therefore, there is no communication and no acknowledgement. I will remove the level shifter, switch to SMbus logic levels and let you know how it goes.

      thanks so far.

    • #5990
      Bitahwa Bindu
      Keymaster

      OK. It’s always good to make sure the hardware is working before testing the code. With I2C, the first thing is to check the acknowledgement from the slave, if no acknowledgement no need to go further, check first what could be wrong.

    • #5991
      NNEU
      Participant

      Ive been working on the project some more.
      The DAC now sends acknowledge bits.

      Basically, it does exactly what the code suggests, but not what I want.

      As seen in the pictures below, the device slave address is sent twice; once for the register byte and once for the command byte.

      The device doesn’t seem to recognise this. It needs the command byte to follow the register byte directly (after the command byte was acknowledged)

      So even though there was another problem also, this gets us back to the initial question 🙂

       

      Attachments:
      You must be logged in to view attached files.
    • #5995
      Bitahwa Bindu
      Keymaster

      Each slave device has its own sequence to write/read, read your DAC datasheet to get its sequence. Then you will know which command should come after which one.

    • #5996
      NNEU
      Participant

      Yes, it should be:

      Slave address -ack- register address -ack- command -ack-.

      The problem is, that I don’t know how to do this.

      The code that you demonstrated (using two separate MasterWrites) does the following:

      Slave address -ack- register address -ack- …pause… Slave address -ack- command -ack.

       

       

    • #5997
      NNEU
      Participant

      Ok, I just figured it out,

       

      unit8_t data[2] = {register address , command};

      I2C_MESSAGE_STATUS status;

      I2C_MasterWrite (&data, 2, slave address, &status);

      while  (I2C_MESSAGE_PENDING == status);

       

      gives me the following (desired) waveform

      • This reply was modified 1 month, 3 weeks ago by NNEU.
      Attachments:
      You must be logged in to view attached files.
    • #6000
      Bitahwa Bindu
      Keymaster

      OK. It’s good that you are making progress.

Viewing 12 reply threads
  • You must be logged in to reply to this topic.
Select your currency
EUR Euro
USD United States (US) dollar