当前位置: 首页 > article >正文

BH1750光照传感器---附代码

目录

    • BH1750简介
    • BH1750指令集
    • BH1750工作流程

BH1750简介

VCC-->电源正;
ADDR-->地址端口;
GND-->电源负;
PA5-->SDA-->I2C数据线;
PA3-->SCL-->I2C时钟线;
DVI-->I2C端口参考电压;

BH1750一共有2个设备地址:
高电平–>0x5C(7bit地址),0xB8(8bit地址)
低电平–>0x23(7bit地址),0x46(8bit地址)
在这里插入图片描述

注:这个模块只适用于室内环境或者学习使用,户外场景下会超量程。
BH1750用的是模块,模块上已经有接上拉电阻了,因此STM32这边就不 需要再接了。
ADDR引脚默认有一个下拉电阻,因此不接地其实也没关系。

BH1750指令集

在初始化BH1750时,通过发送1个字节的指令即可配置BH1750的模式。
在这里插入图片描述
在这里插入图片描述
注:lx,光照强度的单位,勒克斯。
L分辨率模式采集时间短,但精度差,适用于采集光照变化大且变化非常快的场景;H分辨率模式采集时间长,但精度高,适用于光照变化速度不快的场景。
一次采集模式适用于采集间隔时间长或者需要省电的场景;连续采集模式适用于对设备节能没有要求的大多数场景。

BH1750工作流程

  • 第1步:给BH1750供电。
  • 第2步:BH1750上电后默认为断电模式(此断电模式不是说芯片没有电,而是芯片没有进入工作模式)。
  • 第3步:通过发送指令,把BH1750配置为通电模式(此时芯片进入工作模式)。
  • 第4步:发送测量指令。
  • 第5步:读取测量结果并转换成光照值。
#ifndef __BH1750_H
#define __BH1750_H
#include "stm32f10x.h"// 位带操作宏定义
#define BITBAND(addr, bitnum) ((addr & 0xF0000000) + 0x2000000 + ((addr & 0xFFFFF) << 5) + (bitnum << 2))
#define MEM_ADDR(addr)  *((volatile unsigned long  *)(addr))
#define BIT_ADDR(addr, bitnum)   MEM_ADDR(BITBAND(addr, bitnum))// GPIOA的ODR和IDR寄存器地址
#define GPIOA_ODR_ADDR    (GPIOA_BASE + 12) // GPIOB的输出数据寄存器地址,0x4001080C 
#define GPIOA_IDR_ADDR    (GPIOA_BASE + 8)  // GPIOB的输入数据寄存器地址,0x40010808// 定义PBout和PBin宏
#define PAout(n)   BIT_ADDR(GPIOA_ODR_ADDR, n)  //输出 
#define PAin(n)    BIT_ADDR(GPIOA_IDR_ADDR, n)  //输入 /************************************************************************/
// 配置GPIOA的第3个引脚为SCL,第5个引脚为SDA
#define I2C_SCL     PAout(3) // SCL
#define I2C_SDA     PAout(5) // SDA
#define READ_SDA    PAin(5)  // 读取SDA线状态#define SDA_IN()     { GPIOA->CRL &= 0XFF0FFFFF; GPIOA->CRL |= (uint32_t)8 << 20; } 
#define SDA_OUT()    { GPIOA->CRL &= 0XFF0FFFFF; GPIOA->CRL |= (uint32_t)3 << 20; } /************************************************************************/#define	BH1750_ADDR_GND_REG	    0x23	//ADDR引脚接低电平
#define	BH1750_ADDR_VCC_REG	    0x5C	//ADDR引脚接高电平#define	BH1750_ADDR_Write		0x46    //从机地址+最后写方向位
#define	BH1750_ADDR_Read 		0x47    //从机地址+最后读方向位#define BH1750_POWER_DOWN   	0x00	//关闭模块	
#define BH1750_POWER_ON			0x01	//打开模块等待测量指令
#define BH1750_RESET_REG		0x07	//重置数据寄存器值在PowerOn模式下有效#define BH1750_CON_H_RES_MODE	0x10	//连续高分辨率 单位1lx 测量时间120ms
#define BH1750_CON_H_RES_MODE2	0x11	//连续高分辨率模式2 单位0.5lx 测量时间120ms
#define BH1750_CON_L_RES_MODE	0x13	//连续低分辨率 单位4lx 测量时间16ms#define BH1750_ONE_H_RES_MODE	0x20	// 一次高分辨率 单位1lx 测量时间120ms
#define BH1750_ONE_H_RES_MODE2	0x21	// 一次高分辨率模式2 单位0.5lx 测量时间120ms
#define BH1750_ONE_L_RES_MODE	0x23	// 一次低分辨率 单位4lx 测量时间16ms     /*---测量后模块转到 PowerDown模式*//************************************************************************/void BH1750_Init(void);
void Single_Write_BH1750(unsigned char REG_Address);
void BH1750_WriteReg(uint8_t RegAddress);
uint16_t BH1750_ReadReg(void);/************************************************************************/void BH1750_I2C_Start(void); 						//发送I2C开始信号
void BH1750_I2C_Stop(void); 						//发送I2C停止信号
void BH1750_I2C_Ack(void);	   						//I2C发送ACK信号 
void BH1750_I2C_NAck(void);							//I2C不发送ACK信号
uint8_t BH1750_I2C_Wait_Ack(void);					//I2C等待ACK信号
void BH1750_I2C_Send_Byte(uint8_t Byte); 			//I2C发送一个字节
uint8_t BH1750_I2C_Receive_Byte(unsigned char ACK);	//I2C读取一个字节#endif
#include "stm32f10x.h"                  // Device header
#include "BH1750.h"
#include "Delay.h"/************************通信层***************************/
/*产生I2C起始信号*/
void BH1750_I2C_Start(void)
{SDA_OUT(); //SDA线输出I2C_SDA = 1;I2C_SCL = 1;Delay_us(4);I2C_SDA = 0; //START:当CLK为高时,DATA从高变低Delay_us(4);I2C_SCL = 0; //钳住I2C总线,准备发送或接收数据 
}/*产生I2C终止信号*/
void BH1750_I2C_Stop(void)
{SDA_OUT(); //SDA线输出I2C_SCL = 0;I2C_SDA = 0; //STOP:当CLK为高时,DATA从低变为高Delay_us(4);I2C_SCL = 1; I2C_SDA = 1; //发送I2C总线结束信号Delay_us(4);
}//产生ACK应答
void BH1750_I2C_Ack(void)
{I2C_SCL = 0;SDA_OUT();I2C_SDA = 0;Delay_us(2);I2C_SCL = 1;Delay_us(2);I2C_SCL = 0;
}//不产生ACK应答		    
void BH1750_I2C_NAck(void)
{I2C_SCL = 0;SDA_OUT();I2C_SDA = 1;Delay_us(2);I2C_SCL = 1;Delay_us(2);I2C_SCL = 0;
}/*等待应答信号到来*/
//返回值:1,接收应答失败
//        0,接收应答成功
uint8_t BH1750_I2C_Wait_Ack(void)
{uint8_t ucErrTime = 0;SDA_IN(); //SDA设置为输入I2C_SDA = 1; Delay_us(1); I2C_SCL = 1; Delay_us(1);while(READ_SDA){ucErrTime++;if(ucErrTime > 250){BH1750_I2C_Stop();return 1;}}I2C_SCL = 0;	   return 0; 
}/*I2C发送一个字节*/
//返回从机有无应答,1:有应答;0:无应答
void BH1750_I2C_Send_Byte(uint8_t Byte)
{SDA_OUT(); I2C_SCL = 0; //拉低时钟开始数据传输for(uint8_t i = 0; i < 8; i++){if((Byte & 0x80) >> 7)I2C_SDA = 1;	elseI2C_SDA = 0;		Byte<<=1;Delay_us(2);I2C_SCL = 1; //释放SCL,从机在SCL高电平期间读取SDADelay_us(2); I2C_SCL = 0; //拉低SCL,主机开始发送下一位数据Delay_us(2);		}
}/*I2C接收一个字节*/
//ACK=1时,发送ACK,ACK=0,发送nACK
uint8_t BH1750_I2C_Receive_Byte(unsigned char ACK)
{uint8_t i, Byte = 0x00;	SDA_IN();//SDA设置为输入	for(i = 0; i < 8; i++){I2C_SCL = 0; Delay_us(2);I2C_SCL = 1;Byte<<=1;if(READ_SDA)Byte++;Delay_us(1);		}if (!ACK)BH1750_I2C_NAck(); //发送nACKelseBH1750_I2C_Ack(); //发送ACK   return Byte;
}/************************应用层***************************/
/*BH1750寄存器写*/
void BH1750_WriteReg(uint8_t RegAddress)
{do{BH1750_I2C_Start();              			//I2C起始信号BH1750_I2C_Send_Byte(BH1750_ADDR_Write);    //发送器件地址}while(BH1750_I2C_Wait_Ack());          	//等待从机应答BH1750_I2C_Send_Byte(RegAddress);           //发送指令BH1750_I2C_Wait_Ack();                      //等待从机应答BH1750_I2C_Stop();                       	//I2C停止信号
}/*BH1750寄存器读*/
uint16_t BH1750_ReadReg(void)
{	uint16_t buf;	BH1750_I2C_Start();			 				//I2C起始信号BH1750_I2C_Send_Byte(BH1750_ADDR_Read);     //发送器件地址+读标志位BH1750_I2C_Wait_Ack();                      //等待从机应答buf = BH1750_I2C_Receive_Byte(1);           //读取数据buf = buf<<8;                       		//读取并保存高八位数据buf += 0x00ff & BH1750_I2C_Receive_Byte(0); //读取并保存低八位数据BH1750_I2C_Stop();                     		//发送停止信号 return buf; 
}void Single_Write_BH1750(unsigned char REG_Address)
{BH1750_I2C_Start();                  	//起始信号BH1750_I2C_Send_Byte(BH1750_ADDR_Write); //发送设备地址+写信号BH1750_I2C_Send_Byte(REG_Address);   	//内部寄存器地址,BH1750_I2C_Stop();                 		//发送停止信号
}/*BH1750初始化*/
void BH1750_Init(void)
{	RCC->APB2ENR |= 1 << 2; //使能PORTA时钟GPIOA->CRL &= 0XFF0F0FFF; GPIOA->CRL |= 0X00303000; //PA3 5 推挽输出GPIOA->ODR |= 1<<3;      //PA3 输出高GPIOA->ODR |= 1<<5;      //PA5 输出高Single_Write_BH1750(BH1750_POWER_ON);
}
char light[] = "0000Lx"; // 光照值
void UpdateLightDisplay(uint16_t lux) 
{// 限制最大显示值为9999(4位)uint16_t display_val = lux > 9999 ? 9999 : lux;for(uint8_t i = 0; i < 4; i++){light[3 - i] = display_val % 10 + '0'; // 从个位开始填充display_val /= 10;}OLED_Show_String(1, 10, light);
}int main(void)
{/* 初始化部分 */OLED_Init();BH1750_Init();/* BH1750配置 */	BH1750_WriteReg(BH1750_POWER_ON);BH1750_WriteReg(BH1750_RESET_REG);BH1750_WriteReg(BH1750_CON_H_RES_MODE);/* 界面初始化 */OLED_Show_Chinese_String(1,1,CurrentLightIntensity_Str); //显示光照强度OLED_Show_Char(1, 9, ':'); while(1){/* 光照强度处理 */uint16_t lux = BH1750_ReadReg(); // 读取光照值UpdateLightDisplay(lux);Delay_ms(500);}
}

在这里插入图片描述

相关文章:

BH1750光照传感器---附代码

目录 BH1750简介BH1750指令集BH1750工作流程 BH1750简介 VCC-->电源正&#xff1b; ADDR-->地址端口&#xff1b; GND-->电源负&#xff1b; PA5-->SDA-->I2C数据线&#xff1b; PA3-->SCL-->I2C时钟线&#xff1b; DVI-->I2C端口参考电压&#xff1b…...

机器学习在催化剂设计中的应用理论加实操

背景介绍​​ 数据智能驱动&#xff0c;催化理性设计新纪元​​ 催化材料设计是能源转化、化工合成及环境治理等领域的核心挑战。传统催化研究主要依赖密度泛函理论(DFT)计算与实验试错法&#xff0c;通过量子力学模拟揭示活性位点电子结构&#xff0c;结合高通量实验筛选候选…...

蔡浩宇的AIGC游戏革命:从《原神》到《Whispers》的技术跨越

目录 引言&#xff1a;游戏行业的AI革命前夜 一、《Whispers》的技术突破与市场挑战 1.1 多模态AI技术的集成应用 1.2 与传统游戏的差异化体验 1.3 面临的商业化难题 二、从《原神》到《Whispers》的技术演进 2.1 《原神》成功的时代因素分析 2.2 蔡浩宇的技术路线转变 …...

Docker Compose 命令实现动态构建和部署

Docker Compose 命令实现动态构建和部署 一、编写支持动态版本号的 docker-compose.yml version: 3.8services:myapp:build: context: . # Dockerfile所在目录args:APP_VERSION: ${TAG:-latest} # 从环境变量获取版本号&#xff0c;默认latestimage: myapp:${TAG:-latest} …...

前端vue+typeScritp+elementPlus基础页面实现:

效果&#xff1a; 前端代码&#xff1a; index.vue: <template><el-container><el-main><el-card class"search-card" shadow"never"><transition :enter-active-class"proxy?.animate.searchAnimate.enter" :le…...

leetcode第20题(有效的括号)

思路解析&#xff08;使用栈&#xff09;&#xff1a; 使用一个栈来保存左括号。 每当遇到一个右括号时&#xff0c;检查栈顶元素是否是匹配的左括号。 如果匹配&#xff0c;则弹出栈顶元素&#xff1b; 如果不匹配或者栈为空&#xff0c;则说明无效&#xff1b; 最后如果栈…...

超简单的git学习教程

本博客仅用于记录学习和使用 前提声明全部内容全部来自下面廖雪峰网站&#xff0c;如果侵权联系我删除 0.前言 相信有不少人被推荐那个游戏学习git&#xff0c;一个不止我一个完全没学习过的进去后一脸懵&#xff0c;半天都通不过一关然后就放弃了&#xff0c;我个人觉得那个…...

【DVWA File Upload 漏洞实战指南】(Low / Medium / High 全级别解析)

前言 文件上传功能是 Web 应用中非常常见的一种功能&#xff0c;用于上传头像、文档、图片等文件。但如果验证不当&#xff0c;攻击者可能上传恶意脚本&#xff0c;进而控制服务器。在 DVWA 中&#xff0c;File Upload 模块专门设计用于演练此类漏洞的不同防御等级。 一、Low …...

iPhone 13P 换超容电池,一年实记的“电池循环次数-容量“柱状图

继上一篇 iPhone 13P 更换"移植电芯"和"超容电池"&#x1f50b;体验&#xff0c;详细记录了如何更换这两种电池&#xff0c;以及各自的优略势对比。 一晃一年过去&#xff0c;时间真快&#xff0c;这次分享下记录了使用超容电池的 “循环次数 - 容量(mAh)…...

Django 使用教程

Django 使用教程 Django 是一个高级的 Python Web 框架&#xff0c;采用了 MTV&#xff08;Model-Template-View&#xff09;设计模式&#xff0c;旨在帮助开发者快速构建高效、可维护的 Web 应用。它有着非常丰富的功能&#xff0c;包括 ORM、用户认证、表单处理、管理后台等…...

【集群IP管理分配技术_DHCP】一、DHCP技术概念与快速上手

在网络技术飞速发展的今天&#xff0c;动态主机配置协议&#xff08;DHCP&#xff09;作为网络中自动分配 IP 地址及相关配置参数的重要工具&#xff0c;极大地简化了网络管理流程。然而&#xff0c;随着网络规模的不断扩大和应用场景的日益复杂&#xff0c;传统 DHCP 在灵活性…...

Tailwindcss 入门 v4.1

以 react 为例&#xff0c;步骤如下&#xff1a; npm create vitelatest my-app -- --template react 选择 React 和 JavaScript 根据上述命令的输出提示&#xff0c;运行以下命令 cd my-app npm install npm run dev 一个 React App 初始化完成。 安装 Tailwindcss theme …...

【Linux】NAT、代理服务、内网穿透

NAT、代理服务、内网穿透 一. NAT1. NAT 技术2. NAT IP 转换过程3. NAPT 技术4. NAT 技术的缺陷 二. 代理服务器1. 正向代理2. 反向代理3. NAT 和代理服务器 内网穿透内网打洞 一. NAT NAT&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;技术&a…...

PCA——主成分分析数学原理及代码

主成分分析 PCA的目的是&#xff1a;对数据进行一个线性变换&#xff0c;在最大程度保留原始信息的前提下去除数据中彼此相关的信息。反映在变量上就是说&#xff0c;对所有的变量进行一个线性变换&#xff0c;使得变换后得到的变量彼此之间不相关&#xff0c;并且是所有可能的…...

AWS EC2完全指南:如何快速搭建高性能云服务器?

一、什么是AWS EC2&#xff1f;云时代的虚拟服务器革命 AWS Elastic Compute Cloud&#xff08;EC2&#xff09;作为全球领先的云服务器解决方案&#xff0c;正在重新定义虚拟服务器的可能性。与传统VPS相比&#xff0c;EC2提供&#xff1a; 秒级弹性扩展&#xff1a;CPU/RAM按…...

TLS/SSL 弱密码套件中危漏洞修复

TLS/SSL 弱密码套件漏洞是一种常见的安全问题&#xff0c;它可能导致加密通信被破解或降级攻击。修复此漏洞的关键是禁用不安全的密码套件&#xff0c;并配置服务器使用强密码套件。以下是修复步骤和详细说明&#xff1a; 1. 了解弱密码套件 弱密码套件通常包括以下类型&…...

SSMS中如何把一个库的表移到另一个库中

方法 1&#xff1a;使用“生成脚本”功能 步骤 右键点击源表&#xff1a; 在对象资源管理器中&#xff0c;展开源数据库的“表”节点&#xff0c;找到目标表。右键点击该表&#xff0c;选择 “脚本表为” -> “创建到” -> “新查询编辑器窗口”。 修改脚本&#xff1a…...

【技术派后端篇】Redis实现统计计数

在互联网项目中&#xff0c;计数器有着广泛的应用场景。以技术派项目为例&#xff0c;诸如文章点赞数、收藏数、评论数以及用户粉丝数等都离不开计数器的支持。在技术派源码中&#xff0c;提供了基于数据库操作记录实时更新和基于 Redis 的 incr 特性实现计数器这两种方案&…...

JavaWeb 课堂笔记 —— 16 MyBatis 动态SQL

本系列为笔者学习JavaWeb的课堂笔记&#xff0c;视频资源为B站黑马程序员出品的《黑马程序员JavaWeb开发教程&#xff0c;实现javaweb企业开发全流程&#xff08;涵盖SpringMyBatisSpringMVCSpringBoot等&#xff09;》&#xff0c;章节分布参考视频教程&#xff0c;为同样学习…...

论文阅读:2023 ICLR Safe RLHF: Safe Reinforcement Learning from Human Feedback

总目录 大模型安全相关研究:https://blog.csdn.net/WhiffeYF/article/details/142132328 Safe RLHF: Safe Reinforcement Learning from Human Feedback 安全 RLHF:通过人类反馈进行安全强化学习 https://arxiv.org/pdf/2310.12773 https://github.com/PKU-Alignment/safe…...

Python赋能去中心化电子商务平台:重构交易生态的新未来

Python赋能去中心化电子商务平台:重构交易生态的新未来 近年来,传统电子商务平台由于依赖中心化的服务器架构,面临数据隐私泄露、平台垄断、交易中介费用高昂以及信任危机等诸多挑战。而随着区块链和Web 3.0理念的快速普及以及零信任安全架构、边缘计算等新兴技术的不断成熟…...

Deepseek输出的内容如何直接转化为word文件?

我们有时候会直接利用deepseek翻译别人的文章或者想将deepseek输出的内容直接复制到word文档里。但是文本格式和word是不对应的。这时候需要输入如下命令&#xff1a; 以上翻译内容的格式和排版要求如下&#xff1a; 1、一级标题 字体为黑体&#xff08;三号&#xff09;&…...

Python实现对大批量Word文档进行批量自动化排版(15)

前言 本文是该专栏的第15篇,后面会持续分享Python办公自动化干货知识,记得关注。 在本专栏上一篇文章《Python实现对目标Word文档进行自动化排版【4万字精讲】(14)》中,笔者已经详细介绍“基于Python,实现对目标docx格式的word文档进行自动化排版”的实战教学(文章附带…...

北理工宫某的瓜ppt下载地址

关于“北理工宫某瓜”PPT下载地址相关技术探讨 摘要&#xff1a;本文围绕“北理工宫某瓜”事件中PPT下载地址相关情况展开分析&#xff0c;探讨了网络资源传播的技术机制、涉及的网络安全问题以及围绕此类资源分享应遵循的规范和注意事项&#xff0c;旨在从技术角度对这类网络…...

解决ubuntu自带火狐浏览器无法播放视频问题

TIPS:一般执行完1 就可以了 首先安装必要的媒体编解码器和插件&#xff1a; # 安装常用媒体编解码器和插件 sudo apt update sudo apt install -y ubuntu-restricted-extras# 安装额外的编解码器 sudo apt install -y ffmpeg# 安装其他视频相关包 sudo apt install -y libavc…...

AI融合SEO关键词实战指南

内容概要 随着人工智能技术的迭代升级&#xff0c;SEO关键词策略正经历从人工经验驱动向数据智能驱动的范式转变。本指南聚焦AI技术在搜索引擎优化中的系统性应用&#xff0c;通过构建多层技术框架实现关键词全生命周期管理。核心方法论涵盖语义分析引擎的构建原理、基于NLP的…...

快速入手-基于python和opencv的人脸检测

1、安装库 pip install opencv-python 如果下载比较卡的话&#xff0c;指向国内下载地址&#xff1a; pip3 install opencv-python -i https://pypi.tuna.tsinghua.edu.cn/simple 2、下载源码 https://opencv.org/ windows11对应的版本下载&#xff1a; https://pan.baidu…...

Windows 环境下安装 MariaDB 及 HeidiSQL 使用教程

引言 本报告旨在提供一份详尽的操作指南。内容将覆盖在 Windows 操作系统上安装 MariaDB Community Server 的全过程。我们还将探讨如何利用 HeidiSQL 这款图形用户界面&#xff08;GUI&#xff09;工具&#xff0c;直观地预览和管理我们新安装的数据库。除了安装与配置的步骤…...

汽车免拆诊断案例 | 2011款雪铁龙世嘉车刮水器偶尔自动工作

故障现象 一辆2011款雪铁龙世嘉车&#xff0c;搭载1.6 L 发动机&#xff0c;累计行驶里程约为19.8万km。车主反映&#xff0c;该车刮水器偶尔会自动工作&#xff0c;且前照灯偶尔会自动点亮。 故障诊断 接车后试车发现&#xff0c;除了上述故障现象以外&#xff0c;当用遥控器…...

8.QT-按钮类控件|Push Button|Radio Button|Check Box|Tool Button(C++)

Push Button 使⽤ QPushButton 表⽰⼀个按钮.这也是当前我们最熟悉的⼀个控件了. QPushButton 继承⾃ QAbstractButton .这个类是⼀个抽象类.是其他按钮的⽗类 在Qt Designer中也能够看到这⾥的继承关系 属性说明text按钮中的⽂本icon按钮中的图标iconSize按钮中图标的尺⼨sh…...