AnsweredAssumed Answered

Incorrect data received from the MMA8451Q accelerometer

Question asked by wojciech22a on Aug 3, 2015
Latest reply on Aug 4, 2015 by Mark Butcher

Hi! I using KL25Z and KDS 3.0. I'm trying to write a program that will be send data from the accelerometer MMA8451Q and send this data via UART and blinking LED. I2C interface is configured correctly - when I read a register of "who I am" I received in response  "0x1A". I would like to receive the acceleration values from each axis from the registers with addresses from 0x01 to 0x06. I wrote a program for reading 7 consecutive bytes starting at byte address of 0x00 but this program did not work properly. MMA8451Q automatically increases by 1 of byte address read out - that's why I sent you only the address of the first register. After  reset KL25Z is sending 7 bytes of values "0x00 (status register), 0xC9 (value from OUT_X_MSB), 0xFC (OUT_X_LSB), 0x08 OUT_A (Y_MSB), 0xFC (OUT_Y_LSB), 0x7F (OUT_Z_MSB), 0x58 (OUT_Z_LSB). But in the every next   sequence of reading I get the following values: 0x00 (status register), 0xFF (value from OUT_X_MSB), 0xFF (OUT_X_LSB), 0xFF OUT_A (Y_MSB), 0xFF (OUT_Y_LSB), 0xFF (OUT_Z_MSB), 0xFF (OUT_Z_LSB).. These values are incorrect  because in the registers LSB first two bytes are reset. Please help.

 

#include "MKL25Z4.h"

static int i = 0;

void opz(int ile)

{

  int p;

  for(p=0;p<ile;p++)

  {

 

  }

}

void ledkonf(void)

{

  SIM_SCGC5 |= SIM_SCGC5_PORTB_MASK;

  PORTB_PCR19=PORTB_PCR19 &~(1<<10) &~(1<<9) | (1<<8);

  GPIOB_PDDR=GPIOB_PDDR | (1<<19);

}

void uartkonf(void)

{

 

  SIM_SCGC4=SIM_SCGC4| (1<<10);//enable uart0

  SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;//enable PORTA

  SIM_SOPT2 |= SIM_SOPT2_UART0SRC(1);

  PORTA_PCR1=PORTA_PCR1 &~(1<<10) | (1<<9) &~(1<<8);//010mask -uart

  PORTA_PCR2=PORTA_PCR2 &~(1<<10) | (1<<9) &~(1<<8);

  UART0_BDH=0x02;//9600 baud; OSR = 3; module clock 20.97152MHz SBR=546 = 1000100010

  UART0_BDL=0x22;

  UART0_C1 = 0x00;

  UART0_C2 = 0x00;

  UART0_C2=UART0_C2 | (1<<3);//TE bit on

  //UART0_S1=0xC0;

  UART0_C3 = 0x00;

  UART0_C4=0x03;//OSR-3

  UART0_C5=0x00;

}

void i2ckonf(void)

{

  SIM_SCGC4=SIM_SCGC4 | (1 << 6);

  SIM_SCGC5 |= SIM_SCGC5_PORTE_MASK;

  PORTE_PCR24=PORTE_PCR24 | (1<<10) &~(1<<9) | (1<<8);

  PORTE_PCR25=PORTE_PCR25 | (1<<10) &~(1<<9) | (1<<8);

  I2C0_C1 = I2C0_C1 | (1 << 7);//Enable I2C

  I2C0_C1 = I2C0_C1 | (1 << 6);//Enable I2C inter

  I2C0_F=0x2D;

}

void swiec(void)

{

   opz(100000);

   GPIOB_PDOR=GPIOB_PDOR|(1<<19);

   opz(100000);

   GPIOB_PTOR=GPIOB_PTOR|(1<<19);

   opz(100000);

}

void Transmisja( unsigned char data )

{

while ( !( UART0_S1 & (1<<7)));

UART0_D = data;

}

unsigned char Odbior( void )

{

while ( !(UART0_S1 & (1<<5)) );

return UART0_D;

}

 

int main(void)

{

    /* Write your code here */

    /* This for loop should be replaced. By default this loop allows a single stepping. */

  ledkonf();

  uartkonf();

  i2ckonf();

    for (;;) {

    unsigned char Kp='k';

    unsigned char x1[7];

    I2C0_C1 = I2C0_C1 | (1 << 5);//Start

    I2C0_C1 = I2C0_C1 | (1 << 4);//TX mode

 

    I2C0_D=0x3A;//Slave adress of MMA8451Q -write

 

      while ( !(I2C0_S & (1<<1)) );//Waiting of end of transmission -  IICIF

     I2C0_S = I2C0_S | (1 << 1);//Set IICIF

 

       I2C0_D=0x00;//sending adress of first register

 

      while ( !(I2C0_S & (1<<1)) );//Waiting of end of transmission

     I2C0_S = I2C0_S | (1 << 1);//Set IICIF

 

       I2C0_C1 = I2C0_C1 | (1 << 2);//Rstart

 

        I2C0_D=0x3B;//Slave adress of MMA8451Q - read

 

       while ( !(I2C0_S & (1<<1)) );//Waiting of end of transmission -  IICIF

     I2C0_S = I2C0_S | (1 << 1);//Set IICIF

 

       I2C0_C1 = I2C0_C1 & ~(1 << 4);//RX mode

 

       Kp=I2C0_D;//dummy read

       while (! (I2C0_S & (1<<1)) );//Wait for end of trans -receive - IICIF

           I2C0_S = I2C0_S | (1 << 1);//Set IICIF

           x1[0]=I2C0_D;//status

          while (! (I2C0_S & (1<<1)) );//Wait for end of trans -receive - IICIF

          I2C0_S = I2C0_S | (1 << 1);//Set IICIF

          x1[1]=I2C0_D;//OUT_X_MSB

          while (! (I2C0_S & (1<<1)) );//Wait for end of trans -receive - IICIF

          I2C0_S = I2C0_S | (1 << 1);//Set IICIF

          x1[2]=I2C0_D;//OUT_X_LSB

          while (! (I2C0_S & (1<<1)) );//Wait for end of trans -receive - IICIF

                I2C0_S = I2C0_S | (1 << 1);//Set IICIF

                x1[3]=I2C0_D;//OUT_Y_MSB

                while (! (I2C0_S & (1<<1)) );//Wait for end of trans -receive - IICIF

               I2C0_S = I2C0_S | (1 << 1);//Set IICIF

               x1[4]=I2C0_D;//OUT_Y_LSB

                while (! (I2C0_S & (1<<1)) );//Wait for end of trans -receive - IICIF

               I2C0_S = I2C0_S | (1 << 1);//Set IICIF

      /////////////////////////////         ////

          I2C0_C1 = I2C0_C1 | (1 << 3);//set NACK

          x1[5]=I2C0_D;//OUT_Z_MSB

          while (! (I2C0_S & (1<<1)) );//Wait for end of trans -receive - IICIF

          I2C0_S = I2C0_S | (1 << 1);//Set IICIF

           I2C0_C1 = I2C0_C1 & ~(1 << 5);//STOP

           I2C0_C1 = I2C0_C1 | (1 << 4);//TX mode

           x1[6]=I2C0_D;//OUT_Z_LSB

 

    Transmisja(x1[0]);//transmit via UART

    Transmisja(x1[1]);

    Transmisja(x1[2]);

    Transmisja(x1[3]);

    Transmisja(x1[4]);

    Transmisja(x1[5]);

    Transmisja(x1[6]);

       swiec();// blinking LED

    }

    /* Never leave main */

    return 0;

}

////////////////////////////////////////////////////////////////////////////////

// EOF

////////////////////////////////////////////////////////////////////////////////

Image from UART Terminal:

Rysyn.PNG

Outcomes