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

news2024/11/14 0:59:47

目录

概述

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 逻辑分析仪捕捉波形

 读取数据的波形

 

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

openlayers 绘图功能,绘制多边形,draw组件的使用,一个简单的需求引发的思考(二)

上一篇是使用openlayers原生实现的&#xff0c;这一节使用vue3-openlayers实现(有轮子真好) 1 需求 使用openlayers绘图功能绘制多边形 2 分析 主要是openlayers中draw功能的使用 3 实现 为了方便&#xff0c;就不加载底图了&#xff0c;直接使用绘制功能 2.1 简单实现 …

ttkbootstrap的icon图标自定义

前言 在使用ttkbootstrap库时&#xff0c;发现icon参数使用报错&#xff0c;错误代码 root ttk.Window(themename"superhero",size(1400, 700),resizable(True, True),iconphoto"1.png" )结果报错&#xff1a;iconphoto path is bad; using default ima…

AC/DC电源模块的原理、特点以及其在实际应用中的重要性

BOSHIDA AC/DC电源模块的原理、特点以及其在实际应用中的重要性 AC/DC电源模块是一种用于将交流电转换为直流电的设备&#xff0c;广泛应用于各种电子设备中。这种电源模块可以有效地将电力从电网中提取出来&#xff0c;并将其转换为稳定的直流电源&#xff0c;供给各种不同功…

【短剧看剧系统之投流版】短剧看剧系统功能更新,前端uniapp搭建开发

目录 一、常规款短剧系统和投流版的区别&#xff1f; 二、后端体系 1.管理端&#xff1a; 2.代理投流端 三、功能区别 总结&#xff1a; 前言&#xff1a; 短剧看剧系统目前在抖音端是比较热门的&#xff0c;最重要的功能就是可以接入第三方cps&#xff0c;包含类目报白…

万众瞩目的苹果AI来了,但我们用不了

关注卢松松&#xff0c;会经常给你分享一些我的经验和观点。 从今天开始&#xff0c;最了解你的不是你老婆&#xff0c;不是你自己&#xff0c;而是苹果AI。 万众瞩目的苹果WWDC24开发者大会在大半夜举办了&#xff0c;其中一项重要的更新是&#xff1a;苹果宣布要把ChatGPT集…

MES系统定制 | 生产调度车间排班计划/MES排程排产

MES系统是一种集成化的生产信息化管理系统&#xff0c;通过实时收集和分析车间生产数据&#xff0c;帮助企业实现生产过程的自动化控制和监测。它可以跟踪生产计划、设备状态、物料流动等关键指标&#xff0c;并提供实时报表和决策支持。在这个系统中&#xff0c;车间班次排班是…

零基础直接上手java跨平台桌面程序,使用javafx(五)TableView显示excel表

我们在窗口的中间加上TableVie&#xff1a; 在hello-view.fxml的文本中&#xff0c;要增加一些代码。在TableView定义中加上fx:id"TableView1"&#xff0c;这样java代码才方便访问&#xff0c;在java代码中要加上FXML private TableView TableView1;表示定义TableVie…

如何禁止使用U盘|禁止使用U盘的四个方法

你知道U盘滥用对企业的危害&#xff0c;总接下来有这三点: 数据泄露&#xff1a;U盘可以方便地存储和传输大量数据&#xff0c;但如果U盘丢失或被盗&#xff0c;其中的数据可能会被他人获取&#xff0c;从而导致数据泄露。病毒传播&#xff1a;U盘是病毒传播的常见途径之一。如…

基于若依的ruoyi-nbcio-plus里抄送人多页选择人员的bug修复

更多ruoyi-nbcio功能请看演示系统 gitee源代码地址 前后端代码&#xff1a; https://gitee.com/nbacheng/ruoyi-nbcio 演示地址&#xff1a;RuoYi-Nbcio后台管理系统 http://218.75.87.38:9666/ 更多nbcio-boot功能请看演示系统 gitee源代码地址 后端代码&#xff1a; h…

点云技术在AI绘画中的革新性应用

引言&#xff1a; 随着人工智能的不断演进&#xff0c;艺术与科技的交融催生了AI绘画这一全新的创作方式。AI绘画不仅为艺术家提供了前所未有的工具&#xff0c;也拓展了艺术表达的边界。在这一进程中&#xff0c;点云技术作为一种重要的三维数据处理手段&#xff0c;其在AI绘画…

深入解析:常用的IP地址类型及其应用

随着互联网的日益发展&#xff0c;IP地址已经成为了我们日常生活中不可或缺的一部分。无论是浏览网页、发送邮件&#xff0c;还是进行在线视频通话&#xff0c;都离不开IP地址的参与。然而&#xff0c;对于许多非专业人士来说&#xff0c;IP地址的分类及其应用可能还是一个相对…

1502 - JUC高并发

慢慢挣&#xff0c;今天比昨天更有钱&#xff0c;明天比今天有钱&#xff0c;后天比明天有钱。 0.思维导图 6.多线程锁 synchronized实现同步的基础&#xff1a;Java中的每一个对象都可以作为锁。 具体表现为以下3中形式 对于普通同步方法&#xff0c;锁是当前实例对象。对于…

Python 基础001 pythonpycharm安装

1 安装python 尽量在官网安装 根据电脑情况下载,下载完需要重启电脑 python安装路径自定义 添加环境变量&#xff08;add path&#xff09;需要勾选&#xff0c;若无勾选&#xff0c;手动更新环境变量 确认python是否安装成功&#xff1a; 方法一&#xff1a;有安装成功&am…

零基础直接上手java跨平台桌面程序,使用javafx(六)查询sqlite数据显示到TableView中

我们使用jdbc查询sqlite的一个表显示到TableView中 在hello-view的onMouseClicked里面填上“openclick2”&#xff0c;然后在HelloController写上openclick2的相关代码FXML protected void openclick2() { }。我们要先配置好sqlite的jdbc驱动&#xff08;略&#xff09;。openc…

代码随想录算法训练营第二十九天【回溯】| 491,46,47

491. Non-decreasing Subsequences 排列用startindex 树枝不去重&#xff0c;树层去重 子集问题结果在结点&#xff08;个数>2&#xff09; class Solution(object):def findSubsequences(self, nums):""":type nums: List[int]:rtype: List[List[int]]&…

如何在网上下载到最新或者历史QGIS各个版本的C++源码

背景&#xff1a; 博主写下这篇文章的时候已经是PyQGIS下二开了两年&#xff0c;开发一些功能必须得去阅读QGIS的C版本源码&#xff0c;还得考虑到QGIS的长期稳定版和最新版的源码区别。 所以如何去下载到QGIS的源码&#xff0c;就成了当务之急。 QGIS3.36.3的C源码长得像这…

KOL营销在时尚、美妆与健康行业的特点解析与应用策略

在当今数字化时代&#xff0c;KOL营销已经成为推动品牌影响力和销售增长的重要策略之一。尤其在时尚、美妆和健康等行业&#xff0c;KOL的影响力和效果尤为显著。本文Nox聚星将和大家详细探讨KOL营销在这些行业中的应用情况、特点以及最佳实践。 一、时尚行业KOL营销 时尚行业…

finalshell创建和使用

1、下载安装 下载地址Finalshell SSH工具,业界最强大的SSH客户机 2、创建连接 点击文件夹新建连接

Struts2 系列漏洞 - S2-003、S2-005

一、前言 前面一篇文章也有提到 struts2 在进入 action 进行逻辑处理前&#xff08;以及逻辑处理后&#xff09;&#xff0c;会进入 18 个拦截器栈中对请求进行必要的处理&#xff08;如果没有自定义拦截器的话&#xff0c;可以在 struts-default.xml 中找到相应的拦截器栈&am…

【学习笔记】使用gcc编译程序并检查依赖的库

编译 gcc echo.c -o app -lfcgi-o app&#xff1a;指定编译后的输出文件名为 app。 -lfcgi&#xff1a;告诉编译器链接 FastCGI 库。 检查 ldd appldd 是一个在 Unix 和类 Unix 系统中用来打印一个已编译的程序所依赖的共享库列表的命令。当你运行 ldd app 命令时&#xff0…