BH1750( GY-302 )光照传感器

news2024/12/23 22:46:50

文章目录

  • 一、产品简介
  • 二、IIC通信
  • 三、BH1750的使用
  • 四、程序源码


这里我先简单的介绍一下BH1750光照传感器模块的基本信息(不多废话),我将着重讲解它的使用部分,相信对于屏幕前的你也是更关心它是怎么使用的,OK,gogogo!!!

一、产品简介

芯片: BH1750FVI 是一种用于两线式串行总线接口的数字型光强度传感器集成电路。这种集成电路可以根据收集的光线强度数据来调整液晶或者键盘背景灯的亮度。利用它的高分辨率可以探测较大范围的光强度变化。

工作原理: BH1750的内部由光敏二极管、运算放大器、ADC采集、晶振等组成。PD二极管通过光生伏特效应将输入光信号转换成电信号,经运算放大电路放大后,由ADC采集电压,然后通过逻辑电路转换成16位二进制数存储在内部的寄存器中(光照越强,光电流越大,电压就越大)。

物理电路图:
在这里插入图片描述
PCB原理图:
在这里插入图片描述

实物图:
在这里插入图片描述
可见,该模块有5个引脚,接下来再看看引脚介绍是啥模样

引脚定义:
在这里插入图片描述
模块指令:
在这里插入图片描述
使用步骤:
在这里插入图片描述

产品特点:

  • 支持I2CBUS接口
  • 接近视觉灵敏度的光谱灵敏度特性
  • 输出对应亮度的数字值
  • 对应广泛的输入光范围。(相当于1-65535lx)
  • 通过降低功率功能,实现低电流化。
  • 通过50Hz/60Hz除光噪音功能实现稳定的测定。
  • 支持1.8v逻辑输入接口。
  • 无需其他外部件。
  • 光源依赖性弱。
  • 有两种可选的I2Cslave地址。
  • 可调的测量结果影响较大的因素为光入口大小。
  • 使用这种功能计算1.1lx到100000lx马克斯/分钟的范围。
  • 最小误差变动在±20%。
  • 受红外线影响很小。

二、IIC通信

IIC是一种串行通信总线,IIC串行总线一般有两根信号线,一根是双向的数据线SDA,另一根是时钟线SCL。所有接到I2C总线设备上的串行数据SDA都接到总线的SDA上,各设备的时钟线SCL接到总线的SCL上。可以理解为 其通过SDA和CLK俩根线完成通信传输,

由于该模块是通过IIC协议进行通信的,所以接下来我再来介绍介绍IIC的相关驱动。

IIC驱动部分都是通用的,其各个模块是根据自身的设备地址及其配置、命令等寄存器操作不同来完成各自的通信。

IIC 驱动部分我划分为了6个部分,分为:

  • 开始信号
  • 停止信号
  • 发送应答信号
  • 接收应答信号
  • 发送一个字节
  • 接收一个字节

首先先来看时序图:
在这里插入图片描述
时序没看明白,别着急,听我一 一道来。

首先,请记住 : SDA和CLK只有“0和1”俩种状态;其次,主机在发送信号时CLK引脚要定义输出模式,在接收信号时CLK引脚要定义输入模式。

1. 开始信号:
对于开始信号,你可以这样理解,SDA是在CLK置高电平的情况下 由高电平->低电平,这就是开始信号,只不过为了通信稳定,一般在跳变中途延时5us。

接下来看看程序是怎么设计的:

void IIC_Start(void)
{
	SDA_OUT();     //sda线输出模式
	IIC_SDA=1;	  	  
	IIC_SCL=1;
	delay_us(5);
 	IIC_SDA=0;   //产生下降沿
	delay_us(5);
	IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 
}	

2. 停止信号:
同开始信号,SDA在CLK为高电平时 由低电平->高电平,完成停止信号。

void IIC_Stop(void)
{
	SDA_OUT(); //sda线输出
	IIC_SDA=0;  //产生上升沿
 	delay_us(5);
	IIC_SCL=1; 
	IIC_SDA=1; //发送I2C总线结束信号
	delay_us(5);							   	
}

3. 发送应答信号:
在SDA为低电平时 CLK由高电平->低电平 ,完成应答;
在SDA为高电平时 CLK由高电平->低电平 ,拒绝应答;

所以在程序中 需设置一个变量进行判断是否接受应答:

void SendACK(int ack)    
{
  GPIO_InitTypeDef GPIO_InitStruct;   
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;    //定义输出模式
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_Pin = sda;
  GPIO_Init(bh1750_PORT, &GPIO_InitStruct);  
	
	if(ack == 1)   //写应答信号
		SDA=1; 
	else if(ack == 0)
		SDA=0; 
	else
		return;			
  SCL=1;     //拉高时钟线
  delay_us(5);                 //延时
  SCL=0;      //拉低时钟线
  delay_us(5);                //延时
}

4. 接收应答信号:
在CLK由低电平->高电平->低电平 期间SDA保持低电平

u8 IIC_waitAck()
{
	u8 ack =0;
	IIC_setSDAMode_In();
	IIC_SCL_OUT(0);             //准备时序
	delay_us(5);
	
	IIC_SCL_OUT(1);
	delay_us(5);
	
	if(IIC_SDA_IN)
	{
				ack =1;
	}
	else
	{
				ack =0;	
	}
	IIC_SCL_OUT(0);              //拉低,表示应答完成
	delay_us(5);
	return  ack;
}

5. 发送一个字节:
CLK每完成一次 高电平->低电平 跳变,主机发送1bit,1字节发送完成后且需要接收从机发回来的应答信号。

void SendByte(uchar dat)
{
  uchar i;
  for (i=0; i<8; i++)         //8位计数器
  {
		if( 0X80 & dat )
      GPIO_SetBits(bh1750_PORT,sda);
    else
      GPIO_ResetBits(bh1750_PORT,sda);
		dat <<= 1;
    SCL=1;               //拉高时钟线
    delay_us(5);             //延时
    SCL=0;                //拉低时钟线
    delay_us(5);            //延时
  }
  RecvACK();
}

6. 接收一个字节:
类似于发送一字节,只是引脚定义不同,具体如下:

u8 IIC_readByte()
{
  u8 data = 0;
	IIC_setSDAMode_In();
	IIC_SCL_OUT(0);                  //先拉低,为读取数据做准备
	delay_us(5);
	for(int i=0;i<8;i++)
	{
			IIC_SCL_OUT(1);         // SCL为高期间才可以读取数据
			delay_us(5);
		if(IIC_SDA_IN)
		{
				data|=(0x01<<(7-i));	
		}else{
			data &= ~(0x1<<(7-i));
		}	
		IIC_SCL_OUT(0);
		delay_us(5);
	}
	return data;
}

三、BH1750的使用

1. 写信号
首先需要对模块进行写操作,然后再初始化, 写操作的过程为:起始信号 -->发送设备地址+写信号 -->发送内部寄存器地址 --> 发送停止信号。

void Single_Write_BH1750(uchar REG_Address)
{
  BH1750_Start();                  //起始信号
  BH1750_SendByte(SlaveAddress);   //发送设备地址+写信号
  BH1750_SendByte(REG_Address);    //内部寄存器地址
  BH1750_Stop();                   //发送停止信号
}

2. 初始化
对模块进行初始化,初始化SDA和CLK引脚 初步设置为推挽输出,然后对模块进行上电,根据指令表可知 上电指定为0x01,上电后需要延迟180ms左右让模块进行缓冲。

void Init_BH1750()
{
  GPIO_InitTypeDef GPIO_InitStruct;
	 /*开启GPIOB的外设时钟*/ 
  RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOA, ENABLE); 
  GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;  
  GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
  GPIO_InitStruct.GPIO_Pin = sda | scl ;
  GPIO_Init(bh1750_PORT,&GPIO_InitStruct); 
	
  Single_Write_BH1750(0x01);  
	delay_ms(180);            //延时180ms
}

3. 读寄存器内部数据
读数据操作的过程为:起始信号 -->发送设备地址+读信号 -->定义数组存储数据(最后一个数据需要拒绝应答) --> 发送停止信号。

void mread(void)
{   
	uchar i;	
    BH1750_Start();                          //起始信号
    BH1750_SendByte(SlaveAddress+1);         //发送设备地址+读信号
	
	for (i=0; i<3; i++)                      //连续读取3个地址数据,存储中BUF
  {
      BUF[i] = BH1750_RecvByte();          //BUF[0]存储0x32地址中的数据
      if (i == 3)
    {
      BH1750_SendACK(1);                //最后一个数据需要回NOACK
    }
    else
    {		
      BH1750_SendACK(0);                //回应ACK
    }
  }
  BH1750_Stop();                          //停止信号
  delay_ms(5);
}

4. 对数据进行操作、转存

float read_BH1750(void)
{
    int dis_data;                       //变量	
	float temp1;
	float temp2;
	Single_Write_BH1750(0x01);   // power on
    Single_Write_BH1750(0x10);   // H- resolution mode
    delay_ms(180);            //延时180ms
	mread();       //连续读出数据,存储在BUF中
    dis_data=BUF[0];
    dis_data=(dis_data<<8)+BUF[1]; //合成数据 
	temp1=dis_data/1.2;
	temp2=10*dis_data/1.2;	
	temp2=(int)temp2%10;
	OLED_ShowString(87,2,".",12); 
	OLED_ShowNum(94,2,temp2,1,12);	
	return temp1;
}

5. 主函数里调用BH17502并显示在oled上

int main(void)
{ 
    float light;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);// 设置中断优先级分组2
	delay_init();	    	 //延时函数初始化	  
	uart_init(9600);	 	//串口初始化为9600
	LED_Init();				//初始化与LED连接的硬件接口
    Init_BH1750();       //初始化BH1750
	OLED_Init();     //初始化OLED
	OLED_Clear();     //清屏
	
  while(1)
  {
     light=read_BH1750();  //读取BH1750的光强数据
     OLED_ShowString(0,2,"light:",12);  //显示光照强度
	 OLED_ShowNum(48,2,light,6,12);	
	 OLED_ShowString(110,2,"lx",12);
	 if(light<100)
	{
		LED1=0;
		OLED_ShowString(38,5,"LED-ON ",12);
	}
	else
	{
		LED1=1;
		OLED_ShowString(38,5,"LED-OFF",12);
	}
  }		
}	

四、程序源码

该程序结合oled显示输出,有需要可自提:

链接:https://pan.baidu.com/s/1qjR4VbrlUG8NEDpRazu2dg?pwd=0lwi
提取码:0lwi

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

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

相关文章

2019第一届长安杯

检材一 案情简介 在一起电诈案件中&#xff0c;受害者称自己的银行卡被他人冒用&#xff0c;曾收到假冒公安的短信&#xff0c;因为 自己在一个 P2P 网站中理财&#xff0c;假冒公安称该网站已被列外非法网站&#xff0c;要自己到公安备案网站 填写自己的信息&#xff0c;并…

基于javaweb的crm客户关系管理系统(java+springboot+mysql)

基于javaweb的crm客户关系管理系统(javaspringbootmysql) 运行环境 Java≥8、MySQL≥5.7 开发工具 eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计&#xff0c;大作业&#xff0c;毕业设计&#xff0c;项目练习&#xff0c;学习演示等 功能说明 基于javawebsp…

云扩研习社 | RPA高级开发技巧(上)

高级元素选择技巧 XPath介绍 XPath是标准的结构化查询语言&#xff0c;内置丰富的语法、高阶函数可以提供非常强大的目标元素特征描述能力。 XPath是一种强大、复杂的查询语言&#xff1b;XPath与编辑器中内置的选择器没有本质区别&#xff0c;均可作为元素特征描述&#xff…

毕业设计 基于51单片机老人防跌倒GSM短信报警系统

基于51单片机无线蓝牙APP控LED灯亮灭亮度设计1、项目简介1.1 系统构成1.2 系统功能2、部分电路设计2.1 GSM SIM800A模块电路设计2.2 蜂鸣器报警电路&#xff08;低电平有效&#xff09;设计2.3 ADXL345倾角传感器模块电路设计2.4 DS18B20温度传感器模块电路设计3、部分代码展示…

面试官问我 “A + B” 算法,我懵了

&#x1f388; 作者&#xff1a;Linux猿 &#x1f388; 简介&#xff1a;CSDN博客专家&#x1f3c6;&#xff0c;华为云享专家&#x1f3c6;&#xff0c;Linux、C/C、云计算、物联网、面试、刷题、算法尽管咨询我&#xff0c;关注我&#xff0c;有问题私聊&#xff01; &…

逆向学习-UltraEdit安装

一、相关软件安装 1、UltraEdit 1.1、简介 UltraEdit 是当今销量第一且最为强大的一款高性价比的文本编辑器。尽管不是一款开源软件&#xff0c;但多数程序员都使用这款编辑器&#xff0c;支持多种编程语言的语法着色和外挂编译功能。UltraEdit 是理想的文本、HTML 和十六进…

最新|全新风格原创YOLOv7、YOLOv5和YOLOX网络结构解析图

&#x1f4a1;本篇分享一下个人绘制的原创全新风格YOLOv7网络结构图、YOLOv5网络结构图和YOLOX网络结构图 个人感觉搭配还行&#xff0c;看着比较直观&#xff0c;所以开源分享一下。 文章目录YOLOv5 网络结构图(最新 推荐&#x1f525;&#x1f525;&#x1f525;)YOLOv7 网络…

【C++笔试强训】第十三天

&#x1f387;C笔试强训 博客主页&#xff1a;一起去看日落吗分享博主的C刷题日常&#xff0c;大家一起学习博主的能力有限&#xff0c;出现错误希望大家不吝赐教分享给大家一句我很喜欢的话&#xff1a;夜色难免微凉&#xff0c;前方必有曙光 &#x1f31e;。 &#x1f4a6;&a…

YOLOv5、v7改进之三十八:引入RepVGG模型结构

前 言&#xff1a;作为当前先进的深度学习目标检测算法YOLOv7&#xff0c;已经集合了大量的trick&#xff0c;但是还是有提高和改进的空间&#xff0c;针对具体应用场景下的检测难点&#xff0c;可以不同的改进方法。此后的系列文章&#xff0c;将重点对YOLOv7的如何改进进行详…

基于javaweb的养老院管理系统(java+springboot+thymeleaf+html+js+mysql)

基于javaweb的养老院管理系统(javaspringbootthymeleafhtmljsmysql) 运行环境 Java≥8、MySQL≥5.7 开发工具 eclipse/idea/myeclipse/sts等均可配置运行 适用 课程设计&#xff0c;大作业&#xff0c;毕业设计&#xff0c;项目练习&#xff0c;学习演示等 功能说明 基于…

synchronized到底锁的是谁、何时生效

一、synchronized锁的几种形式 synchronized修饰普通方法synchronized修饰静态方法synchronized修饰代码块 1、synchronized修饰普通方法 简单示例 public class Test{private String age;private String name;public synchronized void print(String arg1, String arg2) {…

零代码,让业务人员实现应用创造自由

摘要&#xff1a;以汽车营销场景为例&#xff0c;从AppCube零代码和业务大屏入手&#xff0c;帮助开发者更好地理解AppCube低代码和零代码异同点&#xff0c;在实际使用时能更快选取更合适的工具能力&#xff0c;实现应用构建效率最大化。本文分享自华为云社区《DTT第8期直播回…

超级详细的Vue安装与配置教程

Vue web前端三大主流框架之一,是一套用于构建用户界面的渐进式框架,下面这篇文章主要给大家介绍了关于Vue安装与配置教程的相关资料,文中通过图文介绍的非常详细,需要的朋友可以参考下 − 目录 一、下载和安装Vue二、创建全局安装目录和缓存日志目录三、配置环境变量 1. 环境…

【k哥爬虫普法】简历大数据公司被查封,个人隐私是红线!

我国目前并未出台专门针对网络爬虫技术的法律规范&#xff0c;但在司法实践中&#xff0c;相关判决已屡见不鲜&#xff0c;K 哥特设了“K哥爬虫普法”专栏&#xff0c;本栏目通过对真实案例的分析&#xff0c;旨在提高广大爬虫工程师的法律意识&#xff0c;知晓如何合法合规利用…

mysql忘记密码怎么办(附免密登录和修改密码)

前言 博主个人社区&#xff1a;开发与算法学习社区 博主个人主页&#xff1a;Killing Vibe的博客 欢迎大家加入&#xff0c;一起交流学习~~ 一、打开MySQL&#xff08;能打开请跳过此步&#xff09; 第一种&#xff1a;安装完MySQL之后&#xff0c;MySQL提供大家的客户端程序 …

DASCTF X GFCTF 2022十月挑战赛-hade_waibo

这是一个非预期解&#xff0c;但是得到出题人的赞许&#xff0c;莫名开心&#xff0c;哈哈&#xff1a; cancan need处存在任意文件读取 <!DOCTYPE html> <html lang"en" class"no-js"> <head> <meta charset"UTF-8" />…

引爆记忆广告语盘点

在数字化、流量红利见顶、营销环境巨变的进程中&#xff0c;品牌传播的节奏从快到稳。品牌出圈更需要产品、渠道、内容、文化等方面的共振影响&#xff0c;其中广告语作为品牌定位和价值主张的核心载体&#xff0c;是连接消费者心智的重要品牌资产。 根据益普索Ipsos《引爆记忆…

uni-app、小程序项目分包经验之谈与天坑异常:RangeError: Maximum call stack size exceeded

小程序分包经验之谈与天坑异常&#xff1a;RangeError: Maximum call stack size exceeded小程序分包概述分包配置参数&#xff1a;subPackages分包预载配置参数&#xff1a;preloadRule如何使用实际小程序项目分包项目结构配置分包配置分包预载天坑异常场景分析猜想尝试解决解…

springboot配置多个数据源

一.多数据源的典型使用场景 在实际开发中,经常可能遇到在一个应用中可能要访问多个数据库多的情况,以下是两种典型场景 1.业务复杂 数据分布在不同的数据库中,数据库拆了,应用没拆.一个公司多个子项目,各用各的数据库,设计数据共享 2.读写分离 为了解决数据库的性能瓶颈(读…

C++内存管理和模板

目录 内存管理 new T[N] new和delete关键字的总结&#xff1a; 定位new表达式(placement-new)&#xff1a; 作用&#xff1a; 使用格式&#xff1a; 使用场景&#xff1a; 实例&#xff1a; 调用析构函数的两个方法&#xff1a; 池化技术&#xff1a; 面试题&#xff1…