历史上的今天
今天是:2024年10月29日(星期二)
2021年10月29日 | stm32专题二十七:MPU6050 驱动程序
2021-10-29 来源:eefocus
提供了一个简单的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();
}
}
测试结果:
史海拾趣
|
一直用altium designer,之前也用过ORCAD一段时间,仿真一般用PROTEUS。现在老板要买正版的,联系了ALTIUM报价太贵,有没有别的推荐?… 查看全部问答> |
|
Linux LCD驱动:LCD右屏颜色不对,左屏颜色正常(android)。 在做基于omap3430的android开发是,lcd驱动遇到如下问题:LCD可以正常显示,但是右边屏幕有些地方颜色泛蓝,请问调过LCD的专家帮忙。… 查看全部问答> |
|
《EVC高级编程及其应用开发》中第八章就一个例子,利用ADO访问ACCESS的一个问题 为什么程序的CreataConnection()时就该语句hr= CLSIDFromProgID( g_szADOCE31ConnProgID, &tClsid );就无法正确执行。 在程序中只量把ADOCE30.h换成了ADOCE31.h。另外程序中所有的ADOCE30也全换成了ADOCE31。 急!!参与有分啊~~~~ ...… 查看全部问答> |
|
http://blog.eeworld.net/gooogleman/archive/2009/04/03/4001784.aspx 按照上面KITL的教程指示,结果在DNW 上显示 USB serial wait for connecting . 此时点机 PB上的 attach device 则出现下列错误: (CoreCon) 16:19:5 ...… 查看全部问答> |
|
mobile c++ 手机关机处理事件 我想在手机关机时响应到一个事件,然后在这个事件中做一些其他处理.但现在无法得到手机关机事件. 比如:1:启动软件, 2;长按power键,3:响应到软件中的代码 4:在该代码中做其他处理. 问题:如何实现第三步?当 ...… 查看全部问答> |
|
我使用8M晶振,读取串行flash -AT45DB081,但是速度还是达不到我的要求(用c语言写的),想超频,不知道430能超到多少,稳定吗? 各位dx有没有什么解决速度的经验。… 查看全部问答> |
|
最近看了两个TI的文档呢。DSP281x_HeaderFiles_QuickStart_Readme和spru095a_TMS320F28x Boot ROM Reference Guide (Rev. A)这两个文档。了解了一下 DSP有了复位信号后,会跳到0x3FFFC0这个地址上去,假设现在是BOOT-ROM映射到0x3FF000这个地址上面 ...… 查看全部问答> |




