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);// 复位BH1750BH1750_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.hqwc.cn/news/4734.html

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

相关文章

【C#】云LIS检验医学信息系统源码

系统基于云计算为医院机构改善患者服务质量提供了强有力的支持&#xff0c;“以患者为核心”这一理念得到了充分实现&#xff0c;基于云计算的高效区域医疗信息服务&#xff0c;会为医疗行业带来跨时代的变革。 一、使用技术框架说明 开发语言&#xff1a;C# 6.0、JavaScript …

css 背景颜色级别高于背景图

<div class"bg-parent"> <img :src"employeeImg" class"bg-url" /> <div class"bg"> <el-icon class"plus-icon"> <Plus /> </el-icon> </div> </div> .bg-parent{ //父级…

Tomcat的概念及部署

文章目录 一.Tomcat的概述1.Tomcat介绍2.Tomcat 的主要特点 二.Tomcat的核心组件1.核心组件关系图2.核心组件的介绍2.1 Web容器2.2 servlet容器2.3 JSP容器2.4 Tomcat核心组件的请求方式&#xff08;交互方式&#xff09;2.4.1 Web容器2.4.2 JSP容器2.4.3 serverlet容器 2.5 To…

短视频矩阵-短视频seo源码开发搭建

开发场景&#xff1a;抖音seo&#xff0c;短视频seo&#xff0c;抖音矩阵&#xff0c;短视频矩阵源码开源 一、 短视频矩阵源码需要掌握以下技术&#xff1a; 1. 视频编码技术 短视频矩阵系统利用视频编码技术&#xff0c;将视频文件进行压缩和解压缩&#xff0c;实现了高质…

华为战略方法论:BLM模型之差距分析(限制版)

目录 说明 差距类型 1、业绩差距 2、机会差距 3、对标差距 专栏列表 个人简介 说明 今天就来谈谈 BLM 模型中的第一把钥匙&#xff0c;也就是差距分析。 从本质上来看。 BLM 模型中的差距与你在日常生活中听到或用到的差距在意义都是一样的。 不同之处就在于问题的复…

高级第二个月复习

1.route与router的区别 $route&#xff1a;获取路由信息 指当前路由实例跳转到的路由对象 包括&#xff1a; $route.path 字符串&#xff0c;等于当前路由对象的路径&#xff0c;会被解析为绝对路径&#xff0c;如/home/ews $route.name 当前路由的名字&#xff0c;如果没有使…

探索 Spring Boot 项目全过程

文章目录 &#x1f387;前言1.Spring Boot 所需环境2.Spring Boot 项目创建2.1 安装插件2.2 创建新项目2.3 项目属性配置2.4添加依赖2.4 修改项目名称2.5 添加框架支持2.6 目录介绍 3.判断Spring Boot 创建项目是否成功&#x1f386;总结 &#x1f387;前言 在 Java 这个圈子&…

基于Scrcpy的Android手机屏幕投影到电脑教程

基于Scrcpy的Android手机屏幕投影到电脑教程 文章目录 基于Scrcpy的Android手机屏幕投影到电脑教程一&#xff0c;前言二&#xff0c;具体步骤1.软件下载2.环境配置 三&#xff0c;基于Scrcpy的手机投屏教程1.基于Scrcpy的有线手机投屏2.无线投屏 一&#xff0c;前言 在执行某…

eclipse编辑器汉化;eclipse安装中文插件

eclipse IDE默认是英文环境&#xff0c;使用起来略微不便&#xff0c;汉化还是很有必要的&#xff1b;下面记录一下安装中文插件的过程: 文章目录 一、 选择安装包地址二、 在eclipse安装中文插件2.1 在线安装2.2 手动下载安装包2.3 导入到eclipse 三、汉化插件介绍 一、 选择安…

JAVA 正则表达式 及 案例

JAVA 正则表达式 及 案例 目录 JAVA 正则表达式 及 案例1.正则表达式Regex1.1 概述1.2 常见语法1.3 String提供了支持正则表达式的方法1.4 练习&#xff1a;测试输入身份证号 1.正则表达式Regex 1.1 概述 正确的字符串格式规则。 常用来判断用户输入的内容是否符合格式的要求…

【深度学习】6-1 卷积神经网络 - 卷积层

卷积神经网络(Convolutional Neural Network&#xff0c;CNN)。 CNN 被用于图像识别、语音识别等各种场合&#xff0c;在图像识别的比赛中&#xff0c;基于深度学习的方法几乎都以 CNN 为基础。 首先&#xff0c;来看一下 CNN 的网络结构&#xff0c;了解 CNN 的大致框架。CNN…

亚马逊实践 | 构建可持续发展的架构模型

可持续发展概念源于对系统性文明危机和世界问题的科学和社会意识形态研究。世界级的进步学术社群和政治精英在二十世纪末就认识到了这些问题的存在。他们将即将到来的二十一世纪视为充满不确定性、全球灾难进程逐步升级的时代。可持续发展对多个领域产生影响&#xff0c;目前已…