I2C se atascó esperando 8 ciclos en DSPIC33ev128

1

Soy nuevo en la comunicación I2C y, después de leer una serie de tutoriales sobre el protocolo, intenté conectar un microcontrolador Microchip DSpic 33ev128gm002 a un microcontrolador QMC5883L (Chinese Honeywell HMC5883L) con las bibliotecas periféricas del fabricante. Pude iniciar e iniciar el muestreo continuo en el sensor, y leer los valores x, y, z.

Sin embargo, este código está en un bucle, y en la segunda iteración el código parece detenerse en la instrucción: while(12C1STATbits.TBF) después de que se realiza la segunda escritura ( MasterWriteI2C1(0b00000000); )

El código que contiene el bucle es el siguiente:

'while(1){       

          /**
           * Read data from the magnetometer registers
           **/

           //check if idle
         IdleI2C1();
         //initiate start condition
         StartI2C1();
         //wait until start condition is over
         while(I2C1CON1bits.SEN == 1);
         /* Clear interrupt flag */
         // IFS1bits.MI2C1IF = 0;
          //send magnetometer address and append the write bit of 0
          MasterWriteI2C1(0b00011010);

         //wait till data is transmitted
         while(I2C1STATbits.TBF);  // 8 clock cycles

         while (!IFS1bits.MI2C1IF); //wait for 9th clock cycle

         //clear interrupt flag
         IFS1bits.MI2C1IF = 0;  //clear interrupt flag
         //I2C1STATbits.TBF = 0;


          //send register address : 0x00 = 0000000
          MasterWriteI2C1(0b00000000);

          //wait till address is transmitted
         while(I2C1STATbits.TBF);  // 8 clock cycles

         while (!IFS1bits.MI2C1IF); //wait for 9th clock cycle


          /* Clear interrupt flag */
          IFS1bits.MI2C1IF = 0;


         //generate another start condition

         //check if idle
          IdleI2C1();
         //initiate start condition
         StartI2C1();
         //wait until start condition is over
         while(I2C1CON1bits.SEN == 1);
         /* Clear interrupt flag */
         IFS1bits.MI2C1IF = 0;
         //send magnetometer address and append the write bit of 1 for READ
         MasterWriteI2C1(0b00011011);

          //wait till data is transmitted
         while(I2C1STATbits.TBF);  // 8 clock cycles

         while (!IFS1bits.MI2C1IF); //wait for 9th clock cycle

         //clear interrupt flag
         IFS1bits.MI2C1IF = 0;  //clear interrupt flag

         //read 1 byte
          char x_low = MasterReadI2C1();

         //send Master ACK
         AckI2C1();

          //read 1 byte
         char x_high = MasterReadI2C1();
         //send Master ACK
          AckI2C1();

          //read 1 byte
          char y_low = MasterReadI2C1();
         //send Master ACK
          AckI2C1();

           //read 1 byte
          char y_high = MasterReadI2C1();
         //send Master ACK
          AckI2C1();

          //read 1 byte
          char z_low = MasterReadI2C1();
         //send Master ACK
          AckI2C1();

           //read 1 byte
          char z_high = MasterReadI2C1();
          //send Master ACK
          AckI2C1();

          //read the other registers...

          char status_bits =  MasterReadI2C1();
          //send Master ACK
          AckI2C1();

          char T_out_low =  MasterReadI2C1(); 
         //send Master NACK not ACK!!
          NotAckI2C1();

          //check if idle
          IdleI2C1();
          StopI2C1();
          while(I2C1CON1bits.PEN == 1);//wait for stop condition flag to clear




              U1TXREG = x_low;
              //wait until char (byte) has been transmitted)
              while (IFS0bits.U1TXIF);

               __delay_ms(10);

              U1TXREG = x_high;
              //wait until char (byte) has been transmitted)
              while (IFS0bits.U1TXIF);

               __delay_ms(10);

              U1TXREG = y_low;
              //wait until char (byte) has been transmitted)
              while (IFS0bits.U1TXIF);

               __delay_ms(10);

              U1TXREG = y_high;
              //wait until char (byte) has been transmitted)
              while (IFS0bits.U1TXIF);

               __delay_ms(10);

              U1TXREG = z_low;
              //wait until char (byte) has been transmitted)
              while (IFS0bits.U1TXIF);

               __delay_ms(10);

              U1TXREG = z_high;
              //wait until char (byte) has been transmitted)
              while (IFS0bits.U1TXIF);





         __delay_ms(1000);


    }'

Este es el código para inicializar el módulo I2C:

/*Method to configure and set up I2C*/
void initI2C(void)
{
//SET I2C Lines to inputs
   _TRISB5 = 1;
   _TRISB6 = 1;

  TRISBbits.TRISB5 = 1;
  TRISBbits.TRISB6 = 1;

  CloseI2C1();

 //wait for magnetometer POW On time
 __delay_us(360);

  I2C1CONLbits.A10M = 0;
  I2C1CONLbits.GCEN = 0;
  I2C1CONLbits.STREN = 1;



I2C1BRG = 0x10; //16 in decimal

//enable i2c  called 12C1CONL register
I2C1CONLbits.I2CEN = 1;  }

Este es el código para configurar y configurar el sensor QMC5883L:

'//Method to initialise magnetometer for continuous measurement
void initMagnetometer(void)
{

         //Define set/reset period

        //check if idle
        IdleI2C1();

        //initiate start condition
        StartI2C1();
        //wait until start condition is over
         while(I2C1CON1bits.SEN == 1);

         //send commands to initialise magnetometer 
         //define set/reset period

         /* Clear interrupt flag */

          IFS1bits.MI2C1IF = 0;

          //since 7bit address it has to be shifted by one place
         // MasterWriteI2C1((0x0D << 1)); //Select device

          // MasterWriteI2C1(0x0D);

          //send address and append the write bit
          MasterWriteI2C1(0b00011010);

         //IdleI2C1();

         // MasterputcI2C1(MAGNETOMETER_ADD);

         //wait till address is transmitted
         while(I2C1STATbits.TBF);  // 8 clock cycles

         while (!IFS1bits.MI2C1IF); //wait for 9th clock cycle

           //wait for acknowledgement from slave
         //while(I2C1STATbits.ACKSTAT);

          /* Clear interrupt flag */

          IFS1bits.MI2C1IF = 0;

         //send register address : 0x0BH = 00001011
          MasterWriteI2C1(0b00001011);

         //wait till address is transmitted
         while(I2C1STATbits.TBF);  // 8 clock cycles

         while (!IFS1bits.MI2C1IF); //wait for 9th clock cycle



          //clear interrupt flag
         IFS1bits.MI2C1IF = 0;  //clear interrupt flag

          //send data : 00000001
          MasterWriteI2C1(0b00000001);

           //wait till data is transmitted
         while(I2C1STATbits.TBF);  // 8 clock cycles

         while (!IFS1bits.MI2C1IF); //wait for 9th clock cycle

          //clear interrupt flag
          IFS1bits.MI2C1IF = 0;  //clear interrupt flag

          StopI2C1();


          /**
           * set continuous mode measurement
           **/

          //check if idle
         IdleI2C1();

         //initiate start condition
         StartI2C1();
         //wait until start condition is over
         while(I2C1CON1bits.SEN == 1);

         /* Clear interrupt flag */

          IFS1bits.MI2C1IF = 0;

          //send magnetometer address and append the write bit
          MasterWriteI2C1(0b00011010);

         //wait till address is transmitted
         while(I2C1STATbits.TBF);  // 8 clock cycles

         while (!IFS1bits.MI2C1IF); //wait for 9th clock cycle

          /* Clear interrupt flag */

          IFS1bits.MI2C1IF = 0;

           //send register address : 0x09 = 00001001
          MasterWriteI2C1(0b00001001);

          //wait till address is transmitted
         while(I2C1STATbits.TBF);  // 8 clock cycles

         while (!IFS1bits.MI2C1IF); //wait for 9th clock cycle

          /* Clear interrupt flag */
          IFS1bits.MI2C1IF = 0;

          //send data
           //send data : 00011101
          MasterWriteI2C1(0b00011101);

           //wait till data is transmitted
         while(I2C1STATbits.TBF);  // 8 clock cycles

         while (!IFS1bits.MI2C1IF); //wait for 9th clock cycle

         //clear interrupt flag
         IFS1bits.MI2C1IF = 0;  //clear interrupt flag

         StopI2C1();

         while(I2C1CON1bits.PEN == 1);//wait for stop condition flag to clear


         //wait for magnetometer to create sample
          __delay_ms(1000);    }

¡La ayuda es muy apreciada!

    
pregunta John

0 respuestas

Lea otras preguntas en las etiquetas