STM32硬件接口I2C应用(基于MP6050)

目录

概述

1 STM32Cube控制配置I2C

1.1 I2C参数配置

1.2 使用STM32Cube产生工程

2 HAL库函数介绍

2.1 初始化函数

2.2 写数据函数

 2.3 读数据函数

3  认识MP6050 

3.1 MP6050功能介绍

3.2 加速计测量寄存器

​编辑3.3 温度计量寄存器

3.4 陀螺仪测量寄存器

4 MP6050驱动程序实现

4.1 驱动函数实现

4.2 完整驱动代码

5 测试

6 逻辑分析仪捕捉波形


概述

本文主要介绍STM32F4的内部I2C接口的使用方法,包括使用STM32Cube配置i2c接口函数,还介绍了STM32 HAL库中的接口函数,为了验证接口函数的是否能够正常工作,还使用mp6050
作为device,以I2C接口作为通信接口,以实现该芯片数据的读写操作。

1 STM32Cube控制配置I2C

STM32CubeMX 版本: 6.11

HAL库版本: STM32Cube_FW_F4_V1.27.1

1.1 I2C参数配置

STM32F407 的标准I2C接口最大支持100K工作频率,笔者选择最大工作频100k,以配置I2C的参数。

I2C使用的GPIO接口如下:

使用MCU类型和HAL库的版本

1.2 使用STM32Cube产生工程

 在配置完成项目后,点击GENERATE生成项目,打开项目后项目目录如下,和I2C相关的代码如下:

代码第40行:选择I2C2作为硬件接口

代码第41行:I2C通信速率为100K

代码第44行:定义地址位7bit

2 HAL库函数介绍

STM32 HAL库函数数量很多,本文仅介绍笔者使用的一些函数接口。其他函数在使用的时候在具体研究,而不许把每个函数搞清楚才去应用。

2.1 初始化函数

函数原型:

HAL_StatusTypeDef HAL_I2C_Init(I2C_HandleTypeDef *hi2c);

参数介绍

hi2c:  指向I2C_HandleTypeDef结构体的指针,该结构体包含指定I2C的配置信息。

 一个使用案例: 如果已经初始化完成hi2c结构,初始化时,直接调用该结构体即可。

2.2 写数据函数

函数原型:

HAL_StatusTypeDef HAL_I2C_Mem_Write(   I2C_HandleTypeDef *hi2c, 
                                       uint16_t DevAddress, 
                                       uint16_t MemAddress, 
                                       uint16_t MemAddSize, 
                                       uint8_t *pData, 
                                       uint16_t Size, uint32_t Timeout)

参数介绍:

hi2c:  指向I2C_HandleTypeDef结构体的指针,该结构体包含指定I2C的配置信息。

DevAddress: 目标设备地址:设备的7位地址值在调用接口之前,必须将数据表向左移动

MemAddress:内存地址

MemAddSize:内存地址大小

pData:            写数据指针

Size:               写数据大小

Timeout:         写数据超时时间

 2.3 读数据函数

函数原型:

HAL_StatusTypeDef HAL_I2C_Mem_Read( I2C_HandleTypeDef *hi2c, 
                                    uint16_t DevAddress, 
                                    uint16_t MemAddress, 
                                    uint16_t MemAddSize, 
                                    uint8_t *pData, 
                                    uint16_t Size, 
                                    uint32_t Timeout)

参数介绍:

hi2c:  指向I2C_HandleTypeDef结构体的指针,该结构体包含指定I2C的配置信息。

DevAddress: 目标设备地址:设备的7位地址值在调用接口之前,必须将数据表向左移动

MemAddress:内存地址

MemAddSize:内存地址大小

pData:            读数据指针

Size:               读数据大小

Timeout:         读数据超时时间

3  认识MP6050 

3.1 MP6050功能介绍

™ MPU-6000™ 和MPU-6050™, 统称为MPU-60X0™ 或MPU™.MPU设备提供了世界上第一个集成的6轴运动处理器解决方案,消除了与离散解决方案相关的封装级陀螺仪和加速度计交叉轴未对准。这个该设备将同一硅芯片上的3轴陀螺仪和3轴加速度计与车载数字运动处理器™ (DMP)™) 温度单元:能够处理复杂的9轴传感器融合算法使用经过现场验证的专有MotionFusion™ 发动机MPU-6000和MPU-6050的集成9轴MotionFusion算法可访问外部磁力计或通过辅助主I2C总线的其他传感器,允许设备收集全套传感器数据而不需要系统处理器的干预。这些设备采用相同的4x4x0.9 mm QFN与当前MPU-3000一样的占地面积和引脚™ 集成3轴陀螺仪家族,提供了一个简单的升级路径并便于在已经空间受限的电路板上放置。

对于快速和慢速运动的精确跟踪,MPU-60X0具有用户可编程功能陀螺仪满刻度范围为±250、±500、±1000和±2000°/秒(dps)。这些零件还具有用户可编程的加速度计满量程范围,分别为±2g、±4g、±8g和±16g。MPU-6000系列由两部分组成,即MPU-6000和MPU-6050。这些部件与我会处理好的。

MPU-6050支持高达400kHz的I2C通信,并具有定义其接口电压电平的VLOGIC引脚;MPU-6000还支持高达20MHz的SPI到I2C,并且具有单个电源引脚VDD,VDD既是设备的逻辑参考电源,也是模拟电源供应零件。有关MPU-60X0设备的更多详细信息,请参阅“MPU-6000和MPU-6050产品规范”。

3.2 加速计测量寄存器

寄存器59至64–加速计测量:ACCEL_XOUT_H、ACCEL_QUEUT_L、ACCE_YOUT_H,ACCEL_YOUT_L,ACCE_ZOUT_H和ACCEL_ZOUT_L

这些寄存器存储最新的加速度计测量值。加速度计测量值以中定义的采样率写入这些寄存器寄存器25。加速度计测量寄存器与温度测量寄存器一起,陀螺仪测量寄存器和外部传感器数据寄存器由两组寄存器:内部寄存器集和面向用户的读取寄存器集。加速度计传感器内部寄存器组中的数据总是在采样时更新速度同时,面向用户的读取寄存器集复制内部寄存器集的数据值每当串行接口空闲时。这保证了传感器寄存器的突发读取来自相同采样时刻的测量。请注意,如果不使用突发读取,则用户负责确保一组单字节读取对应于单个采样瞬间检查数据就绪中断。每个16位加速度计测量都具有在ACCEL_FS(寄存器28)中定义的满刻度。对于每个满刻度设置,加速度计ACCEL_xOUT中每个LSB的灵敏度如表所示在下面:


3.3 温度计量寄存器

寄存器65 and 66: TEMP_OUT_H and TEMP_OUT_L

 这些寄存器存储最新的温度传感器测量值。温度测量值以寄存器中定义的采样率写入这些寄存器
25.这些温度测量寄存器与加速度计测量寄存器一起,陀螺仪测量寄存器和外部传感器数据寄存器由两组寄存器:内部寄存器集和面向用户的读取寄存器集。温度传感器内部寄存器组中的数据始终以采样率进行更新。同时,面向用户的读取寄存器集复制内部寄存器集的数据值每当串行接口空闲时。这保证了传感器寄存器的突发读取来自相同采样时刻的测量。请注意,如果不使用突发读取,则用户负责确保一组单字节读取对应于单个采样瞬间检查数据就绪中断。温度传感器的比例因子和偏移可在电气规格表中找到。

3.4 陀螺仪测量寄存器

寄存器67至72——陀螺仪测量:GYRO_XOUT_H、GYRO_XOUT_L、GYRO_YOUT_H,GYRO_YOUT_L,GYRO_ZOUT_H和GYRO_ ZOUT_L

这些寄存器存储最新的陀螺仪测量值。陀螺仪测量值以寄存器中定义的采样率写入这些寄存器
25.这些陀螺仪测量寄存器与加速度计测量寄存器一起,温度测量寄存器和外部传感器数据寄存器由两组寄存器:内部寄存器集和面向用户的读取寄存器集。陀螺仪传感器内部寄存器组中的数据始终以采样率进行更新。同时,面向用户的读取寄存器集复制内部寄存器集的数据值每当串行接口空闲时。这保证了传感器寄存器的突发读取来自相同采样时刻的测量。请注意,如果不使用突发读取,则用户负责确保一组单字节读取对应于单个采样瞬间检查数据就绪中断。每个16位陀螺仪测量都具有FS_SEL(寄存器27)中定义的满刻度。对于每满刻度设置,GYRO_xOUT中每个LSB的陀螺仪灵敏度如下表所示:

4 MP6050驱动程序实现

4.1 驱动函数实现

1)写寄存器函数

代码第25行: 调用HAL_I2C_Mem_Write实现写寄存器功能

2)读寄存器函数

代码第37行: 调用HAL_I2C_Mem_Read实现读寄存器功能

4.2 完整驱动代码

1)创建mp6050.c文件,编写如下代码

/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name            : mpu6050.c
* Description          : I2C drive based on STM32F4
* STM32 HAL library ver: STM32Cube_FW_F4_V1.27.1
* 
******************************************************************************
* @attention
*
* Copyright (c) 2024~2029 mingfei.tang
* All rights reserved.
*
*************************************************************************
*/
/* USER CODE END Header */
#include "mpu6050.h"

MPU6050_T g_tMPU6050;

static uint8_t mpu6050_WeReg( uint16_t regAdd, uint8_t *pData, uint16_t Size )
{
    HAL_StatusTypeDef status;
    
    status = HAL_I2C_Mem_Write( &hi2c2, MPU6050_SLAVE_ADDRESS, regAdd, 
                                I2C_MEMADD_SIZE_8BIT, pData, Size, 1000);
    if( status == HAL_OK)
        return MPU6050_OK;
    else
        return MPU6050_ERROR; 
}

static uint8_t mpu6050_RdReg( uint16_t regAdd, uint8_t *pData, uint16_t Size )
{
    HAL_StatusTypeDef status;
    
    status = HAL_I2C_Mem_Read( &hi2c2, MPU6050_SLAVE_ADDRESS, regAdd, 
                               I2C_MEMADD_SIZE_8BIT, pData, Size, 1000);
    if( status == HAL_OK)
        return MPU6050_OK;
    else
        return MPU6050_ERROR; 
}

void mpu6050_Init(void)
{
    uint8_t cmd;
    
    cmd = 0x00;
    mpu6050_WeReg(PWR_MGMT_1, &cmd,1); //解除休眠状态
    
    cmd = 0x07;
    mpu6050_WeReg(SMPLRT_DIV,  &cmd,1);
    
    cmd = 0x06;
    mpu6050_WeReg(CONFIG,  &cmd,1);
    
    cmd = 0xE8;
    mpu6050_WeReg(GYRO_CONFIG,  &cmd,1);
    
    cmd = 0x01;
    mpu6050_WeReg(ACCEL_CONFIG,  &cmd,1);
}

void mpu6050_ReadData(void)
{
    uint8_t ucReadBuf[14];
    
    mpu6050_RdReg( ACCEL_XOUT_H, ucReadBuf,14);

    /* 将读出的数据保存到全局结构体变量 */
    g_tMPU6050.Accel_X = (ucReadBuf[0] << 8) + ucReadBuf[1];
    g_tMPU6050.Accel_Y = (ucReadBuf[2] << 8) + ucReadBuf[3];
    g_tMPU6050.Accel_Z = (ucReadBuf[4] << 8) + ucReadBuf[5];

    g_tMPU6050.Temp = (int16_t)((ucReadBuf[6] << 8) + ucReadBuf[7]);

    g_tMPU6050.GYRO_X = (ucReadBuf[8] << 8) + ucReadBuf[9];
    g_tMPU6050.GYRO_Y = (ucReadBuf[10] << 8) + ucReadBuf[11];
    g_tMPU6050.GYRO_Z = (ucReadBuf[12] << 8) + ucReadBuf[13];
}

void mpu6050_test( void )
{
    mpu6050_Init();

    while(1)
    {
        HAL_Delay(1000);
        mpu6050_ReadData();
        {
            printf("AX=%6d,AY=%6d,AZ=%6d,",
            g_tMPU6050.Accel_X,
            g_tMPU6050.Accel_Y,
            g_tMPU6050.Accel_Z);

            printf("GX=%6d,GY=%6d,GZ=%6d,T=%6d \r",
            g_tMPU6050.GYRO_X,
            g_tMPU6050.GYRO_Y,
            g_tMPU6050.GYRO_Z,
            g_tMPU6050.Temp);            
        }
    }
}




/* End of this file */


2)创建mp6050.h,编写如下代码

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : mpu9050.h
  * Description        : I2C drive based on STM32F4
  * 
  ******************************************************************************
  * @attention
  *
  * Copyright (c) 2024~2029 mingfei.tang
  * All rights reserved.
  *
  *************************************************************************
  */
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MPU6050_H
#define __MPU6050_H

#ifdef __cplusplus
 extern "C" {
#endif

#include "stdio.h"
#include "main.h"

#define MPU6050_OK               1
#define MPU6050_ERROR            0


#define bsp_DelayMS              HAL_Delay

#define MPU6050_SLAVE_ADDRESS    0xD0        /* I2C从机地址 */

//****************************************
// 定义MPU6050内部地址
//****************************************
#define    SMPLRT_DIV           0x19    //陀螺仪采样率,典型值:0x07(125Hz)
#define    CONFIG               0x1A    //低通滤波频率,典型值:0x06(5Hz)
#define    GYRO_CONFIG          0x1B    //陀螺仪自检及测量范围,典型值:0x18(不自检,2000deg/s)

#define    ACCEL_CONFIG         0x1C    //加速计自检、测量范围及高通滤波频率,典型值:0x01(不自检,2G,5Hz)

#define    ACCEL_XOUT_H         0x3B
#define    ACCEL_XOUT_L         0x3C
#define    ACCEL_YOUT_H         0x3D
#define    ACCEL_YOUT_L         0x3E
#define    ACCEL_ZOUT_H         0x3F
#define    ACCEL_ZOUT_L         0x40

#define    TEMP_OUT_H           0x41
#define    TEMP_OUT_L           0x42

#define    GYRO_XOUT_H          0x43
#define    GYRO_XOUT_L          0x44
#define    GYRO_YOUT_H          0x45
#define    GYRO_YOUT_L          0x46
#define    GYRO_ZOUT_H          0x47
#define    GYRO_ZOUT_L          0x48

#define    PWR_MGMT_1           0x6B    //电源管理,典型值:0x00(正常启用)
#define    WHO_AM_I             0x75    //IIC地址寄存器(默认数值0x68,只读)

typedef struct
{
    int16_t Accel_X;
    int16_t Accel_Y;
    int16_t Accel_Z;

    int16_t Temp;

    int16_t GYRO_X;
    int16_t GYRO_Y;
    int16_t GYRO_Z;
}MPU6050_T;

extern MPU6050_T g_tMPU6050;


void mpu6050_test( void );

#ifdef __cplusplus
}
#endif

#endif /*__MPU6050_H */

5 测试

1)编写测试代码

void mpu6050_test( void )
{
    mpu6050_Init();

    while(1)
    {
        HAL_Delay(1000);
        mpu6050_ReadData();
        {
            printf("AX=%6d,AY=%6d,AZ=%6d,",
            g_tMPU6050.Accel_X,
            g_tMPU6050.Accel_Y,
            g_tMPU6050.Accel_Z);

            printf("GX=%6d,GY=%6d,GZ=%6d,T=%6d \r",
            g_tMPU6050.GYRO_X,
            g_tMPU6050.GYRO_Y,
            g_tMPU6050.GYRO_Z,
            g_tMPU6050.Temp);            
        }
    }
}

2)编写代码,并下载到板卡中,运行代码

6 逻辑分析仪捕捉波形

 读取数据的波形

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/701036.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

WindTerm使用SSH密钥连接阿里云实例,服务器设置SSH密钥登录

安装Windterm 地址https://github.com/kingToolbox/WindTerm/releases 下载完放到文件夹就可以打开 阿里云开启密钥对 打开阿里云ecs控制台 https://ecs.console.aliyun.com/keyPair/region/cn-wulanchabu 网络与安全->密钥对&#xff0c;创建密钥对&#xff0c;创建成…

6.11 作业

以下是一个简单的比喻&#xff0c;将多态概念与生活中的实际情况相联系&#xff1a; 比喻&#xff1a;动物园的讲解员和动物表演 想象一下你去了一家动物园&#xff0c;看到了许多不同种类的动物&#xff0c;如狮子、大象、猴子等。现在&#xff0c;动物园里有一位讲解员&…

OA协同办公系统 iWebPDF插件安装

1、下载压缩文件 iweboffice&#xff0c;并进行解压 链接&#xff1a;https://pan.baidu.com/s/1GQd7000PTZ771ifL5KEflg 提取码&#xff1a;hb56 2、安装iWenpdf2018.exe 3、安装金格中间件外部应用 4、测试了谷歌、360安全&#xff0c;发现安装插件后&#xff0c;只有360极…

10秒变鬼短视频:四川鑫悦里文化传媒有限公司

10秒变鬼短视频&#xff1a;创意与惊悚的完美融合 在短视频的世界里&#xff0c;创新与独特性 节奏、巧妙的剪辑和惊悚的氛围&#xff0c;成为了许多观众喜爱的对象。四川鑫悦里文化传媒有限公司将探讨“10秒变鬼”短视频的创作技巧、受众心理以及其对短视频行业的启示。 一…

【ubuntu22.04~mysql-MHA-mycat】

ubuntu22.04~mysql-MHA-mycat 前言一、安装指定版本mysql-server(8.0.23)1、安装mysql2、启用修改mysql配置1、安装3、修改权限3.1、用户密码存放位置,3.2、创建用户root@%4、mysql配置文件my.cnf修改1、主节点my.cnf2、slave1~my.cnf修改项3、slave2~my.cnf修改项5、重启mys…

我的网络安全之路——一场诗意的邂逅

文章来源&#xff5c;MS08067 安全实验室 本文作者&#xff1a;tuooo 我的网络安全之路 一场诗意的邂逅 童年的星光中&#xff0c;我仰望着璀璨的荧屏&#xff0c;心怀对未知机器世界的浩瀚与好奇。那时的我&#xff0c;每每想到各种游戏的破解版本与工具&#xff0c;便会被技术…

SpringBoot+layui实现商品打标

标题 下拉框组件效果图代码实现前端界面产品打标页面代码 后端代码controllerservice ,serviceImplmappermapper.xmlentity 数据库表 下拉框组件 xm-select 效果图 代码实现 前端界面 <script type"text/html" id"stockTags"><div><div&…

助力草莓智能自动化采摘,基于YOLOv5全系列【n/s/m/l/x】参数模型开发构建果园种植采摘场景下草莓成熟度智能检测识别系统

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;技术已经渗透到我们生活的方方面面&#xff0c;从智能家居到自动驾驶&#xff0c;再到医疗健康&#xff0c;其影响力无处不在。然而&#xff0c;当我们把目光转向中国的农业领域时&#xff0c;一个令人惊讶的…

如何优雅的实现Excel导入通用处理流程

目录 1.业务背景2.业务导入流程3.流程优化3.1 模板模式3.1.1 导入处理器接口ImportProcessor3.1.2 抽象父类 AbstractImportProcessor3.1.3 子类实现 ImportDemoProcessor 3.2 工厂模式3.2.1 标识子类的枚举ImportTypeEnum3.2.2 工厂类ProcessorHolder3.2.3 工厂类的调用 4. 特…

openh264 编码器源码分析:主体框架

openh264 OpenH264 是一个开源的 H.264 编码解码库&#xff0c;专为实时应用如 WebRTC 设计。OpenH264 编码器因其高效性能、广泛的操作系统和架构支持以及灵活的编码参数设置&#xff0c;成为许多开发者在需要 H.264 编码解码解决方案时的理想选择。关于其介绍可以参考&#…

express+宝塔实现文件上传服务

文章目录 服务器部分开启存放文件的端口配置nginx该端口入口手动在/www/wwwroot/file目录下存放一张图片进行访问 express接口部分代码测试 服务器部分 开启存放文件的端口 我这里以83为例 先到对应的服务商开启端口&#xff0c;比如我这里是阿里云 测试&#xff0c;比如这里…

大模型基础——从零实现一个Transformer(3)

大模型基础——从零实现一个Transformer(1)-CSDN博客 一、前言 之前两篇文章已经讲了Transformer的Embedding,Tokenizer,Attention,Position Encoding, 本文我们继续了解Transformer中剩下的其他组件. 二、归一化 2.1 Layer Normalization layerNorm是针对序列数据提出的一种…

如何掌握多门编程语言?

我的答案是&#xff1a;掌握学习新编程语言的能力。 授之以鱼不如授之以渔 对于一个编程老手来说&#xff0c;学习新的编程语言应该很容易。他们只需要一个周末甚至是几个小时就可以开始用新学的编程语言写代码了。优秀的程序员可以为了完成某个任务使用任何一门编程语言。毕…

UE5 Sequencer 使用指导 - 学习笔记

https://www.bilibili.com/video/BV1jG411L7r7/?spm_id_from333.337.search-card.all.click&vd_source707ec8983cc32e6e065d5496a7f79ee6 Sequencer 01 1.1 调整视口 调整窗口数量 调整视口类型为Cinematic视口 视口显示网格&#xff0c;或者条件参考线 1.2 关卡动画与…

探索工厂智能制造解决方案的革新与应用

随着工业4.0时代的到来&#xff0c;工厂智能制造解决方案正在以前所未有的速度和规模改变着传统制造业的面貌。从自动化生产到智能化管理&#xff0c;工厂智能制造解决方案正在为制造企业带来前所未有的效率提升和竞争优势。本文将深入探讨工厂智能制造解决方案的革新与应用&am…

ANSYS电池包行业结构仿真解决方案

目前动力电池开发中面临的问题&#xff1a; ▪ 性能(能量密度及功率密度) ▪ 耐用性和使用寿命(考虑在不同环境和使用周期) ▪ 安全性(考虑恶劣环境) ▪ 费用成本 ▪ 复杂的多尺度、多物理场系统 ▪ 快速发展的材料和设计理念 ▪ 现有软件工具局限性 目录 1. 动力电池开…

Python 制作词云图

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

VM ubuntu终端使用Host代理的方法

1、设置网络地址转换NAT 2、在终端敲击如下命令 先敲击 ip route show 找到网关。再敲击如下命令&#xff1a; export http_proxyhttp://10.0.2.2:33210 export https_proxyhttp://10.0.2.2:33210 export HTTP_PROXYhttp://10.0.2.2:33210/ export HTTPS_PROXYhttp://10.0.2.…

“探索AIGC市场:腾讯元宝APP加入竞争,大模型产品的未来走向与个人选择“

文章目录 每日一句正能量前言使用体验分享独特优势和倾向选择字节豆包百度文心一言阿里通义千问腾讯元宝个人倾向选择结论 未来发展方向技术创新可持续可拓展性用户体验应用场景政府赋能数据安全与隐私保护伦理与社会责任国际合作与竞争结论 后记 每日一句正能量 不管现在有多么…

小程序视图渲染数据和部分事件的绑定

今天依旧使用这个目录进行教学 数据的渲染 在 index.js的 page中定义一个data对象结构是这样的 Page({data:{name:张三} }) 在index.wxml 中 利用模板语法进行渲染 <view >{{name}}</view> 注意这个模板里边不能使用js的方法 要循环渲染数组&#xff0c;如 在…