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

news2024/11/17 20:37:49

目录

概述

1 STM32Cube控制配置I2C

1.1 I2C参数配置

1.2 使用STM32Cube产生工程

2 HAL库函数介绍

2.1 初始化函数

2.2 写数据函数

2.3 读数据函数

3 光照传感器BH1750

3.1 认识BH1750

3.2 BH1750寄存器

3.3 采集数据流程

4 BH1750驱动实现

4.1 接口函数实现

4.2 完整驱动代码

5 测试

6 逻辑分析仪捕捉波形


测试代码下载地址:

https://gitee.com/mftang/stm32_open_test_proj/tree/master/stm32_f407_proj


 

概述

本文主要介绍STM32F4的内部I2C接口的使用方法,包括使用STM32Cube配置i2c接口函数,还介绍了STM32 HAL库中的接口函数,为了验证接口函数的是否能够正常工作,还使用bh1750作为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_Master_Transmit(  I2C_HandleTypeDef *hi2c, 
                                            uint16_t DevAddress, 
                                            uint8_t *pData, 
                                            uint16_t Size, 
                                            uint32_t Timeout)

参数介绍:

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

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

pData:            写数据指针

Size:               写数据大小

Timeout:         写数据超时时间

 2.3 读数据函数

函数原型:

HAL_StatusTypeDef HAL_I2C_Master_Receive( I2C_HandleTypeDef *hi2c, 
                                          uint16_t DevAddress, 
                                          uint8_t *pData, 
                                          uint16_t Size, 
                                          uint32_t Timeout)

参数介绍:

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

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

pData:            读数据指针

Size:               读数据大小

Timeout:         读数据超时时间

3 光照传感器BH1750

3.1 认识BH1750

 光照传感器BH1750是一种高性能数字光照传感器。它采用I2C总线通信接口,可测量环境中的光照强度,并输出数字信号。BH1750传感器具有高分辨率、高灵敏度和宽动态范围的特点,能够适应不同亮度条件下的测量需求。

BH1750传感器具有两种工作模式:连续测量模式和单次测量模式。在连续测量模式下,传感器会以设定的时间间隔进行光照强度的测量,并将结果输出。而在单次测量模式下,传感器进行一次测量后便停止,并将结果输出。用户可以根据实际需求选择适合的工作模式。

BH1750传感器还具有灵敏度调节功能,可以根据环境的亮度调整传感器的灵敏度,以确保测量结果的准确性。

光照传感器BH1750广泛应用于室内照明控制、户外光照强度监测、智能电子设备的自适应亮度调节等领域。它能够帮助节能减排、提升用户体验、增加设备智能化程度。

3.2 BH1750寄存器

3.3 采集数据流程

4 BH1750驱动实现

4.1 接口函数实现

1)写寄存器函数

代码第26行: 调用master发送数据至slave函数

2)读寄存器函数

代码第37行: 调用master读数据函数

 3)修改模式函数

4)设置精度函数

4.2 完整驱动代码

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

/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name            : bh1750.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 "bh1750.h"

static uint8_t s_MTReg;    /* 灵敏度倍率 */
static uint8_t s_Mode;     /* 测量模式 */

static uint8_t bh1750_WeReg(  uint8_t *pData, uint16_t Size )
{
    HAL_StatusTypeDef status;
    
    status = HAL_I2C_Master_Transmit( &hi2c2, BH1750_SLAVE_ADDRESS, pData, Size, 1000);
    if( status == HAL_OK)
        return BH1750_OK;
    else
        return BH1750_ERROR; 
}

static uint8_t bh1750_RdReg( uint8_t *pData, uint16_t Size )
{
    HAL_StatusTypeDef status;
    
    status = HAL_I2C_Master_Receive( &hi2c2, BH1750_SLAVE_ADDRESS, pData, Size, 1000);
    if( status == HAL_OK)
        return BH1750_OK;
    else
        return BH1750_ERROR; 
}

void BH1750_ChageMode(uint8_t _ucMode)
{
    uint8_t cmd;
    
    if (_ucMode == 1)           /* 连续高分测量模式1 */
    {
        cmd = BHOP_CON_H_RES;
        bh1750_WeReg(&cmd, 1);    
        s_Mode = 1;             /* 测量模式1,分辨率 1 lux*/
    }
    else if (_ucMode == 2)      /* 连续高分测量模式2 */
    {
        cmd = BHOP_CON_H_RES2;
        bh1750_WeReg(&cmd, 1);  
        s_Mode = 2;             /* 测量模式2, 分辨率 0.5 lux */        
    }
    else if (_ucMode == 3)     /* 连续低分测量模式 */
    {
        cmd = BHOP_CON_L_RES;
        bh1750_WeReg(&cmd, 1);
        s_Mode = 3;            /* 测量模式3,低分辨率 4 lux*/        
    }
}

void BH1750_AdjustSensitivity(uint8_t _ucMTReg)
{
    uint8_t cmd;
    
    if (_ucMTReg <= 31)
    {
        _ucMTReg = 31;
    }
    else if (_ucMTReg >= 254)
    {
        _ucMTReg = 254;
    }
    
    s_MTReg = _ucMTReg;
    
    cmd = 0x40 + (s_MTReg >> 5);
    bh1750_WeReg(&cmd,1);            /* 更改高3bit */
    
    cmd = 0x60 + (s_MTReg & 0x1F);
    bh1750_WeReg(&cmd,1);            /* 更改低5bit */
    
    /* 更改量程范围后,需要重新发送命令设置测量模式 */
    BH1750_ChageMode(s_Mode);
}

uint16_t BH1750_ReadData(void)
{
    uint8_t buff[2];

    bh1750_RdReg( buff, 2);
    return (buff[0] << 8) + buff[1];
}

float BH1750_GetLux(void)
{
    uint16_t usLight;
    float lux;
    
    usLight = BH1750_ReadData();
    
    /* 
       计算光强度 = 16位寄存器值 / 1.2  * (69 / X) 
    */
    lux = (float)(usLight * 5 * 69) / (6 * s_MTReg);
    
    if (s_Mode == 2)    /* 高分辨率测量模式2 */
    {
        lux = lux / 2;
    }
    
    return lux;
}

void bh1750_test( void )
{
    uint8_t cmd;
    float fLux;
    
    cmd = BHOP_POWER_ON;            /* 芯片上电 */
    bh1750_WeReg(&cmd, 1); 
    
    BH1750_ChageMode(2);             /* 高分辨率连续测量 */

    BH1750_AdjustSensitivity(69);    /* 芯片缺省灵敏度倍率 = 69 */

    while(1)
    {
        fLux = BH1750_GetLux();
        printf("Ambient Light = %6.2f lux  \r",fLux);
        HAL_Delay(100);
    }
}



/* End of this file */

2)创建bh1750.h文件,编写如下代码:

/* USER CODE BEGIN Header */
/**
  ******************************************************************************
  * File Name          : bh1750.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 __BH1750_H
#define __BH1750_H

#ifdef __cplusplus
 extern "C" {
#endif

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

#define BH1750_OK                1
#define BH1750_ERROR             0


#define bsp_DelayMS             HAL_Delay
#define BH1750_SLAVE_ADDRESS    0x46        /* I2C从机地址 */

/* 操作码 Opercode 定义 */
enum
{
    BHOP_POWER_DOWN = 0x00,        /* 进入掉电模式。芯片上电后缺省就是PowerDown模式 */
    BHOP_POWER_ON   = 0x01,        /* 上电,等待测量命令 */
    BHOP_RESET      = 0x07,        /* 清零数据寄存器 (Power Down 模式无效) */
    BHOP_CON_H_RES  = 0x10,        /* 连续高分辨率测量模式  (测量时间 120ms) (最大 180ms)*/
    BHOP_CON_H_RES2 = 0x11,        /* 连续高分辨率测量模式2 (测量时间 120ms)*/
    BHOP_CON_L_RES  = 0x13,        /* 连续低分辨率测量模式 (测量时间 16ms)*/

    BHOP_ONE_H_RES  = 0x20,        /* 单次高分辨率测量模式 , 之后自动进入Power Down */
    BHOP_ONE_H_RES2 = 0x21,        /* 单次高分辨率测量模式2 , 之后自动进入Power Down  */
    BHOP_ONE_L_RES  = 0x23,        /* 单次低分辨率测量模式 , 之后自动进入Power Down  */
};

void bh1750_test( void );

#ifdef __cplusplus
}
#endif

#endif /*__BH1750_H */

5 测试

1)编写测试代码

void bh1750_test( void )
{
    uint8_t cmd;
    float fLux;
    
    cmd = BHOP_POWER_ON;            /* 芯片上电 */
    bh1750_WeReg(&cmd, 1); 
    
    BH1750_ChageMode(2);             /* 高分辨率连续测量 */

    BH1750_AdjustSensitivity(69);    /* 芯片缺省灵敏度倍率 = 69 */

    while(1)
    {
        fLux = BH1750_GetLux();
        printf("Ambient Light = %6.2f lux  \r",fLux);
        HAL_Delay(100);
    }
}

2)编译代码,下载到板卡中,运行代码得到结果如下:

6 逻辑分析仪捕捉波形

 1)读取lux值

2) 配置参数函数

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

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

相关文章

又有人叫嚣:AI取代前端,来给你几张图,看能不能憋死AI。

总有自媒体人&#xff0c;为了些许流量&#xff0c;在大放厥词&#xff0c;说截个图给AI&#xff0c;AI就能输出前端代码&#xff0c;这是啥都敢说&#xff0c;吹牛不上税。 我来给你几张贝格前端工场日常接的大数据项目相关的图&#xff0c;你让AI生成代码&#xff0c;取代前…

WordPress安装插件失败No working transports found

1. 背景&#xff08;Situation&#xff09; WordPress 社区有非常多的主题和插件&#xff0c;大部分人用 WordPress 都是为了这些免费好用的主题和插件。但是今天安装完 WordPress 后安装插件时出现了错误提示&#xff1a;“ 安装失败&#xff1a;下载失败。 No working trans…

WPF之打印与预览

目录 1&#xff0c;打印设置与管理。 1.1&#xff0c;引入程序集&#xff1a; 1.2&#xff0c;主要管理类介绍&#xff1a; 1.3&#xff0c;应用&#xff1a; 1.4&#xff0c;效果。 1.5&#xff0c;Demo链接。 2&#xff0c;打印。 2.1&#xff0c;主要参与打印的类与…

【C++】<知识点> 标准和文件的输入输出

目录 一、输入输出操作 1. 相关的类 2. 标准流对象 3. istream类的成员函数 二、流操纵算子 1. 整数流的基数 2. 浮点数精度的流操纵算子 3. 域宽的流操纵算子 4. 其他的流操纵算子 5. 用户自定义流操纵算子 三、文件读写 1. 文本文件的读写 2. 二进制文件的读写 3. 文件读写…

港湾周评|京东图书遭抵制不赢不输

《港湾商业观察》李镭 临近618前夕&#xff0c;数十家出版社抵制京东的消息引发全民关注。一定程上&#xff0c;本就生意冷门或不太赚钱的图书市场&#xff0c;随着这次群起抵制行动&#xff0c;更像是一场行业的反击。 不过&#xff0c;平台有平台的销售策略&#xff0c;毕竟…

给uniapp的扩展组件uni-file-picker设置默认显示的图片

官方给出的代码如下所示&#xff0c;但是按照官网给出的代码图片并没有显示出来。 <template><uni-file-picker readonly :value"fileLists" :imageStyles"imageStyles" file-mediatype"image"></uni-file-picker> </temp…

C#基础一

使用Visual Studio 2022&#xff08;VS2022&#xff09;编写C#控制台程序 1. 安装Visual Studio 2022 确保已安装Visual Studio 2022。如果未安装&#xff0c;请从Visual Studio官网下载并安装。 另一篇文章中已经有详细描述&#xff0c;这里就不在细说了。 VisualStudio2022…

文件自动同步备份-FreeFileSync工具解决硬盘损坏、误操作覆盖导致数据丢失

文件自动同步备份-FreeFileSync工具解决硬盘损坏、误操作覆盖导致数据丢失 文章目录 文件自动同步备份-FreeFileSync工具解决硬盘损坏、误操作覆盖导致数据丢失前言一、FreeFileSync二、使用方法1.用外部存储卡或盘作为异地备份目标盘2.设置同步策略3.设置为windows的自动计划 …

CentOS上升级glibc2.17至glibc2.31

glibc是Linux系统中的重要组件之一。在CentOS中&#xff0c;glibc通常是作为系统的默认C标准库使用的&#xff0c;因为它是许多软件的基础库。在CentOS中&#xff0c;glibc的版本通常与CentOS版本一起发布。因为CentOS通常会优先选择稳定性而不是最新性&#xff0c;所以CentOS使…

前端 CSS 经典:图片边框

前言&#xff1a;有这么一个业务&#xff0c;需要边框随着图片宽度的变化而变化&#xff0c;比如一些聊天的气泡框等。 实现原理&#xff1a;使用 border-image 属性 效果图&#xff1a; 实现代码&#xff1a; <!DOCTYPE html> <html lang"en"><he…

java抽象类,接口,枚举练习题

第一题&#xff1a; 答案&#xff1a; class Animal{//成员变量protected String name;protected int weight;//构造方法public Animal(){this.name"refer";this.weight50;}public Animal(String name,int weight){this.namename;this.weightweight;}//成员方法publ…

基于Android Studio记事本系统

目录 项目介绍 图片展示 运行环境 获取方式 项目介绍 具有登录&#xff0c;注册&#xff0c;记住密码&#xff0c;自动登录的功能&#xff1b; 可以新增记事本&#xff0c;编辑&#xff0c;删除记事本信息&#xff0c;同时可以设置主标题&#xff0c;内容&#xff0c;以及…

【网络】为什么udp协议报头有长度字段,而tcp没有

引言&#xff1a; 在网络通信中&#xff0c;UDP&#xff08;用户数据报协议&#xff09;和TCP&#xff08;传输控制协议&#xff09;是两种常用的传输层协议。它们在设计和功能上有一些不同之处&#xff0c;其中之一就是报头中的长度字段。本文将深入探讨UDP和TCP协议中长度字…

LLM——探索大语言模型在心理学方面的应用研究

1. 概述 心理学经历了多次理论变革&#xff0c;目前人工智能&#xff08;AI&#xff09;和机器学习&#xff0c;特别是大型语言模型&#xff08;LLMs&#xff09;的使用&#xff0c;预示着新研究方向的开启。本文详细探讨了像ChatGPT这样的LLMs如何转变心理学研究。它讨论了LL…

LangChain笔记

很好的LLM知识博客&#xff1a; https://lilianweng.github.io/posts/2023-06-23-agent/ LangChain的prompt hub: https://smith.langchain.com/hub 一. Q&A 1. Q&A os.environ["OPENAI_API_KEY"] “OpenAI的KEY” # 把openai-key放到环境变量里&…

元宇宙虚拟线上会议,可应用于哪些行业和领域?

随着科技的飞速进步和互联网的广泛普及&#xff0c;线上元宇宙会议以其独特的魅力和优势&#xff0c;逐渐崭露头角&#xff0c;积木易搭旗下的元宇宙数字营销平台——视创云展&#xff0c;为线上元宇宙会议提供了全方位的服务&#xff0c;不仅涵盖了场景搭建、数字人互动、在线…

超简单白话文机器学习 - 回归树树剪枝(含算法介绍,公式,源代码实现以及调包实现)

1. 回归树 1.1 算法介绍 大家看到这篇文章时想必已经对树这个概念已经有基础了&#xff0c;如果不是很了解的朋友可以看看笔者的这篇文章&#xff1a; 超简单白话文机器学习-决策树算法全解&#xff08;含算法介绍&#xff0c;公式&#xff0c;源代码实现以及调包实现&#x…

小程序checkbox改成圆形与radio样式保持一致

修改前 修改后 html: <view class"agreement"><checkbox value"{{ isAgreed }}" bind:tap"toggleCheckbox" /><text>我同意室外智能健身房 <text class"link" bind:tap"showUserProtocol">用户协…

【C++】继承(二)深入理解继承:派生类默认成员函数与友元、静态成员的奥秘

目录 派生类的默认成员函数①派生类的构造函数②派生类的拷贝构造函数③派生类的赋值构造④派生类的析构函数 继承与友元继承与静态成员 前言 我们在上一章讲解了: 继承三部曲&#xff0c;本篇基于上次的基础继续深入了解继承的相关知识&#xff0c;欢迎大家和我一起学习继承 派…

Python小游戏——打砖块

文章目录 打砖块游戏项目介绍及实现项目介绍环境配置代码设计思路代码设计详细过程 难点分析源代码代码效果 打砖块游戏项目介绍及实现 项目介绍 打砖块游戏是一款经典的街机游戏&#xff0c;通过控制挡板来反弹小球打碎屏幕上的砖块。该项目使用Python语言和Pygame库进行实现…