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

目录

概述

1 STM32Cube控制配置I2C

1.1 I2C参数配置

1.2 使用STM32Cube产生工程

2 HAL库函数介绍

2.1 初始化函数

2.2 写数据函数

 2.3 读数据函数

3 认识HMC5883L

3.1 HMC5883L功能介绍

3.2 HMC5883L的寄存器

4 HMC5883L驱动程序实现

4.1 驱动函数实现

4.2 完整驱动代码

5 测试

6 逻辑分析仪捕捉波形


概述

本文主要介绍STM32F4的内部I2C接口的使用方法,包括使用STM32Cube配置i2c接口函数,还介绍了STM32 HAL库中的接口函数,为了验证接口函数的是否能够正常工作,还使用HMC5883L
作为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 认识HMC5883L

3.1 HMC5883L功能介绍

霍尼韦尔HMC5883L是一款表面贴装的多芯片模块,专为低场磁传感设计,具有数字接口,适用于低成本罗盘和磁强计等应用。HMC5883L包括我们最先进的高分辨率HMC118X系列磁阻传感器,以及包含放大、自动消磁带驱动器、偏移抵消和12位ADC的ASIC,可实现1°至2°罗盘航向精度。I2C串行总线允许简单的接口。HMC5883L是3.0 × 3.0 × 0.9mm表面贴装16引脚无引线芯片载体(LCC)。

HMC5883L采用霍尼韦尔的各向异性磁阻(AMR)技术,与其他磁传感器技术相比具有优势。这些各向异性定向传感器具有高精度的轴内灵敏度和线性度。这些传感器的固态结构具有非常低的交叉轴灵敏度,旨在测量地球磁场的方向和大小,从毫高斯到8高斯。霍尼韦尔的磁传感器是业内最灵敏、最可靠的低场传感器之一。

3.2 HMC5883L的寄存器

该设备通过许多片上寄存器进行控制和配置,这些寄存器将在本节中描述。在以下描述中,除另有说明外,set表示逻辑1,reset或clear表示逻辑0。

4 HMC5883L驱动程序实现

4.1 驱动函数实现

1)写寄存器函数

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

2)读寄存器函数

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

4.2 完整驱动代码

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

/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name            : hmc5883l.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 "hmc5883l.h"HMC5883L_T g_tMag;static uint8_t hmc5883L_WeReg( uint16_t regAdd, uint8_t *pData, uint16_t Size )
{HAL_StatusTypeDef status;status = HAL_I2C_Mem_Write( &hi2c2, HMC5883L_SLAVE_ADDRESS, regAdd, I2C_MEMADD_SIZE_8BIT, pData, Size, 1000);if( status == HAL_OK)return HMC5883L_OK;elsereturn HMC5883L_ERROR; 
}static uint8_t hmc5883L_RdReg( uint16_t regAdd, uint8_t *pData, uint16_t Size )
{HAL_StatusTypeDef status;status = HAL_I2C_Mem_Read( &hi2c2, HMC5883L_SLAVE_ADDRESS, regAdd, I2C_MEMADD_SIZE_8BIT, pData, Size, 1000);if( status == HAL_OK)return HMC5883L_OK;elsereturn HMC5883L_ERROR; 
}void hmc5883L_WriteByte(uint8_t _ucRegAddr, uint8_t _ucRegData)
{hmc5883L_WeReg( _ucRegAddr, &_ucRegData, 1);
}uint8_t hmc5883L_ReadByte(uint8_t _ucRegAddr)
{uint8_t _ucRegData;hmc5883L_RdReg( _ucRegAddr, &_ucRegData, 1);return  _ucRegData;
}void hmc5883l_Init(void)
{/* 设置Mode寄存器 */#if 1hmc5883L_WriteByte(0x00, 0x70);hmc5883L_WriteByte(0x01, 0x20);hmc5883L_WriteByte(0x02, 0x00);#else    /* 自校准模式 */hmc5883L_WriteByte(0x00, 0x70 + 2);hmc5883L_WriteByte(0x01, 0x20);hmc5883L_WriteByte(0x02, 0x00);#endifg_tMag.CfgRegA = hmc5883L_ReadByte(0);g_tMag.CfgRegB = hmc5883L_ReadByte(1);g_tMag.ModeReg = hmc5883L_ReadByte(2);g_tMag.IDReg[0] = hmc5883L_ReadByte(10);g_tMag.IDReg[1] = hmc5883L_ReadByte(11);g_tMag.IDReg[2] = hmc5883L_ReadByte(12);g_tMag.IDReg[3] = 0;/* 设置最小最大值初值 */g_tMag.X_Min = 4096;g_tMag.X_Max = -4096;g_tMag.Y_Min = 4096;g_tMag.Y_Max = -4096;g_tMag.Z_Min = 4096;g_tMag.Z_Max = -4096;
}void hmc5883l_ReadData(void)
{uint8_t ucReadBuf[7];hmc5883L_RdReg( DATA_OUT_X, ucReadBuf, 7);/* 将读出的数据保存到全局结构体变量 */g_tMag.X = (int16_t)((ucReadBuf[0] << 8) + ucReadBuf[1]);g_tMag.Z = (int16_t)((ucReadBuf[2] << 8) + ucReadBuf[3]);g_tMag.Y = (int16_t)((ucReadBuf[4] << 8) + ucReadBuf[5]);g_tMag.Status = ucReadBuf[6];/* 统计最大值和最小值 */if ((g_tMag.X > - 2048) && (g_tMag.X < 2048)){if (g_tMag.X > g_tMag.X_Max){g_tMag.X_Max = g_tMag.X;}if (g_tMag.X < g_tMag.X_Min){g_tMag.X_Min = g_tMag.X;}    }if ((g_tMag.Y > - 2048) && (g_tMag.Y < 2048)){if (g_tMag.Y > g_tMag.Y_Max){g_tMag.Y_Max = g_tMag.Y;}if (g_tMag.Y < g_tMag.Y_Min){g_tMag.Y_Min = g_tMag.Y;}    }if ((g_tMag.Z > - 2048) && (g_tMag.Z < 2048)){if (g_tMag.Z > g_tMag.Z_Max){g_tMag.Z_Max = g_tMag.Z;}if (g_tMag.Z < g_tMag.Z_Min){g_tMag.Z_Min = g_tMag.Z;}    }
}void hmc5883l_test( void )
{hmc5883l_Init();while(1){hmc5883l_ReadData();printf("X=%5d(%5d,%5d),Y=%6d(%5d,%5d),Z=%6d(%5d,%5d)\r",g_tMag.X, g_tMag.X_Min, g_tMag.X_Max,g_tMag.Y, g_tMag.Y_Min, g_tMag.Y_Max,g_tMag.Z, g_tMag.Z_Min, g_tMag.Z_Max);HAL_Delay(100);}
}/* End of this file */

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

/* USER CODE BEGIN Header */
/********************************************************************************* File Name          : hmc5883l.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 __HMC5883L_H
#define __HMC5883L_H#ifdef __cplusplusextern "C" {
#endif#include "stdio.h"
#include "main.h"#define HMC5883L_OK               1
#define HMC5883L_ERROR            0#define bsp_DelayMS               HAL_Delay
#define HMC5883L_SLAVE_ADDRESS    0x3C           /* I2C从机地址 */#define DATA_OUT_X        0x03typedef struct
{int16_t X;int16_t Y;int16_t Z;int16_t X_Min;int16_t Y_Min;int16_t Z_Min;int16_t X_Max;int16_t Y_Max;int16_t Z_Max;uint8_t Status;uint8_t CfgRegA;uint8_t CfgRegB;uint8_t CfgRegC;uint8_t ModeReg;uint8_t IDReg[3+1];
}HMC5883L_T;extern HMC5883L_T g_tMag;void hmc5883l_test( void );#ifdef __cplusplus
}
#endif#endif /*__BH1750_H */
__HMC5883L_H

5 测试

1)编写测试代码

void hmc5883l_test( void )
{hmc5883l_Init();while(1){hmc5883l_ReadData();printf("X=%5d(%5d,%5d),Y=%6d(%5d,%5d),Z=%6d(%5d,%5d)\r",g_tMag.X, g_tMag.X_Min, g_tMag.X_Max,g_tMag.Y, g_tMag.Y_Min, g_tMag.Y_Max,g_tMag.Z, g_tMag.Z_Min, g_tMag.Z_Max);HAL_Delay(100);}
}

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

6 逻辑分析仪捕捉波形

 读取数据的波形

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

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

相关文章

如何使用CCS9.3打开CCS3.0工程

如何使用CCS9.3打开CCS3.0工程 点菜单栏上的project&#xff0c;选择Import Legacy CCSv3.3 Porjects…&#xff0c;弹出对话框&#xff0c;通过Browse…按钮导入一个3.3版本的工程项目&#xff1b; 选择.pjt文件&#xff0c;选择Copy projects into worlkspace 右击选择P…

Python酷库之旅-比翼双飞情侣库(08)

目录 一、xlrd库的由来 二、xlrd库优缺点 1、优点 1-1、支持多种Excel文件格式 1-2、高效性 1-3、开源性 1-4、简单易用 1-5、良好的兼容性 2、缺点 2-1、对.xlsx格式支持有限 2-2、功能相对单一 2-3、更新和维护频率低 2-4、依赖外部资源 三、xlrd库的版本说明 …

AIGC绘画设计—揭秘Midjourney关键词魔法:让你的AI绘画瞬间起飞

在这个数字化飞速发展的时代&#xff0c;AI技术正以前所未有的速度改变着我们的生活和创作方式。在艺术创作领域&#xff0c;Midjourney作为一款强大的AI绘画工具&#xff0c;正逐渐受到越来越多创作者和爱好者的青睐。今天&#xff0c;我就来为大家揭秘Midjourney背后的关键词…

【第9章】Vue之Element Plus快速入门

文章目录 前言一、安装1. 兼容性2. 安装 二、按需导入1.自动导入2.Vite 三、全局配置四、官方案例五、效果总结 前言 基于 Vue 3&#xff0c;面向设计师和开发者的组件库。 一、安装 1. 兼容性 Element Plus 目前还处于快速开发迭代中。 由于 Vue 3 不再支持 IE11&#xff0c…

Stability AI最新的SD3模型存在严重问题 为规避裸体结果导致躯体部分错乱

人工智能 Stability AI 最新的 SD3 Medium 模型存在严重问题&#xff0c;只要生成人物就会出现躯体错乱&#xff0c;这似乎是该公司刻意规避生成裸体图片的结果。目前猜测他们可能在训练过程中就剔除了 NSFW 内容&#xff0c;同时在训练时规避裸体内容进而导致模型也会刻意将人…

Java多线程学习笔记

文章目录 1. 引言1.1 多线程的重要性 2. 什么是多线程2.1 线程的定义和基本概念2.2 线程与进程的区别 3. 创建线程的方式3.1 继承Thread类3.2 实现Runnable接口&#xff0c;重写run方法3.3 实现Runnable接口&#xff0c;重写call方法3.4 匿名内部类创建Thread子类对象3.5 使用匿…

自定义 LLM:LangChain与文心一言擦出火花

自定义 LLM 自定义 LLM 需要实现以下必要的函数&#xff1a; _call &#xff1a;它需要接受一个字符串、可选的停用词&#xff0c;并返回一个字符串。 它还可以实现第二个可选的函数&#xff1a; _identifying_params &#xff1a;用于帮助打印 LLM 信息。该函数应该返回一…

如何在 Vue 3 中使用 vue3-print-nb 实现灵活的前端打印

你好&#xff0c;我是小白Coding日志&#xff0c;一个热爱技术的程序员。在这里&#xff0c;我分享自己在编程和技术世界中的学习心得和体会。希望我的文章能够给你带来一些灵感和帮助。欢迎来到我的博客&#xff0c;一起在技术的世界里探索前行吧&#xff01; 前言 在前端开…

Vue38-组件的几个注意点

一、组件回顾 1-1、创建组件 1-2、注册组件 1-3、使用组件 二、注意点&#xff1a;组件名 2-1、组件名一个单词&#xff1a;纯小写&#xff0c;或者&#xff0c;首字母大写 2-2、多个单词&#xff1a; 1、xx-bbbb 2、AaaBbbb&#xff1a;每个单词的首字母都大写 前提&…

【NUJ PA2】Read a Makefile

这里是NJU的PA2.2里面要求读懂的Makefile&#xff0c;是abstract-machine的。这里会放一些与读懂这个Makefile有关的知识。 下面是用ChatGPT解释的代码。只做大致的了解&#xff0c;写Makefile的时候还是要具体去看官方手册。 官方手册&#xff1a;make.pdf (gnu.org) # Makef…

Json-server 的使用教程

目录 前言一、简介二、安装与配置1. 安装 node-js2. npm 镜像设置3. 安装 json-server 三、使用1. 创建本地数据源2. 启动 Json Server3. 操作数据&#xff08;1&#xff09;查询数据&#xff08;2&#xff09;新增数据&#xff08;3&#xff09;修改数据&#xff08;4&#xf…

RTOS笔记--资源管理

资源管理 资源管理&#xff0c;其实就是前面介绍过的通知方式中的队列信号量互斥量等是如何访问临界资源的&#xff0c;如何做到完全互斥。 在之前举过一个例子&#xff1a;当我们使用全局变量来进行互斥操作时&#xff0c;有可能在改写全局变量时被切换使得不再互斥&#xff0…

【SpringBoot】深入分析 SpringApplication 源码:彻底理解 SpringBoot 启动流程

在黄昏的余晖里&#xff0c;梦境渐浓&#xff0c;如烟如雾。心随星辰&#xff0c;徜徉远方&#xff0c;岁月静好&#xff0c;愿如此刻般绵长。 文章目录 前言一、SpringBoot 应用二、SpringApplication2.1 SpringApplication 中的属性2.2 SpringApplication 的构造器2.3 Sprin…

【Linux】基础IO——文件描述符,重定向,FILE

话接上篇&#xff1a; 1.文件描述符fd 磁盘文件 VS 内存文件&#xff1f; 当文件存储在磁盘当中时&#xff0c;我们将其称之为磁盘文件&#xff0c;而当磁盘文件被加载到内存当中后&#xff0c;我们将加载到内存当中的文件称之为内存文件。磁盘文件和内存文件之间的关系就像程…

JVM 三色标记算法

三色标记算法核心原理 三色标记算法是一种JVM的垃圾标记算法&#xff0c;CMS/G1垃圾回收器就是使用的这种算法&#xff0c;它可以让JVM在不发生或者尽可能短的发生STW&#xff08;Stop The World&#xff09;的情况下进行垃圾的标记和清除。 顾名思义&#xff0c;三色标记算法…

实现JWT认证与授权的Spring Boot项目详解

我们将详细介绍如何使用JWT&#xff08;JSON Web Tokens&#xff09;结合Spring Boot框架实现用户认证和授权系统。此方案将包括用户注册、登录以及通过JWT令牌进行后续请求的身份验证过程。我们将从引入必要的依赖开始&#xff0c;然后逐步构建项目的各个部分&#xff0c;包括…

精品丨PowerBI迁移到SSAS

业务场景&#xff1a; 企业初期在进行 BI 可视化路线的时候&#xff0c;往往不会选择方案较为完整的SSAS&#xff0c;而是会选择轻量的 PowerBI 方案&#xff0c;究其根本还是软件成本的问题。 但是随着模型越来越臃肿&#xff0c;维护成本越来越高&#xff0c;有很多模型需要进…

Java面向对象-抽象类和抽象方法

Java面向对象-抽象类和抽象方法 1、代码案例展示2、抽象类和抽象方法的关系&#xff1a; 1、代码案例展示 1、在一个类中会有一类方法&#xff0c;无需重写&#xff0c;直接使用 2、在一个类中会有一类方法&#xff0c;会对这个方法进行重写 3、一个方法的方法体去掉&#xff…

【文心智能体分享】日记周报助手

引言 在繁忙的实习生活中&#xff0c;你是否曾为如何整理日常的工作日志、周报、月报而烦恼&#xff1f;现在&#xff0c;我们为你带来了一个全新的智能体——“日记周报助手”&#xff0c;它将成为你实习过程中的得力助手&#xff0c;帮你轻松整理实习日志&#xff0c;让你的…

mysql 中的锁

一.锁的介绍 锁是计算机协调多个进程或线程并发访问某一资源的机制&#xff0c;在数据库中&#xff0c;除了传统的计算资源&#xff08;cpu&#xff0c;ram&#xff0c;i/o&#xff09;的争用以外&#xff0c;数据也是一种供许多用户共享的资源。如何保证数据并发访问的一致性…