历史上的今天
返回首页

历史上的今天

今天是: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();

  }

}


测试结果:

推荐阅读

史海拾趣

Altitude Technology公司的发展小趣事

在电子行业中,合作与共赢是企业发展的重要途径。Altitude Technology深知这一点,因此积极寻求与其他企业的合作机会。通过与一家知名芯片制造商建立战略合作关系,Altitude Technology获得了更先进的芯片供应和技术支持,进一步提升了产品的竞争力。同时,公司还与其他企业开展了一系列合作项目,共同推动电子行业的发展。

Greatbatch-Sierra Inc公司的发展小趣事

随着公司的不断发展,Altitude Technology逐渐在电子行业中崭露头角。然而,市场竞争也日趋激烈,为了保持领先地位,公司决定加大研发投入,致力于技术突破。经过长时间的研发,Altitude Technology成功推出了一款采用最新芯片技术的智能手机,这款手机在性能、功耗和拍照效果等方面均达到了行业领先水平,为公司赢得了更多的市场份额。

AAC [American Accurate Components]公司的发展小趣事

AAC公司的创立可以追溯到上世纪90年代初,当时电子音响器件市场正迎来快速发展的机遇。AAC公司敏锐地捕捉到了这一市场趋势,迅速行动,与德国投资者共同成立了中德合资常州威利来电子音响器件有限公司。这一合资举措为AAC带来了先进的生产技术和管理经验,使其生产的讯响器和微型扬声器迅速打开了德国市场的大门。这一成功的合资经验为AAC后续的发展奠定了坚实的基础。

台湾富晶(FORTUNE)公司的发展小趣事
对于老化或损坏的元件进行更换,确保触发器的正常工作。
B&F Fastener Supply公司的发展小趣事

B&F Fastener Supply公司在上世纪末成立之初,就瞄准了快速发展的电子行业,意识到紧固件和电子元器件的供应将成为行业发展的关键。公司迅速调整战略,开始专注于电子工业用紧固件的研发和销售。通过与多家电子制造厂商建立合作关系,B&F逐渐在电子紧固件市场占据了一席之地。

Avasem公司的发展小趣事

Avasem公司深知人才是企业发展的核心驱动力。因此,公司一直致力于构建良好的人才培养机制和企业文化。Avasem公司注重员工的个人成长和职业发展,提供丰富的培训和学习机会,鼓励员工不断学习和创新。同时,公司还倡导开放、包容和协作的企业文化,为员工创造一个积极、健康的工作环境。这种以人为本的管理理念不仅吸引了大量优秀人才加入公司,还激发了员工的创新精神和团队凝聚力,为公司的持续发展提供了有力保障。

问答坊 | AI 解惑

老板一定要买正版EDA软件,有没有价廉物美的?

一直用altium designer,之前也用过ORCAD一段时间,仿真一般用PROTEUS。现在老板要买正版的,联系了ALTIUM报价太贵,有没有别的推荐?…

查看全部问答>

用VHDL实现正弦波

用定制ROM的方法完成正弦波设计···…

查看全部问答>

Linux LCD驱动:LCD右屏颜色不对,左屏颜色正常(android)。

在做基于omap3430的android开发是,lcd驱动遇到如下问题:LCD可以正常显示,但是右边屏幕有些地方颜色泛蓝,请问调过LCD的专家帮忙。…

查看全部问答>

《EVC高级编程及其应用开发》中第八章就一个例子,利用ADO访问ACCESS的一个问题

  为什么程序的CreataConnection()时就该语句hr= CLSIDFromProgID( g_szADOCE31ConnProgID, &tClsid );就无法正确执行。 在程序中只量把ADOCE30.h换成了ADOCE31.h。另外程序中所有的ADOCE30也全换成了ADOCE31。 急!!参与有分啊~~~~ ...…

查看全部问答>

USB FOR KITL 到底要如何使用

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++ 手机关机处理事件

mobile c++  手机关机处理事件 我想在手机关机时响应到一个事件,然后在这个事件中做一些其他处理.但现在无法得到手机关机事件. 比如:1:启动软件, 2;长按power键,3:响应到软件中的代码 4:在该代码中做其他处理. 问题:如何实现第三步?当 ...…

查看全部问答>

串口不能烧程序

前段时间在淘宝买了块STM32的板子,我收到发现串口不能烧程序,寄回卖家说用JTAG,把什么“保护”给弄了下,当时我也没具体问卖家怎么回事。这是不是说明STM32是已经用过的芯片,要不然新的片子怎么会串口都不能烧写呢? 不知道是不是?…

查看全部问答>

请教:430单片机的速度?

我使用8M晶振,读取串行flash -AT45DB081,但是速度还是达不到我的要求(用c语言写的),想超频,不知道430能超到多少,稳定吗? 各位dx有没有什么解决速度的经验。…

查看全部问答>

关于DSP上电引导的提问

最近看了两个TI的文档呢。DSP281x_HeaderFiles_QuickStart_Readme和spru095a_TMS320F28x Boot ROM Reference Guide (Rev. A)这两个文档。了解了一下 DSP有了复位信号后,会跳到0x3FFFC0这个地址上去,假设现在是BOOT-ROM映射到0x3FF000这个地址上面 ...…

查看全部问答>