1

我正在使用带有 MPU6050 的 STM32F446,我正在为此应用程序使用 I2C 通信,问题是它只显示一个值并且不更新,我的意思是,如果串行监视器中的值是 1、1、1,那么它每次只显示一个,即使我断开 MPU 并将其连接到 STM32,它也不会显示另一个。我还尝试逐行调试以查找错误,但似乎程序卡在 MPU_Init 函数的第一个数据传输行中。

#include "main.h"
#include <stdio.h>
#include <math.h>

#define MPU_ADDRESS 0xD0

I2C_HandleTypeDef hi2c1 = {0};
UART_HandleTypeDef huart2 = {0};

void GPIO_Init(void);
void Error_Handler(void);
void Clock_Config(void);
void UART2_Init(void);
void I2C1_Init(void);
void MPU_Init(void);

int main(void)
{
uint8_t bufOut[32], bufIn[12], buflen;
HAL_Init();
Clock_Config();
GPIO_Init();
UART2_Init();
I2C1_Init();
MPU_Init();
while(1)
{
    bufOut[0] = 0x3B;
    HAL_I2C_Master_Transmit(&hi2c1, MPU_ADDRESS, bufOut, 1, HAL_MAX_DELAY);
    HAL_I2C_Master_Receive(&hi2c1, MPU_ADDRESS, bufIn, 12, HAL_MAX_DELAY);

    int16_t acc_x_raw = ((uint16_t)bufIn[0] << 8) | bufIn[1];
    int16_t acc_y_raw = ((uint16_t)bufIn[2] << 8) | bufIn[3];
    int16_t acc_z_raw = ((uint16_t)bufIn[4] << 8) | bufIn[5];

    buflen = sprintf((char *)bufOut, "Accel: %i %i %i\r\n", acc_x_raw, acc_y_raw, acc_z_raw);
    HAL_UART_Transmit(&huart2, bufOut, buflen, HAL_MAX_DELAY);
    HAL_Delay(100);
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
}
return 0;
}

void MPU_Init(void)
{
uint8_t buffer[2];

buffer[0] = 0x6B;
buffer[1] = 0x80;
HAL_I2C_Master_Transmit(&hi2c1, MPU_ADDRESS, buffer, 2, HAL_MAX_DELAY);
HAL_Delay(10);

buffer[0] = 0x6B;
buffer[1] = 0x00;
HAL_I2C_Master_Transmit(&hi2c1, MPU_ADDRESS, buffer, 2, HAL_MAX_DELAY);
HAL_Delay(10);

buffer[0] = 0x6B;
buffer[1] = 0x00;
HAL_I2C_Master_Transmit(&hi2c1, MPU_ADDRESS, buffer, 2, HAL_MAX_DELAY);
HAL_Delay(10);

buffer[0] = 0x6C;
buffer[1] = ~(0x3F);
HAL_I2C_Master_Transmit(&hi2c1, MPU_ADDRESS, buffer, 2, HAL_MAX_DELAY);
HAL_Delay(10);

buffer[0] = 0x1A;
buffer[1] = 0x00;
HAL_I2C_Master_Transmit(&hi2c1, MPU_ADDRESS, buffer, 2, HAL_MAX_DELAY);
HAL_Delay(10);

buffer[0] = 0x1B;
buffer[1] = 0x00;
HAL_I2C_Master_Transmit(&hi2c1, MPU_ADDRESS, buffer, 2, HAL_MAX_DELAY);
HAL_Delay(10);

buffer[0] = 0x1C;
buffer[1] = 0x00;
HAL_I2C_Master_Transmit(&hi2c1, MPU_ADDRESS, buffer, 2, HAL_MAX_DELAY);
HAL_Delay(10);
}

void UART2_Init(void)
{
/* Habilitar señales de reloj */
__HAL_RCC_USART2_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();

/* Configuración de bajo nivel */
GPIO_InitTypeDef uart_pins = {0};
uart_pins.Pin = GPIO_PIN_2;
uart_pins.Mode = GPIO_MODE_AF_PP;
uart_pins.Alternate = GPIO_AF7_USART2;
HAL_GPIO_Init(GPIOA, &uart_pins);

/* Habilitar interrupción */

/* Configuración de alto nivel */
huart2.Instance = USART2;
huart2.Init.BaudRate = 115200;
huart2.Init.Mode = UART_MODE_TX;
if (HAL_UART_Init(&huart2) != HAL_OK)
    Error_Handler();
}

void I2C1_Init(void)
{
/* Habilitar el reloj del periférico */
__HAL_RCC_I2C1_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();

/* Configuración de Bajo nivel */
GPIO_InitTypeDef i2c_pins = {0};
i2c_pins.Pin = GPIO_PIN_6 | GPIO_PIN_7;
i2c_pins.Mode = GPIO_MODE_AF_PP;
i2c_pins.Alternate = GPIO_AF4_I2C1;
HAL_GPIO_Init(GPIOB, &i2c_pins);

/* Habilitar Interrupciones */

/* Configuración de alto nivel */
hi2c1.Instance = I2C1;
hi2c1.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
hi2c1.Init.ClockSpeed = 100000;
//hi2c1.Init.DutyCycle = I2C_DUTYCYCLE_2;
if (HAL_I2C_Init(&hi2c1) != HAL_OK)
    Error_Handler();
}

void Clock_Config(void)
{
RCC_OscInitTypeDef osc_init = {0};
osc_init.OscillatorType = RCC_OSCILLATORTYPE_HSE;
osc_init.HSEState = RCC_HSE_BYPASS;
osc_init.PLL.PLLState = RCC_PLL_ON;
osc_init.PLL.PLLSource = RCC_PLLSOURCE_HSE;
osc_init.PLL.PLLM = 4;
osc_init.PLL.PLLN = 180;
osc_init.PLL.PLLP = RCC_PLLP_DIV2;
osc_init.PLL.PLLQ = 2;
osc_init.PLL.PLLR = 2;

if (HAL_RCC_OscConfig(&osc_init) != HAL_OK)
    Error_Handler();

RCC_ClkInitTypeDef clock_init = {0};
clock_init.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
clock_init.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK |
        RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
clock_init.AHBCLKDivider = RCC_SYSCLK_DIV1;
clock_init.APB1CLKDivider = RCC_HCLK_DIV4;
clock_init.APB2CLKDivider = RCC_HCLK_DIV2;

if (HAL_RCC_ClockConfig(&clock_init, FLASH_LATENCY_4) != HAL_OK)
    Error_Handler();
}

void Error_Handler(void)
{
while(1)
{
    HAL_GPIO_TogglePin(GPIOA, GPIO_PIN_5);
    HAL_Delay(100);
}
}

void GPIO_Init(void)
{
__HAL_RCC_GPIOA_CLK_ENABLE();

GPIO_InitTypeDef led_pin = {0};
led_pin.Pin = GPIO_PIN_5;
led_pin.Mode = GPIO_MODE_OUTPUT_PP;
HAL_GPIO_Init(GPIOA, &led_pin);
}

void SysTick_Handler(void)
{
HAL_IncTick();
HAL_SYSTICK_IRQHandler();
}
4

1 回答 1

0

您是否将 MPU6050 配置为连续测量模式?传感器可能工作在单 ADC 转换模式。这不会更新数据寄存器。另一件事是您为什么要使用HAL_MAX_DELAYI2C 超时值?该值会阻塞 CPU,直到超时值通过。

于 2021-10-03T17:37:32.070 回答