提供了一个简单的mpu6050的驱动:
mpu6050.h
#ifndef __MPU6050_H
#define __MPU6050_H
#include "stdint.h"
#include "i2c.h"
#include "usart.h"
#include "stm32f1xx_hal.h"
/* MPU6050 */
#define DELAY_MS 10 // 初始化延时
#define DEVICE_ADDR (0XD0) // 8位设备地址
#define PWR_MGMT_1 (0X6B) // 电源管理1
#define MPU6050_RA_RATE_DIV (0X19) // 采样频率分频器
#define MPU6050_RA_CONFIG (0X1A) // 低通滤波器
#define MPU6050_RA_ACCEL_CONFIG (0X1C) // 加速度计量程设置
#define MPU6050_RA_GYRO_CONFIG (0X1B) // 陀螺仪量程设置
#define MPU6050_RA_WHO_AM_I (0X75) // 设备标识
#define MPU6050_GYRO_OUT (0x43) // 陀螺仪数据寄存器地址
#define MPU6050_ACC_OUT (0x3B) // 加速度数据寄存器地址
#define MPU6050_RA_TEMP_OUT_H (0x41) // 温度寄存器 高地址
#define MPU6050_RA_TEMP_OUT_L (0x42) // 温度寄存器 低地址
typedef enum
{
Bit_Reset = 0,
Bit_Set
} BIT_Typedef;
void MPU6050_Init(void);
void MPU6050_ReadID(void);
void MPU6050_ReadAcc(int16_t *accData);
void MPU6050_ReadGyro(int16_t *gyroData);
#endif /* __MPU6050_H */
mpu6050.c
#include "mpu6050.h"
/**
* @brief 写数据到MPU6050寄存器
* @param reg_addr 待写入的寄存器地址
* @param data 待写入的数据
*/
static void MPU6050_WriteRegData(uint8_t reg_addr, uint8_t data)
{
HAL_I2C_Mem_Write(&hi2c1, DEVICE_ADDR, reg_addr, I2C_MEMADD_SIZE_8BIT, &data, 1, 0xFFFF);
}
/**
* @brief 从指定寄存器读取数据
* @param reg_addr 待读取的寄存器地址
* @param data 数据指针
* @param num 待读取的字节数
*/
static void MPU6050_ReadRegData(uint8_t reg_addr, uint8_t *data, uint8_t num)
{
HAL_I2C_Mem_Read(&hi2c1, DEVICE_ADDR, reg_addr, I2C_MEMADD_SIZE_8BIT, data, num, 0XFFFF);
}
/**
* @brief MPU6050初始化
*/
void MPU6050_Init(void)
{
HAL_Delay(DELAY_MS);
/* 解除休眠 */
MPU6050_WriteRegData(PWR_MGMT_1, 0X00);
/* 陀螺仪采样率 = 1kHz / (1 + 采样率分频) = 100Hz */
MPU6050_WriteRegData(MPU6050_RA_RATE_DIV, 0x09);
/* 采样频率fs = 100Hz,带宽 = fs/2 = 50Hz */
MPU6050_WriteRegData(MPU6050_RA_CONFIG, 0X03);
/* 配置加速度计量程范围(最小计量范围):±2g */
MPU6050_WriteRegData(MPU6050_RA_ACCEL_CONFIG, 0x00);
/* 配置陀螺仪量程范围(最小计量范围):±250°/s */
MPU6050_WriteRegData(MPU6050_RA_GYRO_CONFIG, 0X00);
}
/**
* @brief 读取MPU6050的设备ID
*/
void MPU6050_ReadID(void)
{
uint8_t device_id = 0;
MPU6050_ReadRegData(MPU6050_RA_WHO_AM_I, &device_id, 1);
if (device_id == 0X68)
{
printf("设备ID读取成功 -- ID = %#Xn", device_id);
}
else
{
printf("设备ID读取失败n");
}
}
/**
* @brief 读取加速度值
* @param accData 加速度数组指针
*/
void MPU6050_ReadAcc(int16_t *accData)
{
uint8_t buf[6] = {0};
/* 连续读取6个寄存器值,高位在前 */
MPU6050_ReadRegData(MPU6050_ACC_OUT, buf, 6);
/* 数据保存到传入的数组指针 */
accData[0] = (buf[0] << 8) | buf[1];
accData[1] = (buf[2] << 8) | buf[3];
accData[2] = (buf[4] << 8) | buf[5];
}
/**
* @brief 读取陀螺仪值
* @param accData 加速度数组指针
*/
void MPU6050_ReadGyro(int16_t *gyroData)
{
uint8_t buf[6] = {0};
/* 连续读取6个寄存器值,高位在前 */
MPU6050_ReadRegData(MPU6050_GYRO_OUT, buf, 6);
/* 数据保存到传入的数组指针 */
gyroData[0] = (buf[0] << 8) | buf[1];
gyroData[1] = (buf[2] << 8) | buf[3];
gyroData[2] = (buf[4] << 8) | buf[5];
}
测试程序 main.c
#include "main.h"
#include "dma.h"
#include "i2c.h"
#include "usart.h"
#include "gpio.h"
#include "mpu6050.h"
void SystemClock_Config(void);
int main(void)
{
HAL_Init();
int16_t accData[3] = {0};
int16_t gyroData[3] = {0};
SystemClock_Config();
MX_GPIO_Init();
MX_DMA_Init();
MX_I2C1_Init();
MX_USART1_UART_Init();
MX_USART2_UART_Init();
MPU6050_Init();
while (1)
{
MPU6050_ReadAcc(accData);
MPU6050_ReadGyro(gyroData);
printf("加速度%8d%8d%8dt", accData[0], accData[1], accData[2]);
printf("陀螺仪%8d%8d%8dtn", gyroData[0], gyroData[1], gyroData[2]);
HAL_Delay(500);
}
}
/**
* @brief System Clock Configuration
* @retval None
*/
void SystemClock_Config(void)
{
RCC_OscInitTypeDef RCC_OscInitStruct = {0};
RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
RCC_OscInitStruct.HSEState = RCC_HSE_ON;
RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
RCC_OscInitStruct.HSIState = RCC_HSI_ON;
RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
{
Error_Handler();
}
RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
|RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
{
Error_Handler();
}
}
测试结果:
上一篇:stm32专题二十七:MPU6050介绍
下一篇:stm32专题二十八:读写内部Flash
推荐阅读最新更新时间:2024-11-05 17:34
设计资源 培训 开发板 精华推荐
- 使用 Analog Devices 的 LTC1660IN 的参考设计
- L4995K 5V、500mA低压降稳压器典型应用电路
- LTC1440,微功率 LDO 稳压器消耗 <5mA
- CN3300升压锂电充电模块
- LTC2195CUKG、16 位、125Msps 低功耗双通道 ADC 的典型应用
- CYUSBS236DVK,USB 串行开发套件
- LT3973HMSE-3.3 2.5V 降压转换器的典型应用
- DC2073B-J,基于 LTC6908-1 SOT23 硅振荡器的演示板
- LT6656AIDC-3、3V 扩展电源范围电压基准的典型应用
- AD9642-210EBZ,使用 AD9642BCPZ-210 的评估板,14 位,210 MSPS 模数转换器,用于设置和控制的 SPI 接口 外部