STM32 HAL驱动MPU6050传感器

STM32 HAL驱动MPU6050传感器

项目概述

本项目实现了基于STM32 HAL库的MPU6050传感器驱动,可以读取加速度计和陀螺仪数据。项目使用I2C接口与MPU6050通信,并通过UART接口输出数据。

项目仓库地址:STM32_Sensor_Drives

硬件连接

在这里插入图片描述

MPU6050 I2C接口

PB10 ------> I2C2_SCL
PB11 ------> I2C2_SDA

UART调试接口

PA2 ------> USART2_TX
PA3 ------> USART2_RX

代码结构

项目主要包含以下文件:

  • main.c: 主程序入口,初始化外设并循环读取MPU6050数据
  • i2c.c/h: I2C配置和MPU6050驱动函数
  • usart.c/h: UART配置和printf重定向
  • gpio.c/h: GPIO配置

MPU6050驱动实现

数据结构定义

i2c.h中定义了MPU6050数据结构:

typedef struct _mpu6050_data{double ACCEL_X ,ACCEL_Y ,ACCEL_Z;double GYRO_X ,GYRO_Y ,GYRO_Z;
}mpu6050_data;

初始化函数

i2c.c中实现了MPU6050初始化函数:

void MPU6050_start(void)
{uint8_t SendAddress = 0x6b;uint8_t SendData  = 0x00; //解除休眠状态HAL_I2C_Mem_Write(&hi2c2,0xD1,SendAddress,1,&SendData,1,0xff);SendAddress = 0x19;//采样率分频器SendData = 0x07;HAL_I2C_Mem_Write(&hi2c2,0xD1,SendAddress,1,&SendData,1,0xff);SendAddress = 0x1A;//低通滤波器SendData = 0x06;HAL_I2C_Mem_Write(&hi2c2,0xD1,SendAddress,1,&SendData,1,0xff);SendAddress = 0x1B;//陀螺仪SendData = 0x08;   //± 500 °/sHAL_I2C_Mem_Write(&hi2c2,0xD1,SendAddress,1,&SendData,1,0xff);SendAddress = 0x1C;//加速度计SendData = 0x00;   //± 2gHAL_I2C_Mem_Write(&hi2c2,0xD1,SendAddress,1,&SendData,1,0xff);   
}

初始化步骤:

  1. 解除MPU6050休眠状态(寄存器0x6B)
  2. 设置采样率分频器(寄存器0x19)
  3. 配置低通滤波器(寄存器0x1A)
  4. 配置陀螺仪量程为±500°/s(寄存器0x1B)
  5. 配置加速度计量程为±2g(寄存器0x1C)

数据读取函数

i2c.c中实现了MPU6050数据读取函数:

void get_i2c_mpu6050(mpu6050_data *data){uint8_t MPU_Data[] = {0X00, 0X00,0X00, 0X00,0X00, 0X00,0X00, 0X00,0X00, 0X00,0X00, 0X00,0X00, 0X00};uint8_t preg1_Data  = 0x3B;HAL_I2C_Mem_Read(&hi2c2, 0xD1,preg1_Data,I2C_MEMADD_SIZE_8BIT,MPU_Data,14,50);float Temp = (MPU_Data[6]<<8)|MPU_Data[7];if(Temp>32768) Temp-=65536;Temp=(36.53+Temp/340);short int ACCEL_XOUT1 = ((MPU_Data[0]<<8)|MPU_Data[1]);data->ACCEL_X = (double)ACCEL_XOUT1/16384;short int ACCEL_YOUT1 = ((MPU_Data[2]<<8)|MPU_Data[3]);data->ACCEL_Y = (double)ACCEL_YOUT1/16384;short int ACCEL_ZOUT1 = ((MPU_Data[4]<<8)|MPU_Data[5]);data->ACCEL_Z = (double)ACCEL_ZOUT1/16384;short int GYRO_XOUT1 = ((MPU_Data[8]<<8)|MPU_Data[9]);data->GYRO_X = (double)GYRO_XOUT1/65.5;short int GYRO_YOUT1 = ((MPU_Data[10]<<8)|MPU_Data[11]);data->GYRO_Y = (double)GYRO_YOUT1/65.5;short int GYRO_ZOUT1 = ((MPU_Data[12]<<8)|MPU_Data[13]);data->GYRO_Z = (double)GYRO_ZOUT1/65.5;
}

数据读取步骤:

  1. 从寄存器0x3B开始,连续读取14个字节的数据
  2. 处理温度数据(虽然在本例中未使用)
  3. 处理加速度数据(前6个字节)
    • X轴加速度:字节0-1
    • Y轴加速度:字节2-3
    • Z轴加速度:字节4-5
    • 除以16384转换为g单位(±2g量程下)
  4. 处理陀螺仪数据(后6个字节)
    • X轴角速度:字节8-9
    • Y轴角速度:字节10-11
    • Z轴角速度:字节12-13
    • 除以65.5转换为°/s单位(±500°/s量程下)

I2C配置

I2C配置在i2c.c中实现:

void MX_I2C2_Init(void)
{hi2c2.Instance = I2C2;hi2c2.Init.ClockSpeed = 100000;hi2c2.Init.DutyCycle = I2C_DUTYCYCLE_2;hi2c2.Init.OwnAddress1 = 0;hi2c2.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;hi2c2.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;hi2c2.Init.OwnAddress2 = 0;hi2c2.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;hi2c2.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;if (HAL_I2C_Init(&hi2c2) != HAL_OK){Error_Handler();}
}

主要配置:

  • 时钟速度:100kHz
  • 7位地址模式
  • 禁用时钟拉伸

UART配置与printf重定向

UART配置在usart.c中实现:

void MX_USART2_UART_Init(void)
{huart2.Instance = USART2;huart2.Init.BaudRate = 115200;huart2.Init.WordLength = UART_WORDLENGTH_8B;huart2.Init.StopBits = UART_STOPBITS_1;huart2.Init.Parity = UART_PARITY_NONE;huart2.Init.Mode = UART_MODE_TX_RX;huart2.Init.HwFlowCtl = UART_HWCONTROL_NONE;huart2.Init.OverSampling = UART_OVERSAMPLING_16;if (HAL_UART_Init(&huart2) != HAL_OK){Error_Handler();}
}

为了支持printf函数,重定向了fputc函数:

int fputc(int ch, FILE *f)
{if (f == stdout)  // 仅处理标准输出{HAL_UART_Transmit(&huart2, (uint8_t *)&ch, 1, 100);  // 阻塞发送if (ch == '\n')  // 发送\n时自动补充\rHAL_UART_Transmit(&huart2, (uint8_t *)"\r", 1, 100);}return ch;
}

主程序

主程序在main.c中实现:

int main(void)
{/* 初始化代码省略 */MX_GPIO_Init();MX_USART2_UART_Init();MX_I2C2_Init();/* USER CODE BEGIN 2 */MPU6050_start();/* USER CODE END 2 *//* Infinite loop *//* USER CODE BEGIN WHILE */printf("System will start while\n");while (1){mpu6050_data data = {0};get_i2c_mpu6050(&data);printf("ax: %.3f--ay: %.3f--az: %.3f--gx: %.3f--gy: %.3f--gz: %.3f\n", data.ACCEL_X, data.ACCEL_Y, data.ACCEL_Z, data.GYRO_X, data.GYRO_Y, data.GYRO_Z);HAL_Delay(200);/* USER CODE END WHILE *//* USER CODE BEGIN 3 */}/* USER CODE END 3 */
}

主程序流程:

  1. 初始化GPIO、UART和I2C外设
  2. 初始化MPU6050传感器
  3. 进入主循环
    • 读取MPU6050数据
    • 通过UART打印数据
    • 延时200ms

MPU6050寄存器说明

寄存器地址名称功能
0x6BPWR_MGMT_1电源管理1,用于设备复位、睡眠模式、时钟源等
0x19SMPLRT_DIV采样率分频器
0x1ACONFIG配置寄存器,主要用于配置DLPF(数字低通滤波器)
0x1BGYRO_CONFIG陀螺仪配置,设置量程等
0x1CACCEL_CONFIG加速度计配置,设置量程等
0x3B-0x40ACCEL_XOUT_H至ACCEL_ZOUT_L加速度计输出数据
0x41-0x42TEMP_OUT_H和TEMP_OUT_L温度传感器输出数据
0x43-0x48GYRO_XOUT_H至GYRO_ZOUT_L陀螺仪输出数据

注意事项

  1. MPU6050的I2C地址为0x68(二进制:1101000),但在代码中使用的是0xD1(二进制:11010001)。这是因为HAL库的I2C函数需要在7位地址后添加读/写位(0表示写,1表示读)。

  2. 加速度计和陀螺仪的原始数据都是16位有符号整数,需要进行转换才能得到实际的物理量:

    • 加速度计:在±2g量程下,除以16384得到以g为单位的加速度
    • 陀螺仪:在±500°/s量程下,除以65.5得到以°/s为单位的角速度
  3. 温度传感器的数据转换公式为:温度(°C) = 36.53 + (原始数据/340)

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

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

相关文章

flex-wrap子元素是否换行

flex-wrap设置子元素是否换行&#xff0c;默认情况下&#xff0c;项目都排在一条线&#xff08;又称”轴线”&#xff09;上。flex-wrap属性定义&#xff0c;flex布局中默认是不换行的。1、div的宽度是600px&#xff0c;每个span的宽度是150px&#xff0c;总共有5个&#xff0c…

RabbitMQ面试精讲 Day 21:Spring AMQP核心组件详解

【RabbitMQ面试精讲 Day 21】Spring AMQP核心组件详解 开篇 欢迎来到"RabbitMQ面试精讲"系列第21天&#xff01;今天我们将深入探讨Spring AMQP的核心组件&#xff0c;这是Java开发者集成RabbitMQ最常用的框架。掌握Spring AMQP不仅能提升开发效率&#xff0c;更是…

Flink TableAPI 按分钟统计数据量

一、环境版本环境版本Flink1.17.0Kafka2.12MySQL5.7.33二、MySQL建表脚本 create table user_log (id int auto_increment comment 主键primary key,uid int not null comment 用户id,event int not null comment 用户行为,logtime bigint null comment 日志时…

18.13 《3倍效率提升!Hugging Face datasets.map高级技巧实战指南》

3倍效率提升!Hugging Face datasets.map高级技巧实战指南 实战项目:使用 datasets.map 进行高级数据处理 在大模型训练过程中,数据预处理的质量直接决定了模型最终的表现。Hugging Face Datasets 库提供的 datasets.map 方法是处理复杂数据场景的瑞士军刀,本章将深入解析…

实体店获客新引擎:数据大集网如何破解传统门店引流难题

在商业竞争日益激烈的当下&#xff0c;实体店的生存与发展正面临前所未有的挑战。无论是街边的小型便利店&#xff0c;还是大型购物中心的连锁品牌&#xff0c;都在为"如何吸引顾客进店"而绞尽脑汁。传统广告投放效果不佳、线下流量持续萎缩、客户转化率难以提升………

LeetCode 分类刷题:2302. 统计得分小于 K 的子数组数目

题目一个数组的 分数 定义为数组之和 乘以 数组的长度。比方说&#xff0c;[1, 2, 3, 4, 5] 的分数为 (1 2 3 4 5) * 5 75 。给你一个正整数数组 nums 和一个整数 k &#xff0c;请你返回 nums 中分数 严格小于 k 的 非空整数子数组数目。子数组 是数组中的一个连续元素序…

TDengine IDMP 基本功能(1.界面布局和操作)

UI 布局和操作说明 TDengine IDMP 的用户界面&#xff08;UI&#xff09;设计旨在提供直观、易用的操作体验。下面介绍 UI 的主要区域和典型操作&#xff1a; 主要区域 IDMP 的用户界面是完全基于浏览器的。登录后的典型 UI 界面具有几个区域&#xff1a; 主菜单&#xff1a;AI…

QT(概述、基础函数、界面类、信号和槽)

一、概述1、QTQT是一个c的第三方库&#xff0c;是专门用来进行界面编程的一个库 1. QT本身实现了多种软件&#xff1a; 2. ubuntu系统中所有界面都是QT做的 3. 最新版本的QQ也是QT做的 4. 嵌入式编程中&#xff0c;几乎所有的上位机&#xff0c;都可以使用QT来做 QT本身除了实现…

【从零开始java学习|第六篇】运算符的使用与注意事项

目录 一、算术运算符 1. 基本算术运算符&#xff08;二元&#xff09; 2. 自增 / 自减运算符&#xff08;一元&#xff09; 二、类型转换&#xff08;隐式与强制&#xff09; 1. 隐式转换&#xff08;自动类型转换&#xff09; ​编辑 2. 强制转换&#xff08;显式类型转…

shellgpt

一、介绍 官网&#xff1a;https://github.com/TheR1D/shell_gpt ShellGPT&#xff08;shell_gpt&#xff09; 是一款把 GPT 系列大模型能力直接搬到终端 的开源命令行生产力工具。用日常英语或中文描述需求&#xff0c;就能帮你 生成、解释甚至自动执行 Shell 命令&#xff…

geoserver sql视图调用Postgis自定义函数问题记录

一、问题描述&#xff1a;geoserver sql视图调用Postgis自定义函数对点图层增加一条记录时&#xff0c;返回结果主键自增ID加了2&#xff0c;但表中数据只增加一条记录。 但在pgAdmin中直接写SQL调用Postgis自定义函数对点图层增加一条记录时&#xff0c;返回结果主键自增ID只加…

#T1224. 最大子矩阵

题目传送 题目描述 已知矩阵的大小定义为矩阵中所有元素的和。给定一个矩阵&#xff0c;你的任务是找到最大的非空(大小至少是11)子矩阵。 比如&#xff0c;如下44的矩阵 0 -2 -7 09 2 -6 2 -4 1 -4 1-1 8 0 -2的最大子矩阵是 9 2-4 1-1 8这…

2025年大模型安全岗的面试汇总(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 1. Transformer核心机制及其对LLM突破的基石作用 2. LLM能力边界评估框架设计 3. 模型层级安全风险分析 …

《关于省级政务云服务费支出预算标准的规定》豫财预〔2024〕106号解读

《关于省级政务云服务费支出预算标准的规定》豫财预〔2024〕106号文件由河南省财政厅编制经省政府同意后于2024年12月3日印发执行&#xff0c;规定作为省级政务云服务费支出预算编制和审核的依据&#xff0c;旨在加强省级部门预算管理&#xff0c;规范政务云服务费支出预算编制…

使用HalconDotNet实现异步多相机采集与实时处理

文章目录 一、核心功能与原理 功能目标: 工作原理: 关键机制: 二、完整C#实现代码 三、关键实现解析 1. 零拷贝图像传输 2. 动态帧率控制 3. HALCON并行优化 4. 异常隔离机制 四、高级优化策略 1. 硬件加速配置 2. 内存池管理 3. 实时性保障 一、核心功能与原理 功能目标:…

《疯狂Java讲义(第3版)》学习笔记ch4

ch4流程控制与数组1.switch语句后的expression表达式的数据类型只能是byte、short、char、int四种证书类型。2.建议不要在循环体内修改循环变量&#xff08;也叫循环计数器&#xff09;的值&#xff0c;否则会增加程序出错的可能性。3.定义数组推荐语法格式&#xff1a;type[] …

COLMAP进行密集重建,三维重建的步骤

密集重建是在稀疏重建的基础上进行的 稀疏重建见&#xff1a;用 COLMAP GUI 在 Windows 下一步步完成 相机位姿估计&#xff08;SfM&#xff09; 和 稀疏点云重建的详细步骤&#xff1a;_colmap database导入图片位姿-CSDN博客 完成稀疏重建后直接进入以下步骤进行密集重建&am…

基于飞算JavaAI实现Reactor模式服务器的深度实践

一、飞算JavaAI技术概述 1.1 飞算JavaAI平台简介飞算JavaAI是飞算科技推出的智能化Java开发平台&#xff0c;通过AI技术赋能传统软件开发流程&#xff0c;为开发者提供从需求分析到代码实现的全流程智能化解决方案。该平台深度融合了人工智能技术与软件开发实践&#xff0c;具备…

量子人工智能

量子人工智能&#xff08;QAI&#xff09;是量子计算与人工智能的强大融合。这一领域旨在将量子系统独特的计算能力与人工智能的模式识别和学习能力相结合&#xff0c;以更快、更高效地解决问题。 量子人工智能与常规人工智能的区别是什么&#xff1f;常规人工智能在经典计算机…

算法题Day1

1. 练习1&#xff1a;Hello,World!解题步骤:using namespace std; int main() {cout<<"Hello,World!"<<endl;return 0; }2. 练习2&#xff1a;打印飞机解题步骤:#include <iostream> using namespace std; int main() {cout << " …