STM32外设系列—BH1750

文章目录

  • 一、BH1750简介
  • 二、BH1750原理图
  • 三、BH1750数据手册
    • 3.1 指令集
    • 3.2 IIC通信读/写
  • 四、BH1750程序设计
    • 4.1 IIC程序
    • 4.2 BH1750初始化程序
    • 4.3 读取BH1750测量结果
    • 4.4 获取光照强度
    • 4.5 相关宏定义
  • 五、应用实例
  • 六、拓展应用
    • 6.1 实时调节LED亮度
    • 6.2 实时调整颜色阈值

一、BH1750简介

BH1750是一款数字型光照强度传感器,能够获取周围环境的光照强度。其测量范围在0~65535 lx。lx勒克斯,是光照强度的单位。BH1750可用于调节手机屏幕和键盘的背光功率,或者用于智能灯光控制,比如,随着外界光照强度的变化调节灯光亮度。

BH1750

BH1750有以下特点

  • I2C总线接口
  • 接近视觉灵敏度的光谱灵敏度特性
  • 输出对应亮度的数字值
  • 高分辨率(0~65535 lx)
  • 通过降低功率功能,实现低电流化
  • 50Hz / 60Hz光噪声抑制功能
  • 可以选择两种类型的I2C从属地址
  • 最小误差变动在±20%
  • 受红外线影响很小

二、BH1750原理图

BH1750原理图

  • PD —— 接近人眼反应的光敏二极管
  • AMP —— 集成运算放大器(将 PD 电流转换为 PD 电压)
  • ADC —— 模数转换获取 16 位数字数据
  • Logic + IC Interface(逻辑+ IC 界面)
  • OSC —— 内部振荡器(该时钟为内部逻辑时钟,时钟频率典型值:320kHz)

PD二极管通过光伏效应将输入光信号转换成电信号,经运放电路放大后,电压经ADC采集,再经逻辑电路转换成16位二进制数,存储在内部的寄存器中(进入光窗的光越强,光电流越大,电压就越大,所以光强可以通过电压的大小判断,但是应该注意的是,虽然电压和光强一一对应,但它们不是成正比关系,所以该芯片内部是对数据进行了线性处理,这就是为什么直接使用集成IC而不是光电二极管的原因)。BH1750引出了时钟线和数据线,单片机可以通过I2C协议与BH1750进行通讯,可选择BH1750的工作模式,提取BH1750寄存器中的照度数据。

三、BH1750数据手册

3.1 指令集

BH1750的数据手册中给出了一些指令

BH1750指令集

其中的H分辨率模式和L分辨率模式等,是BH1750的测量模式,数据手册中也给出了说明

BH1750测量模式

我们通常使用H分辨率模式,H 分辨率模式下足够长的测量时间(积分时间)能够抑制一些噪声(包括 50Hz/60Hz)。同时,H 分辨率模式的分辨率在 1lx 下,适用于黑暗场合下(少于 10 lx)。

3.2 IIC通信读/写

上面介绍,BH1750有两种从属地址,由 ADDR 端口的电平决定。

  • ADDR=“H”( ADDR ≧ 0.7VCC ) →“1011100”
  • ADDR=“L”( ADDR ≦ 0.3VCC ) →“0100011”

关于IIC通信的详细内容,这里就不再介绍了,可以去本系列的OLED篇查看。BH1750数据手册中给出了一种配置连续高分辨率模式的方法

配置连续高分辨率模式方法步骤

BH1750数据读取格式如下

BH1750数据读取格式

光照强度(单位lx)=(High Byte + Low Byte)/ 1.2 * 测量精度

四、BH1750程序设计

4.1 IIC程序

相比于之前的OLED的IIC程序,增加了主设备发送应答信号(Ack),非应答信号(NAck),读取一个字节数据程序。修改了等待应答信号程序,增加了返回值。

/*
 *==============================================================================
 *函数名称:IIC_Delay
 *函数功能:IIC延时
 *输入参数:无
 *返回值:无
 *备  注:数据手册提供
 *==============================================================================
 */
void IIC_Delay (void)
{
	u8 t = 10;
	while (t--);
}
/*
 *==============================================================================
 *函数名称:I2C_Start
 *函数功能:IIC起始信号
 *输入参数:无
 *返回值:无
 *备  注:数据手册提供
 *==============================================================================
 */
void I2C_Start (void)
{
	BH1750_SDA_Set();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SDA_Clr();
	IIC_Delay();
	BH1750_SCL_Clr();
	IIC_Delay();
}
/*
 *==============================================================================
 *函数名称:I2C_Stop
 *函数功能:IIC终止信号
 *输入参数:无
 *返回值:无
 *备  注:数据手册提供
 *==============================================================================
 */
void I2C_Stop (void)
{
	BH1750_SDA_Clr();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SDA_Set();
}
/*
 *==============================================================================
 *函数名称:IIC_Ack
 *函数功能:CPU产生一个ACK信号
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
 */
void IIC_Ack (void)
{
	BH1750_SDA_Clr();
	IIC_Delay();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SCL_Clr();
	IIC_Delay();
	BH1750_SDA_Set();
}
/*
 *==============================================================================
 *函数名称:IIC_NAck
 *函数功能:CPU产生一个NACK信号
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
 */
void IIC_NAck (void)
{
	BH1750_SDA_Set();
	IIC_Delay();
	BH1750_SCL_Set();
	IIC_Delay();
	BH1750_SCL_Clr();
	IIC_Delay();	
}
/*
 *==============================================================================
 *函数名称:I2C_WaitAck
 *函数功能:IIC等待应答
 *输入参数:无
 *返回值:0:未收到应答信号;1:收到应答信号
 *备  注:无
 *==============================================================================
 */
u8 I2C_WaitAck (void)
{
	u8 re;

	BH1750_SDA_Set();
	IIC_Delay();
	BH1750_SCL_Set();
	IIC_Delay();
	if (BH1750_SDA_DATA())
	{
		re = 1;
	}
	else
	{
		re = 0;
	}
	
	BH1750_SCL_Clr();
	IIC_Delay();
	
	return re;
}
/*
 *==============================================================================
 *函数名称:Send_Byte
 *函数功能:写入一个字节
 *输入参数:dat:需要写入的数据
 *返回值:无
 *备  注:数据手册提供
 *==============================================================================
 */
void Send_Byte (u8 dat)
{
	u8 i;

	for (i = 0;i < 8;i ++)
	{
		// 发送数据时,从高位依次写入
		if (dat & 0x80)
		{
			BH1750_SDA_Set();
		}
		else
		{
			BH1750_SDA_Clr();
		}
		IIC_Delay();
		BH1750_SCL_Set();
		IIC_Delay();
		BH1750_SCL_Clr();
		
		// dat左移1位
		dat <<= 1;
	}
}
/*
 *==============================================================================
 *函数名称:IIC_Read_Byte
 *函数功能:IIC读取一个字节数据
 *输入参数:无
 *返回值:无
 *备  注:读取到的一个字节数据
 *==============================================================================
 */
u8 IIC_Read_Byte (void)
{
	u8 i;
	u8 value;
	
	// 高位在前
	value = 0;
	
	// 循环读取8bit数据
	for (i = 0; i < 8; i ++)
	{
		value <<= 1;   // 循环左移一位
		
		BH1750_SCL_Set();
		IIC_Delay();
		
		// 如果是“1”
		if (BH1750_SDA_DATA())
		{
			value ++;
		}
		
		BH1750_SCL_Clr();
		IIC_Delay();
	}
	
	return value;
}
//BH1750写一个字节
//返回值	成功:0		失败:非0 
/*
 *==============================================================================
 *函数名称:BH1750_Byte_Write
 *函数功能:BH1750写一个字节
 *输入参数:data:要写入的数据
 *返回值:0:写入成功;1/2:写入失败
 *备  注:无
 *==============================================================================
 */
u8 BH1750_Byte_Write (u8 data)
{
	I2C_Start();
	
	// 发送从设备地址,0:写
	Send_Byte (BH1750_Addr | 0);
	
	// 收到应答信号
	if(I2C_WaitAck() == 1)
	{
		return 1;
	}
	//发送控制命令
	Send_Byte(data);
	
	// 收到应答信号
	if(I2C_WaitAck() == 1)
	{
		return 2;
	}
	
	I2C_Stop();
	
	return 0;
}

4.2 BH1750初始化程序

初始化包括两部分,一部分是初始化IIC引脚,另一部分是初始化BH1750。也就是给BH1750上电,并复位。

/*
 *==============================================================================
 *函数名称:Drv_Bh1750_Init
 *函数功能:初始化BH1750
 *输入参数:无
 *返回值:无
 *备  注:无
 *==============================================================================
 */
void Drv_Bh1750_Init (void)
{
	// 结构体定义
 	GPIO_InitTypeDef  GPIO_InitStructure;
	
	// 开启时钟
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
	
	// 初始化GPIO结构体
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;	 
 	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;   // 推挽式输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
 	GPIO_Init(GPIOB, &GPIO_InitStructure);
	// 全部拉高,IIC处于空闲状态
 	GPIO_SetBits(GPIOB,GPIO_Pin_6 | GPIO_Pin_7);
	
	// BH1750上电
	BH1750_Byte_Write(POWER_ON);
	
	// 复位BH1750
	BH1750_Byte_Write(MODULE_RESET);
}

4.3 读取BH1750测量结果

BH1750返回两字节的测量结果数据

/*
 *==============================================================================
 *函数名称:Drv_Bh1750_Read_Measure
 *函数功能:读取BH1750测量数据
 *输入参数:无
 *返回值:0:读取失败;其他:光照强度
 *备  注:无
 *==============================================================================
 */
u16 Drv_Bh1750_Read_Measure (void)
{
	u16 receData = 0;
	
	I2C_Start();
	
	// 发送从设备地址,1:读
	Send_Byte(BH1750_Addr | 1);
	
	if(I2C_WaitAck() == 1)
	{
		return 0;
	}
	
	// 读取高八位
	receData = IIC_Read_Byte();
	IIC_Ack();
	
	// 读取低八位
	receData = (receData << 8) + IIC_Read_Byte();
	IIC_NAck();
	I2C_Stop();
	
	return receData;   // 返回读取到的数据
}

4.4 获取光照强度

/*
 *==============================================================================
 *函数名称:Med_Bh1750_GetLightIntensity
 *函数功能:获取光照强度
 *输入参数:无
 *返回值:光照强度
 *备  注:分辨率	光照强度(单位lx)=(High Byte  + Low Byte)/ 1.2 * 测量精度
 *==============================================================================
 */
float Med_Bh1750_GetLightIntensity (void)
{
	return (float)(Drv_Bh1750_Read_Measure() / 1.1f * Resolurtion);   //返回测量光照强度
}

4.5 相关宏定义

// BH1750的地址(ADDR=“H”)
#define BH1750_Addr   0x46

// BH1750指令
#define POWER_OFF					0x00
#define POWER_ON					0x01
#define MODULE_RESET			0x07
#define	CONTINUE_H_MODE		0x10
#define CONTINUE_H_MODE2	0x11
#define CONTINUE_L_MODE		0x13
#define ONE_TIME_H_MODE		0x20
#define ONE_TIME_H_MODE2	0x21
#define ONE_TIME_L_MODE		0x23

//测量模式
#define Measure_Mode   CONTINUE_H_MODE

//分辨率	光照强度(单位lx)=(High Byte  + Low Byte)/ 1.2 * 测量精度
#if ((Measure_Mode == CONTINUE_H_MODE2)|(Measure_Mode == ONE_TIME_H_MODE2))
	#define Resolurtion		0.5
#elif ((Measure_Mode == CONTINUE_H_MODE)|(Measure_Mode == ONE_TIME_H_MODE))
	#define Resolurtion		1
#elif ((Measure_Mode == CONTINUE_L_MODE)|(Measure_Mode == ONE_TIME_L_MODE))
	#define Resolurtion		4
#endif

// SCL
#define BH1750_SCL_Clr()   GPIO_ResetBits(GPIOB,GPIO_Pin_6)
#define BH1750_SCL_Set()   GPIO_SetBits(GPIOB,GPIO_Pin_6)
// SDA
#define BH1750_SDA_Clr()   GPIO_ResetBits(GPIOB,GPIO_Pin_7)
#define BH1750_SDA_Set()   GPIO_SetBits(GPIOB,GPIO_Pin_7)

// 读取SDA电平
#define BH1750_SDA_DATA()   GPIO_ReadInputDataBit(GPIOB,GPIO_Pin_7)

五、应用实例

使用串口打印光照强度,main函数如下

float gLingtIntensity = 0;

int main(void)
{
	Med_Mcu_Iint();   // 系统初始化
	
	while(1)
  {
		gLingtIntensity = Med_Bh1750_GetLightIntensity();   // 获取光照强度
		printf ("Light:%.1f lx",gLingtIntensity);   // 串口打印光照强度
		
		delay_ms(500);   //延时500ms = 0.5s
	}
}

六、拓展应用

利用BH1750获取到的周围环境光强可用于许多方面,这里举几个例子,比如设计一个教室灯光控制系统,根据实际环境光强来调节灯光亮度,使室内环境光强保持在一个稳定的值。另外,比如做颜色识别时,周围环境的光照强度不同,识别的效果也不同。可以利用BH1750实时监测周围环境光照强度变化,不同的光照强度下,切换不同的颜色阈值,可以改善颜色识别的效果。这里简单介绍一下实现思路。

6.1 实时调节LED亮度

可以用PWM来控制LED的亮度。根据周围环境的光照强度的变化,实时调节PWM的占空比,达到LED亮度根据周围环境光照强度变化而变化的效果。但是需要注意光照强度与占空比的换算关系。

6.2 实时调整颜色阈值

比如使用Open MV做颜色是别时,在不同光照强度下,同一种颜色的颜色阈值不同,可以根据不同的光照强度,匹配不同的颜色阈值。

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

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

相关文章

C++【位图/布隆过滤器—海量数据处理】

文章目录 一、位图&#xff08;1&#xff09;位图概念介绍&#xff08;2&#xff09;简单模拟实现&#xff08;3&#xff09;位图应用 二、布隆过滤器&#xff08;1&#xff09;关于布隆过滤器概念及介绍&#xff08;2&#xff09;布隆过滤器的使用场景&#xff08;3&#xff0…

【前端布局篇】浮动、定位、弹性布局,固比固、双飞翼、圣杯布局

一、布局方式介绍 布局模型是基于盒模型基础上进行的拓展&#xff0c;关于布局有流式布局&#xff08;标准的布局&#xff09;&#xff0c;浮动布局、定位布局、flex布局等。 1.1 标准流&#xff08;流动模型&#xff09; 描述&#xff1a;元素按照自己默认的元素类型在页面…

Unity3D 连接MySQL数据库

1、MySQL下载安装运行 详见&#xff1a;MySQL下载安装运行 2、使用mysql-connector-net &#xff08;1&#xff09;官方下载地址&#xff1a;https://downloads.mysql.com/archives/c-net/&#xff0c;下载后直接双击安装即可。 提示&#xff1a;不要使用版本过高的connect…

Jmeter(三) - 从入门到精通 - 测试计划(Test Plan)的元件(详解教程)

1.简介 上一篇中我已经教你如何通过JMeter来创建一个测试计划&#xff08;Test Plan&#xff09;&#xff0c;那么这一篇我们就将JMeter启动起来&#xff0c;创建一个测试计划&#xff08;Test plan&#xff09;&#xff0c;然后现在给大家介绍一下测试计划&#xff08;Test P…

C# wpf 附加属性实现任意控件拖动调整大小

摘自这里 https://blog.csdn.net/u013113678/article/details/121719278 调试效果如下 using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using Syst…

【信号】信号处理与进程通信:快速上手

目录 0. 信号概述 1. 产生信号的方式&#xff1a; 1.1 当用户按某些终端键时&#xff0c;将产生信号。 1.2 硬件异常将产生信号。 1.3 软件异常将产生信号。 1.4 调用kill函数将发送信号。 1.5 运行kill命令将发送信号。 2. 信号的默认&#xff08;缺省&#xff09;处理…

Visual C++类的继承及类中成员的访问特性——搞懂public、protected、private

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天来说说Visual C中类的继承及类中成员的访问特性&#xff0c;也就是来搞懂public、protected、private这三个东西。 很多人搞不清楚这三个东西&#xff0c;并且很容易弄错&#xff0c;其实不是学习的人的…

ModaHub魔搭社区:向量数据库MIlvus服务端配置(三)

目录 gpu 区域 logs 区域 metric_config 区域 gpu 区域 在该区域选择是否在 Milvus 里启用 GPU 用于搜索和索引创建。同时使用 CPU 和 GPU 可以达到资源的最优利用&#xff0c;在特别大的数据集里做搜索时性能更佳。 若要切换到 CPU-only 模式&#xff0c;只要将 enable 设…

【VMD-LSTM】变分模态分解-长短时记忆神经网络研究(Python代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

数据库大题

(计算题&#xff0c;20分) 设有两个关系R和S,求① R ∪ S R \cup S R∪S;② R − S R - S R−S;③ R S R \times S RS;④ ∏ C , A ( R ) \prod_{C,A}(R) ∏C,A​(R);⑤ σ B > ′ 4 ′ ( R ) \sigma_{B>4}(R) σB>′4′​(R) 关系R关系S (简答题&#xff0c;10…

基于深度学习FasterRCNN模型Restnet50 的生活垃圾智能分类(准确率达84%)-含python工程全源码

目录 前言总体设计系统整体结构图系统流程图 运行环境1. 硬件环境2. Python 环境 模块实现1. 数据预处理2. 数据加载3. 模型构建4. 模型训练及保存5. 模型加载与调用 系统测试1. 模型准确率2. 分类别准确率 工程源代码下载其它资料下载 前言 本项目基于Faster R-CNN模型&#…

jenkins流水线Pipeline的使用

pipeline流水线 1、jenkins安装pipeline插件 2、创建流水线项目 1、创建pipeline的流水线项目 2、编写流水线 pipeline {agent anystages {stage(拉去代码) {steps {git credentialsId: gitee, url: https://gitee.com/xwb1056481167/jenkins-demo.gitecho 拉去代码}}stage(m…

Vue中如何进行数据导入与Excel导入

Vue中如何进行数据导入与Excel导入 Vue是一款非常流行的JavaScript框架&#xff0c;它提供了一套用于构建用户界面的工具和库。在Vue中&#xff0c;我们可以使用多种方式来导入数据&#xff0c;包括从服务器获取数据、从本地存储获取数据、从文件中读取数据等等。其中&#xf…

NVIDIA Jetson TX1,TX2,TX2 NX,AGX Xavier 和 Nano开发板GPIO口配置及应用

NVIDIA Jetson TX1&#xff0c;TX2&#xff0c;TX2 NX&#xff0c;AGX Xavier 和 Nano开发板GPIO口配置及应用 简介 ​ Jetson TX1、TX2、TX2 NX、AGX Xavier和Nano开发板都配备了一个包含40个引脚的GPIO接头&#xff0c;这些引脚可以用于数字输入输出。如下图 ​ 类似于Rasp…

Solid Converter PDF v10 安装及使用教程

目录 一、软件介绍二、下载教程三、安装教程四、使用教程1.PDF转Word、Html等2.合并PDF文件 一、软件介绍 Solid Converter PDF是一套专门将PDF文件转换成Word的软件。 能够将PDF转换为Word、Excel、HTML、PowerPoint、纯文本文件从PDF文档中提取数据并以CSV等格式保存能够转…

【人工智能】— 深度神经网络、卷积神经网络(CNN)、多卷积核、全连接、池化

【人工智能】— 深度神经网络、卷积神经网络&#xff08;CNN&#xff09;、多卷积核、全连接、池化 深度神经网络训练训练深度神经网络参数共享 卷积神经网络&#xff08;CNN&#xff09;卷积多卷积核卷积全连接最大池化卷积池化拉平向量激活函数优化小结 深度神经网络训练 Pr…

Pytest+selenium+allure+Jenkins自动化测试框架搭建及使用

一、 环境搭建 1. Python下载及安装 Python可应用于多平台包括windows, Linux 和 Mac OS X, 本文主要介绍windows环境下。你可以通过终端窗口输入 "python" 命令来查看本地是否已经安装Python以及Python的安装版本。 如未安装python, 推荐下载python 3.8.3以…

Prompt的技巧持续总结

Prompt 有很多网站已经收录了&#xff0c;比如&#xff1a;aimappro 有些直接抄上述网站的作业即可&#xff0c;不过也来看看&#xff0c; 有一些日常提问大概的咒语该怎么写。 1 三种微调下的提示写法 chatgpt时代的创新&#xff1a;LLM的应用模式比较 实际案例说明AI时代大…

将win上的文件传输到Ubuntu虚拟机

首先获取Ubuntu系统的ip地址&#xff0c;在Ubuntu的Terminal中输入ifconfig&#xff0c;可以看到Ubuntu的ip地址 可以看到我电脑的ip地址是10.0.2.15。更改虚拟机的网络连接 这里以VirtualBox为例&#xff0c;打开VirtualBox设置&#xff0c;选择网络&#xff0c;将连接方式改…

通付盾入围《2023年度中国数字安全能力图谱(行业版)》

近日&#xff0c;数世咨询发布《2023年度中国数字安全能力图谱&#xff08;行业版&#xff09;》。通付盾作为以分布式数字身份和大数据决策智能技术为核心的数字化高端软件与服务提供商&#xff0c;凭借在数字安全领域的实力和影响力&#xff0c;入选政府、互联网两大行业细分…