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;
    else
        return 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;
    else
        return 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 1
        hmc5883L_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);
    #endif
    
    
    g_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 __cplusplus
 extern "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        0x03

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

 读取数据的波形

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

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

相关文章

如何通过数据库与AI实现以图搜图?OceanBase向量功能详解

OceanBase支持向量数据库的基础能力 当前&#xff0c;数据库存储系统与人工智能技术的结合&#xff0c;可以体现在两个主要的应用方向上。 一、近似搜索。它利用大语言模型&#xff08;LLM&#xff0c;简称大模型&#xff09;的嵌入&#xff08;embedding&#xff09;技术&am…

如何低成本、高效搭建线上3D艺术展?

随着数字技术的日新月异&#xff0c;艺术展览领域正迎来一场革新。未来的艺术展览将不再是单一的线下体验&#xff0c;而是线上线下相互融合&#xff0c;其中&#xff0c;3D线上展览将成为线下展览的重要延伸与拓展&#xff0c;为广大观众提供更多元化的选择。 对于艺术家和策…

限流器设计思路(浅入门)

限流器(Rate Limiter)是一种用于控制系统资源利用率和质量的重要机制。它通过限制单位时间内可以执行的操作数量&#xff0c;从而防止系统过载和保护服务的可靠性。在程序设计中&#xff0c;可以使用多种方式来实现限流器&#xff0c;下面是几个常见方案的介绍&#xff1a; 令牌…

2024年,计算机相关专业还值得选择吗? 又该如何判断自己是否适合这类专业呢?

文章目录 一、2024年,计算机相关专业还值得选择吗?二、判断自己是否适合这类专业呢&#xff1f;三、哪所大学的计算机专业最好&#xff1f;四、计算机专业是否仍具有长远的发展潜力和就业前景呢? 一、2024年,计算机相关专业还值得选择吗? 在2024年选择大学专业时&#xff0…

开源完全自动化的桌上足球机器人Foosbar;自动编写和修复代码的AI小工具;开源工具,可本地运行,作为Perplexity AI的替代方案

✨ 1: Foosbar Foosbar是一款完全自动化的桌上足球机器人&#xff0c;能与人类玩家对战&#xff0c;具备防守、传球和射门能力。 Foosbar是一个完全自动化的桌上足球机器人&#xff0c;它实现了一侧由机器人控制&#xff0c;另一侧由人类玩家对战的游戏模式。这个机器人能够自…

【论文阅读】Activity Recognition using Cell Phone Accelerometers

Activity Recognition using Cell Phone Accelerometers 引用&#xff1a; Kwapisz J R, Weiss G M, Moore S A. Activity recognition using cell phone accelerometers[J]. ACM SigKDD Explorations Newsletter, 2011, 12(2): 74-82. 论文链接&#xff1a; Activity recogn…

基于JSP的贝儿米幼儿教育管理系统

开头语&#xff1a; 你好呀&#xff0c;我是计算机学长猫哥&#xff01;如果您对本系统感兴趣或者有相关需求&#xff0c;文末可以找到我的联系方式。 开发语言&#xff1a; Java 数据库&#xff1a; MySQL 技术&#xff1a; JSP技术 工具&#xff1a; IDEA/Eclipse、…

西南交通大学【操作系统实验7】

实验目的 &#xff08;1&#xff09;理解内存管理中缺页的概念。&#xff08;2&#xff09;综合运用实验1&#xff0c;实验5&#xff0c;实验6中/proc文件系统、内存管理、系统调用、 内核编译的知识。&#xff08;3&#xff09;掌握向/proc文件系统中增加文件的方法。&#…

人人必看:人工智能成熟后,被社会广泛使用后,可能被取代的行业有哪些,以及AI后新兴的行业和职位有哪些?

随着人工智能技术的不断成熟和广泛应用&#xff0c;许多行业和职位可能会受到影响&#xff0c;一些可能被取代&#xff0c;而另一些则会因为AI技术的引入而新兴。人人必看&#xff1a;人工智能成熟后&#xff0c;被社会广泛使用后&#xff0c;可能被取代的行业有哪些&#xff0…

高德地图AI革新:智能导航提升驾驶安全与个性化体验

AITOP100平台了解到&#xff0c;近期&#xff0c;高德地图的用户们在社交平台上分享了令人惊叹的体验&#xff0c;纷纷点赞并称之为“黑科技”。这源于高德地图推出的“车道级安全预警”功能&#xff0c;这一创新不仅适用于两轮和四轮车辆&#xff0c;也成为新老司机的出行必备…

Matlab使用Simulink仿真实现AM和BPSK信号的解调及误码率对比

前言 本篇实现了基于AM和BPSK调制的通信系统&#xff0c;采用Bernoulli Binary Generator生成随机二元序列&#xff0c;码元速率为0.5秒/个。AM调制使用Sine Wave模块生成载波&#xff0c;频率40Hz&#xff0c;相位π/2。BPSK调制通过Switch模块切换相位0和π的载波。信号传输…

乡村振兴的多元化产业发展:推动农村一二三产业融合发展,培育乡村新业态,打造多元化发展的美丽乡村

一、引言 乡村振兴是我国当前及未来一段时间内的重大战略任务&#xff0c;旨在促进农村经济的全面发展&#xff0c;提高农民的生活水平&#xff0c;实现城乡融合发展。在乡村振兴的进程中&#xff0c;推动农村一二三产业融合发展&#xff0c;培育乡村新业态&#xff0c;是打造…

绿色转型,节能攻坚

随着人口增长和经济发展&#xff0c;资源短缺和环境污染问题愈发严重&#xff0c;绿色转型和节能已成为我们共同的责任。为了推动环保事业的发展&#xff0c;阜阳善于善行志愿者团队&#xff0c;参与了本年度以“绿色转型&#xff0c;节能攻坚”为主题的全国节能宣传周活动。这…

echart盒子没有跟着当前div大小变化而自适应

一、问题描述 当echarts图表在一个盒子里的时候&#xff0c;盒子大小变化了&#xff0c;但是图表没有跟着自适应&#xff0c;比如这样&#xff0c;盒子变大了&#xff0c;但是图表没变化 二、解决方法 在盒子大小更改的同时&#xff0c;调用图表的resize方法&#xff0c;记…

海思Hi3519DV500方案1200万无人机吊舱套板

海思Hi3519DV500方案1200万无人机吊舱套板 Hi3519DV500 是一颗面向行业市场推出的超高清智能网络摄像头SoC。该芯片最高 支持四路sensor 输入&#xff0c;支持最高4K30fps 的ISP 图像处理能力&#xff0c;支持2F WDR、 多级降噪、六轴防抖、全景拼接、多光谱融合等多种传统图像…

FL Studio21永久免费破解中文版下载,让我这个音乐制作爱好者如获至宝!

FL Studio21永久免费破解中文版下载&#xff0c;让我这个音乐制作爱好者如获至宝&#xff01;&#x1f3b6; 这款软件功能强大&#xff0c;操作简单易上手。我可以轻松地创作出各种风格的音乐作品。无论是流行、摇滚还是电子音乐&#xff0c;都能轻松驾驭。&#x1f3a7; 使用F…

Java 基础语法

Java 基础语法 一个 Java 程序可以认为是一系列对象的集合&#xff0c;而这些对象通过调用彼此的方法来协同工作。下面简要介绍下类、对象、方法和实例变量的概念。 对象&#xff1a;对象是类的一个实例&#xff0c;有状态和行为。例如&#xff0c;一条狗是一个对象&#xff…

vue3中实现点击ctrl+enter换行,enter发送

效果 TS部分&#xff1a; <script lang"ts" setup> import { Promotion } from element-plus/icons-vue import { ref } from vue;const question ref() const keyDownCode ref(0)// 键盘按下事件处理函数 const keyDownEnter (e: any) > {console.log(…

AI魔法相机:实时3D重建与场景魔法化

一、产品概述 AI魔法相机是一款创新的硬件产品,它结合了AI技术和3D重建扫描技术,能够实时捕捉并重建3D场景和物理世界。用户只需通过简单的点击操作,即可捕捉现实物体或环境,并将其无缝融合到任何场景中,创造出全新的想象现实。 二、核心功能 实时捕捉:一键式操作,迅速…

CV每日论文--2024.6.6

1、Dealing with All-stage Missing Modality: Towards A Universal Model with Robust Reconstruction and Personalization 中文标题&#xff1a;处理全阶段缺失模态&#xff1a;迈向具有鲁棒重建和个性化的通用模型 简介&#xff1a;这篇论文提出了一种具有模态重建和模型个…