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

目录

概述

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) 配置参数函数

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

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

相关文章

质量评估门户:您AI内容的质量守护者

在当今这个内容饥渴和内容疯狂的世界里&#xff0c;AI驱动的内容创作既是一种流行趋势&#xff0c;有时也是一个改变游戏规则的存在。但强大的能力伴随着巨大的责任……即确保质量的责任。 想象一下&#xff1a;你拥有一个AI[和创意团队]&#xff0c;他们以闪电般的速度输出博…

前端SEO优化包括哪些方面?

前端SEO优化主要关注网站的用户体验和页面内容的呈现&#xff0c;以确保网站对搜索引擎友好并能吸引用户 首先&#xff0c;要注意页面结构&#xff0c;用对的HTML标签比如标题和段落&#xff0c;这样搜索引擎更容易理解你的网页是怎么组织的&#xff0c;同时&#xff0c;保持H…

深度学习——自己的训练集——测试模型(CNN)

测试模型 1.导入新图片名称2.加载新的图片3.加载图片4.使用模型进行预测5.获取最可能的类别6.显示图片和预测的标签名称7.图像加载失败输出 导入新的图像&#xff0c;显示图像和预测的类别标签。 1.导入新图片名称 new_image_path 456.jpg2.加载新的图片 new_image cv2.imr…

知攻善防应急响应靶机训练-Web2

前言&#xff1a; 本次应急响应靶机采用的是知攻善防实验室的Web-2应急响应靶机 靶机下载地址为&#xff1a; https://pan.quark.cn/s/4b6dffd0c51a 相关账户密码 用户:administrator 密码:Zgsfqq.com 解题过程&#xff1a; 一、攻击者的IP地址&#xff08;两个&#xff09;…

B站pink老师CSS学习(一)

文章目录 一、CSS基础选择器1.标签选择器2.类选择器3. id选择器4.通配符选择器 二、字体属性1.字体2.字体大小3.字体粗细4.文字样式5.复合属性 三、文本属性1.文本颜色2.对齐文本3.装饰文本4.文本缩进5.行间距 四、CSS引入方式1. 内部样式表2.行内样式表3.外部样式表 一、CSS基…

LangChain打造一个AI客服

最近在学习LangChain&#xff0c;langchain的第一个入门应用就是和ChatGPT结合形成的一个AI客服&#xff0c;本期文章就带大家一起认识下 LangChain LangChain是现在用得最多的AI框架&#xff0c;langchain在帮助如基于文档数据的回答、聊天机器人和代理这类的应用程序 langch…

重生之我要精通JAVA--第六周笔记

File 路径 相对路径 路径1&#xff1a;“a.txt” 路径2&#xff1a;“abc\\a.txt” 绝对路径 路径1&#xff1a;“c:\\a.txt” 路径2&#xff1a;“c:\\abc\\a.txt” File对象就表示一个路径&#xff0c;可以是文件的路径、也可以是文件夹的路径这个路径可以是存在的&…

make disclean V=1 分析

文章目录 make distclean步骤1&#xff1a;2090-2114行&#xff0c;执行依赖 clean步骤2&#xff1a;2120-2124行&#xff0c;执行依赖 $(mrproper-dirs)步骤3&#xff1a;2118-2129行&#xff0c;执行依赖 mrproper步骤4&#xff1a;2135-2142行&#xff0c;实现 distclean 编…

小阿轩yx-Shell 编程之循环语句与函数

小阿轩yx-Shell 编程之循环语句与函数 for 循环语句 可以很好地解决顺序编写异常烦琐、困难重重的全部代码 &#xff08;&#xff09;{}&#xff1a;里边写的都是命令 &#xff09;&#xff1a;不能嵌套 $&#xff08;&#xff09;&#xff1a;可以嵌套&#xff0c;适合更…

全球伦敦银收盘时间一致吗

跟伦敦金市场相似&#xff0c;伦敦银市场也是一个全球化的无形市场&#xff0c;无论来自世界上什么地方的投资者参与其中&#xff0c;都可以得到全天接近24个小时的连贯行情&#xff0c;只要精力足够&#xff0c;根本不用担心没有交易获利的机会。但由于交易平台始终有维护的需…

Linux:线程

文章目录 前言1. 线程概念1.1 什么是线程1.2 线程比进程更加轻量化1.3 虚拟地址到物理地址的转化物理内存的管理页表 1.4 线程的优点1.5 线程的缺点1.6 线程异常1.7 线程用途 2. 进程 vs 线程3. 线程控制3.1 线程创建3.2 线程退出3.3 线程等待3.4 分离线程3.5 线程取消 4. 线程…

磁盘问题——外部、动态,无法读取

今天&#xff0c;小编又遇到事了&#xff0c;给同事换个电脑&#xff0c;要把他原来的硬盘拆过去&#xff0c;一开始电脑都准备好了&#xff0c;就差拆他的硬盘了&#xff0c;结果装过去&#xff0c;问题来啦&#xff01;如下图所示&#xff1a; 这下可咋搞呢&#xff01;我先用…

专业145+总410+成电电子科技大学858信号与系统考研经验电子信息与通信工程,抗干扰,空天,资环,真题,大纲,参考书。

今年考研总分410,专业课858信号与系统145&#xff0c;顺利上岸成电&#xff0c;毕设已经搞得七七八八&#xff0c;就等毕业了&#xff0c;抽空整理回顾一下去年的复习&#xff0c;给群里的同学提供一些参加&#xff0c;少走弯路&#xff0c;对于整体复习的把握有个大概得规划。…

抽象类和接口(2)

1、接口 1、接口的概念 接口就是公共的行为规范标准&#xff0c;大家在实现时&#xff0c;只要符合规范标准&#xff0c;就可以通用。 在Java中&#xff0c;接口可以看成是&#xff1a;多个类的公共规范&#xff0c;是一种引用数据类型。 2、语法规则 接口的定义格式与定义…

Python考试练习题---day1

1.计算2的n次幂结果的后3位 获得用户输入的一个数字N&#xff0c;计算并输出2的N次幂结果的后3位。 【输出样例】-----因为2的10次方等于1024 输入10输出024 ninput() print(str(2**eval(n))[-3:]) 2.分割四位正整数 例1&#xff1a; 编写程序&#xff0c;提示用户从键盘…

2、python环境的安装-mac系统下

打开官网&#xff0c;downloads下边有macOS&#xff0c;点击&#xff1a; 选择最新版本&#xff0c;点击&#xff0c;进入下边的页面&#xff0c;一直往下滑&#xff0c;看到files中有个macOS的版本&#xff0c;点击下载 点击下载后是pkg的安装包&#xff0c;点击安装。 一步步…

350种类型、10W+量级的API,企业应该怎么管?

忽如一夜春风来&#xff0c;万物皆可API。 在互联网时代&#xff0c;API无处不在&#xff1a;企业对外开放的数据、服务和业务能力&#xff0c;以API的形式提供给合作方&#xff1b;企业内部应用与应用、App与App之间的通信&#xff0c;通过API进行&#xff1b;甚至应用内部的…

机器视觉HALCON:3.图像获取,运算,率噪,滤波(边缘),锐化

目录 图像获取生成单通道图像图像运算加法运算减法运算乘法运算除法 仿射变换图像平滑&#xff08;噪点处理&#xff09;高斯滤波均值滤波中值滤波多图像均值 边缘滤波索贝尔滤波凯尼滤波 图像锐化索贝尔锐化拉普拉斯锐化高通滤波锐化几种锐化方式对比 图像获取 用到的函数&…

液氮罐内部会污染吗

液氮罐是一种常见的存储液态氮的设备&#xff0c;广泛应用于科研、生物医药、食品冷冻等领域。但是&#xff0c;人们对于液氮罐内部是否会产生污染一直存在疑问。 我们来看液氮罐内部可能的污染源。液氮罐内部主要存在以下几种潜在的污染来源&#xff1a;气体污染、杂质污染、…

MySQL数据处理增删改

数据处理增删改DML 由于约束&#xff0c;以下操作都有可能执行失败&#xff08;后面讲约束&#xff09; 插入数据 INSERT 基础添加&#xff1a;VALUES 值的顺序必须和表中字段顺序相同 INSERT INTO class VALUES(1,王小,10); 向指定字段添加&#xff1a; 值的顺序和指定…