I am working with MPU6050 and STM32f103VE as master. When I wake up the sensor and ask for information it returns 3 bytes of zeroes and the protocol stops working. I only send the communication Part of my code to be more specific:

void I2C_interface(void){       
    I2C1->CR1 |=I2C_CR1_START;              //Generating Start condition
    while(!(I2C1->SR1 & I2C_SR1_SB)); //making sure the communication has started
    I2C1->DR=(0x68<<1); //clearing SB and writing MPU address in "writing" mode
    while(!(I2C1->SR1 & I2C_SR1_ADDR)){}; //waiting for the address to be sent
    (void)I2C1->SR2; //clearing ADDR bit

    I2C1->DR=(0x6B); // addressing MPU internal power management register
    while(!(I2C1->SR1 & I2C_SR1_TXE)){}; //waiting for bye to be sent

    I2C1->DR=(0<<6)|(0<<5);              // clearing sleep mode bit
    while(!(I2C1->SR1 & I2C_SR1_BTF)){};
    I2C1->CR1 |=I2C_CR1_STOP;            //generating stop condition
    while((I2C1->CR1 & I2C_CR1_STOP ));

// **** second part ****
    I2C1->CR1 |=I2C_CR1_START;           //generating start condintion      
    while(!(I2C1->SR1 & I2C_SR1_SB));    //making sure the communication has started
    I2C1->DR=(0x68<<1); //sending address in "writing mode"
    while(!(I2C1->SR1 & I2C_SR1_ADDR)){}; //waiting for the address to be sent
    (void)I2C1->SR2;//clearing ADDR

    I2C1->DR=(0x71);//sending address of internal register
    while(!(I2C1->SR1 & I2C_SR1_BTF)){};  //waiting for the address to be sent

    I2C1->CR1 |=I2C_CR1_START;            //generating start condition to read data         
    while(!(I2C1->SR1 & I2C_SR1_SB));     //making sure the communication has started
    I2C1->DR=((0x68<<1)|(0x01));          //sending MPU address this time in "read" mode
    while(!(I2C1->SR1 & I2C_SR1_ADDR)){};

    I2C1->CR1 |=I2C_CR1_ACK;                //enabling ack bit      
    while(!(I2C1->SR1 & I2C_SR1_BTF)){};    //Waiting for MPU to send data of the requested register
    (void)I2C1->DR; //clearing BTF
    while((I2C1->SR1 & I2C_SR1_BTF)){}; 

The first part of the code is responsible for clearing register 0x6B in order to wake MPU up. The second part reads the requested register information. And here is what I get from the communication.

enter image description here

  • \$\begingroup\$ There is obviously something wrong with your write procedure at the beginning as your analyzer fails to decode the protocol. \$\endgroup\$ – Arsenal Sep 18 at 11:56
  • \$\begingroup\$ Hi @Arsenal. thanks for your reply. The logic analyzer decodes the protocol fine. If I zoom in further It shows writing sequence. How ever I suspect writing zero in 0x6B does not wake MPU up. I dont know what is going wrong here. \$\endgroup\$ – Ahmadreza.2ahm Sep 18 at 12:16
  • \$\begingroup\$ As I see it, the hardware does exactly what the code tells it to do - transfer 3 bytes without sending a NAK and stop. How many bytes are you trying to read? Again, like in your previous question, if you choose not to do the sequence exactly like the reference manual says how to do it, then it is just not going to work. \$\endgroup\$ – Justme Sep 18 at 17:11
  • \$\begingroup\$ Hi @Justme. thanks for your reply and kindness. That's my point. I never asked the sequence to stop so I think it should keep sending bytes. Otherwise, I've never asked for three! And beside that, what bothers me the most is that the MPU does not wake up. I think It never receive zeroe for bit6. Is there something wrong with my "Sending part"? \$\endgroup\$ – Ahmadreza.2ahm Sep 19 at 8:59
  • \$\begingroup\$ No the MCU won't transfer more when receive buffers are already full. This means if you read one byte out of data register, the peripheral will transfer three bytes in total, unless told otherwise. A proper sequence, explained in the reference manual, will transfer one byte if you want only one byte. \$\endgroup\$ – Justme Sep 19 at 9:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.