MPU6050 obteniendo datos incorrectos en stm32 f103

2

Estoy tratando de enviar datos desde el giro en MPU6050 a la computadora a través de UART, pero por razones desconocidas para mí, estoy obteniendo valores dos veces más grandes que el valor máximo de un número entero (4294967247). He comprobado el cableado y estoy seguro de que está funcionando bien.

Estoy usando el SMT32F103C8:

MPU: VCC - > STM32: 3v3

MPU: GND- > STM32: GND

MPU: SCL - > STM32: PB6

MPU: SDA - > STM32: PB7

MPU: ADO - > STM32: GND

MPU: INT - > STM32: PB4

Sé que I2C funciona bien porque puedo escribir y leer desde los registros internos, como el registro de espera, puedo configurarlo en 1 y leer 1 o configurarlo en 0 y leer 0.

Estos son algunos datos que registré cuando los muevo a mano:

        Gyro X: 169
        Gyro Y: 4294967177
        Gyro Z: 4294967104

        Gyro X: 61
        Gyro Y: 4294967194
        Gyro Z: 4294967079

        Gyro X: 221
        Gyro Y: 4294967243
        Gyro Z: 4294967114

        Gyro X: 247
        Gyro Y: 4294967226
        Gyro Z: 4294967100

        Gyro X: 245
        Gyro Y: 4294967224
        Gyro Z: 4294967104

        Gyro X: 255
        Gyro Y: 4294967219
        Gyro Z: 4294967091

        Gyro X: 220
        Gyro Y: 4294967234
        Gyro Z: 4294967081

        Gyro X: 302
        Gyro Y: 4294967247
        Gyro Z: 4294967100

        Gyro X: 4294961910
        Gyro Y: 11540
        Gyro Z: 3815

        Gyro X: 4294961799
        Gyro Y: 4294952795
        Gyro Z: 4294962484

        Gyro X: 1215
        Gyro Y: 11904
        Gyro Z: 845

        Gyro X: 4294960722
        Gyro Y: 2173
        Gyro Z: 9881

        Gyro X: 118
        Gyro Y: 4294949006
        Gyro Z: 4294959017

        Gyro X: 237
        Gyro Y: 226
        Gyro Z: 4294967131

        Gyro X: 4,294,964,816
        Gyro Y: 4294955893
        Gyro Z: 4294964117

        Gyro X: 756
        Gyro Y: 4294966889
        Gyro Z: 394

        Gyro X: 544
        Gyro Y: 4294967064
        Gyro Z: 4294966905

        Gyro X: 4294963519
        Gyro Y: 3233
        Gyro Z: 6166

        Gyro X: 2485
        Gyro Y: 4294962643
        Gyro Z: 4294960238

Estructura del resultado:

        typedef struct {
            int16_t Gyroscope_X;     /*!< Gyroscope value X axis */
            int16_t Gyroscope_Y;     /*!< Gyroscope value Y axis */
            int16_t Gyroscope_Z;     /*!< Gyroscope value Z axis */

            float Temperature;       /*!< Temperature in degrees */
        } MPU6050_GYROResult;

La función importante:

            HAL_StatusTypeDef MPU::GetRawGyro(MPU6050_GYROResult *result)
            {
                uint8_t I2C2_Buffer_Rx[6];

                /*Read the 6  gyro registers from the device*/
                HAL_StatusTypeDef statResult = this->I2C_BufferRead(MPU6050_DEFAULT_ADDRESS, I2C2_Buffer_Rx , MPU6050_RA_GYRO_XOUT_H, 6);

                result->Gyroscope_X = (((int16_t)I2C2_Buffer_Rx[0]) << 8) | I2C2_Buffer_Rx[1];
                result->Gyroscope_Y = (((int16_t)I2C2_Buffer_Rx[2]) << 8) | I2C2_Buffer_Rx[3];
                result->Gyroscope_Z = (((int16_t)I2C2_Buffer_Rx[4]) << 8) | I2C2_Buffer_Rx[5];
                return statResult;
            }

principal de CÓDIGO:

        static void MPU6050_Init(void)
        {
            mpu = new Core::MPU();

            if(mpu->Initialize() != HAL_OK)
            {
                _Error_Handler(__FILE__, __LINE__);
                return;
            }

            mpu->EnableAllFIFOBit();
        }


        /*
         .............. 
         * stm32 initialize code (default)
         */
        int main()
        {
            MPU6050_Init(); //init 
            while (1)
            {
                Core::MPU6050_GYROResult GyroData;

                mpu->GetRawGyro(&GyroData);


                printf("Gyro X: ");
                printf("%u\n", GyroData.Gyroscope_X);
                printf("\n\r");

                printf("Gyro Y: ");
                printf("%u\n", GyroData.Gyroscope_Y);
                printf("\n\r");

                printf("Gyro Z: ");
                printf("%u\n", GyroData.Gyroscope_Z);
                printf("\n\r");
                printf("\n\r");

                HAL_Delay(1060);    
                /* USER CODE END WHILE */
            }

        }

Código de inicio I2C

            HAL_StatusTypeDef MPU::I2C_init()
            {   
                //Enable the clock for gpioc
                __HAL_RCC_GPIOB_CLK_ENABLE();
                //Enable clock for I2C1 
                __HAL_RCC_I2C1_CLK_ENABLE();

                GPIO_InitTypeDef GPIO_InitStruct;

                /*Configure GPIO pins : MPU_I2C1_SCL_Pin MPU_I2C1_SDA_Pin */
                GPIO_InitStruct.Pin = MPU_I2C1_SCL_Pin | MPU_I2C1_SDA_Pin;
                GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
                GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
                HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);


                this->i2c1.Instance = I2C1;
                this->i2c1.Mode = HAL_I2C_MODE_MASTER;
                this->i2c1.Init.ClockSpeed = MPU6050_I2C_Speed;
                this->i2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
                this->i2c1.Init.OwnAddress1 = MPU6050_DEFAULT_ADDRESS;
                this->i2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
                this->i2c1.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
                this->i2c1.Init.OwnAddress2 = 0;
                this->i2c1.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
                this->i2c1.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;

                HAL_StatusTypeDef result = HAL_I2C_Init(&this->i2c1);

                if (result != HAL_OK)
                {
                    this->ModuleErrorHandle();
                }   
                return result;
            }

Código de inicialización:

            HAL_StatusTypeDef MPU::Initialize()
            {
                HAL_StatusTypeDef result = this->I2C_init();
                if(result == HAL_OK)
                {
                    result = this->SetClockSource(MPU6050_CLOCK_PLL_XGYRO); /* Set clock source as x gyro */
                        if(result == HAL_OK)
                        {
                            result = this->SetFullScaleAccelRange(MPU6050_GYRO_FS_250); 
                            if(result == HAL_OK)
                            {   
                                result = this->SetFullScaleGyroRange(MPU6050_ACCEL_FS_2);
                                if(result == HAL_OK)
                                {
                                    result = this->SetSleepModeStatus(Sys_Disable); /*Take chip off sleepmode*/
                                    this->isInitialized = (result == HAL_OK); /*Chip is initialized */

                                    return result; //return our result
                                }
                            }
                        }
                }

                return result;
            }

Establecer código fuente del reloj:

            HAL_StatusTypeDef MPU::SetClockSource(uint8_t source)
            {
                return this->WriteBits(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_CLKSEL_BIT, MPU6050_PWR1_CLKSEL_LENGTH, source);
            }

Código SetFullScaleAccelRange:

            HAL_StatusTypeDef MPU::SetFullScaleAccelRange(uint8_t range)
            {
                return this->WriteBits(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_ACCEL_CONFIG, MPU6050_ACONFIG_AFS_SEL_BIT, MPU6050_ACONFIG_AFS_SEL_LENGTH, range);
            }

Código SetFullScaleGyroRange:

            HAL_StatusTypeDef MPU::SetFullScaleGyroRange(uint8_t range)
            {
                return this->WriteBits(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_GYRO_CONFIG, MPU6050_GCONFIG_FS_SEL_BIT, MPU6050_GCONFIG_FS_SEL_LENGTH, range);
            }

Código SetSleepModeStatus:

            HAL_StatusTypeDef MPU::SetSleepModeStatus(Sys_StatusTypeDef State)
            {
                return this->WriteBit(MPU6050_DEFAULT_ADDRESS, MPU6050_RA_PWR_MGMT_1, MPU6050_PWR1_SLEEP_BIT, State);
            }

Código WriteBits:

            HAL_StatusTypeDef MPU::WriteBit(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitNum, uint8_t data)
            {
                uint8_t tmp;
                HAL_StatusTypeDef result = this->I2C_BufferRead(slaveAddr, &tmp, regAddr, 1);

                if(result != HAL_OK)
                    return result;

                tmp = (data != 0) ? (tmp | (1 << bitNum)) : (tmp & ~(1 << bitNum));

                return this->I2C_ByteWrite(slaveAddr, &tmp, regAddr);
            }

Código de ReadBits:

            HAL_StatusTypeDef MPU::ReadBits(uint8_t slaveAddr, uint8_t regAddr, uint8_t bitStart, uint8_t length, uint8_t *data)
            {
                //I2C_BufferRead(uint8_t slaveAddr, uint8_t* pBuffer, uint8_t readAddr, uint16_t NumByteToRead)
                uint8_t tmp;

                HAL_StatusTypeDef result = this->I2C_BufferRead(slaveAddr, &tmp, regAddr, 1);

                if(result != HAL_OK)
                    return result;

                uint8_t mask = ((1 << length) - 1) << (bitStart - length + 1);
                tmp &= mask;
                tmp >>= (bitStart - length + 1);
                *data = tmp;

                return result;
            }

Código I2C_ByteWrite:

            HAL_StatusTypeDef MPU::I2C_ByteWrite(uint8_t slaveAddr, uint8_t* pBuffer, uint8_t writeAddr)
            {   
                /*Write data to MPU6050's internal memory*/
                return HAL_I2C_Mem_Write(&this->i2c1, (uint16_t)slaveAddr, (uint16_t)writeAddr, I2C_MEMADD_SIZE_8BIT, pBuffer, 1, MPU6050_I2C_TIMEOUTLEN);
            }

Código I2C_ByteRead:

            HAL_StatusTypeDef MPU::I2C_BufferRead(uint8_t slaveAddr, uint8_t* pBuffer, uint8_t readAddr, uint16_t NumByteToRead)
            {
                /*Read data from MPU6050's internal memory*/
                return HAL_I2C_Mem_Read(&this->i2c1, (uint16_t)slaveAddr, (uint16_t)readAddr, I2C_MEMADD_SIZE_8BIT, pBuffer, NumByteToRead, MPU6050_I2C_TIMEOUTLEN);
            }
    
pregunta kelvinmac

1 respuesta

4

Usted usa int16_t como campos en su estructura, pero imprime %u . Eso es incorrecto: %u debería ser de 32 bits en su plataforma, no 16.

    
respondido por el Marcus Müller

Lea otras preguntas en las etiquetas