BH1750 光照传感器文档详解 及 驱动设计_bh1750(1)

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上物联网嵌入式知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、电子书籍、讲解视频,并且后续会持续更新

需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)

如果你需要这些资料,可以戳这里获取

通过上图我们可以直接确定传感器的供电电压。

当然还有一个重要的点就是他的 I2C 参考电压可以达到 Vcc ,这说明在我们常用的 3.3V 供电的 MCU 系统上使用这个传感器不需要做电平转换,可以直接与 MCU 的 I2C 接口连接。

再往下的一些电气参数 Electrical Characteristics 其实过一遍了解一下即可,不仔细也没有太大关系。

1.3 根据推荐电路图确定 PCB 设计

上面我们已经知道了传感器供电电压,那么如果是自己设计 硬件电路的话,那么需要了解:

各个引脚的功能定义

参考产品手册上的推荐电路图

这个在资料往下翻一大段。

引脚的定义如下:

在这里插入图片描述

这里加一个判别传感器1引脚的方法:

上图中,传感器中间有一个品字形状,我们拿到传感器仔细看,也能看到品字形状,根据这个形状判断 引脚即可。

在文档后面有引脚的定义:

在这里插入图片描述

我这里自己写一个表格做简要说明:

名称功能
VCC电源
ADDR传感器地址引脚,ADDR 高低电平传感器地址不一样 ,高电平:0x5C 低电平: 0x23
GNDGND
SDAI2C 数据线
DVISDA和 SCL 的参考电压,内部寄存器的异步重置端口,在供电以后需要保持低电平,在内部通过 150k 的电阻下拉到地
SCLI2C 时钟线

当 ADDR 为高电平的时候,传感器地址为 1011100 :0x5C;

当 ADDR 为低电平的时候,传感器地址为 0100011 :0x23;

接下来我们来看看推荐电路图 ,注意手册中的说明:

在这里插入图片描述
图中 SDA 和 SCL 以及省略了,还得注意一下 ADDR 的高低电平,因为决定了传感器的地址。

在手册中推荐了 4 种电路图,我这里推荐的是使用第四种(需要知道一下这种无法满足内部寄存器重置的操作):

在这里插入图片描述

如果使用这种方式,那么我们接下来操作传感器的地址就是:0x23。

对于硬件相关的东西我们确定好了以后,我们可以自己画 PCB ,要记住 I2C 通讯是需要上拉电阻的。当然如果是采购的现成的传感器模块可以省略。

采购的传感器模块一般都只需要连接 4个引脚,就是标准的 I2C 通讯的 :SCL、 SDA、VCC、GND 。

博主本次采用的传感器其实也是采购的成品小板子,但是正真的最后还是会自己画的,到时候有机会也来记录一下自己画的用作低功耗的小板子:

在这里插入图片描述

二、工作流程及指令

我们完成硬件的基本了解,可以了解一下传感器的工作流程级操作指令。

2.1 工作流程分析

在资料手册中,列出了 Measurement Procedure 部分,如下图:

在这里插入图片描述

对于低功耗的产品,我们都会使用单次测量模式,可以最大限度的控制功耗。

我们可以直接总结出来,我们如果使用单次测量命令的话,我们在初始化传感器的时候就可以使用指令让模块进入单次测量模式:

初始化:

模块上电 ——> 发送指令使模块进入单次测量模式

正常工作流程:

发送指令使模块进入上电模式 ——> 发送测量命令 ——> 模块测量完成会会自动进入掉电模式(单次测量模式)

2.2 操作命令

在手册中给出了操作命令,但是根据我们前面的分析,我们需要用到的指令并不多,在图中我圈出了我们可能需要用到的指令:

在这里插入图片描述

其中我们只需要记住单次测量的命令就可以了,使用什么分辨率根据自己的情况而定。

2.3 单次测量示例解析

为了更好的说明命令怎么用,在手册中也已经举了例子,我给他加上了中文注释说明测量流程:

在这里插入图片描述

传感器手册读到这里,基本上已经满足我们的开发需求,我们下面就开始根据上面所分析的资料进行程序设计。

三、程序设计

本次的测试基于 STM32L051 ,但是其实在驱动程序中体现不出来,因为用的软件 I2C ,驱动基本上可以移植到各种单片机平台。

在我们使用 i2c 传感器的时候,一般都是有一个通用驱动文件,然后还有一个传感器的驱动文件,如下图(d6t44l 是一个 I2C 传感器):

在这里插入图片描述

对于 I2C 的基础知识,本文不做过多讨论,大家应该比较熟悉,不熟悉的可以复习一下基础知识。

3.1 I2C 通用驱动

通用驱动就包括了 ,I2C 启动,结束,发送等待 ACK ,发送不等待 ACK ,读取,等待 ACK 等等这些函数,这个其实在很多开源的项目中找一个就可以了。

我们这里先确定一下 i2c.h 文件,针对自己的设备连接的 IO 口进行定义:

在这里插入图片描述

这里因为大家都很方便的可以找到开源的驱动,唯独需要注意上图中的定义,改成自己测试的 IO 口,所以这里就不过多解释,直接把通用驱动放上 :

i2c.h:

#ifndef \_I2C\_H\_INCLUDED
#define \_I2C\_H\_INCLUDED

#include "main.h"
#include "Datadef.h"
        
#define MYIIC\_CLK\_HIGH HAL\_GPIO\_WritePin(SCL\_GPIO\_Port,SCL\_Pin,GPIO\_PIN\_SET) 
#define MYIIC\_CLK\_LOW HAL\_GPIO\_WritePin(SCL\_GPIO\_Port,SCL\_Pin,GPIO\_PIN\_RESET) 

#define MYIIC\_DATA\_HIGH HAL\_GPIO\_WritePin(SDA\_GPIO\_Port,SDA\_Pin,GPIO\_PIN\_SET) 
#define MYIIC\_DATA\_LOW HAL\_GPIO\_WritePin(SDA\_GPIO\_Port,SDA\_Pin,GPIO\_PIN\_RESET)
#define MYIIC\_DATA\_STATE HAL\_GPIO\_ReadPin(SDA\_GPIO\_Port,SDA\_Pin)
                         
                         
// ------------------------
#define DONOTHING() {;}

// ------------------------
// command's
#define I2C\_WRITE 0 
#define I2C\_READ 1
#define I2C\_ACK 0
#define I2C\_NACK 1


void MYIIC\_Start(void);
void MYIIC\_Stop(void);
u8 MYIIC\_Wait\_Ack(void);
void IIC\_NAck(void);
void IIC\_Ack(void);
void IIC\_Send\_Byte(u8 txd);
u8 IIC\_Read\_Byte(unsigned char ack);

#endif

i2c.c:

#include "i2c.h"

void MYIIC\_Start(void)
{
   MYIIC_DATA_HIGH;
   delay\_us(5);
   MYIIC_CLK_HIGH;
   delay\_us(10);
   MYIIC_DATA_LOW;
   delay\_us(10);
   MYIIC_CLK_LOW; //使SCL置低,准备发送或者接受数据
   delay\_us(10);
}

void MYIIC\_Stop(void)
{ 
   MYIIC_DATA_LOW;
   delay\_us(5);
   MYIIC_CLK_LOW;
   delay\_us(10);
   MYIIC_CLK_HIGH;
   delay\_us(5);
   MYIIC_DATA_HIGH;
   delay\_us(10); 
}

//读1个字节,ack=1时,发送ACK,ack=0,发送nACK 
u8 IIC\_Read\_Byte(unsigned char ack)
{
	unsigned char i,receive=0;
	// MYSDA\_IN;//SDA设置为输入
   for(i=0;i<8;i++ )
	{
        MYIIC_CLK_LOW;    //SCL为由低变高,在SCL高的时候去读 SDA的数据
        delay\_us(10);
		  MYIIC_CLK_HIGH;
        receive<<=1;  //第一次这里还是0,第二次开始每次接收的数据做移动一位,从高位开始接收
        if(MYIIC_DATA_STATE)receive++;   //如果数据为1,++以后就是1,数据为0,不执行就是0; 
		  delay\_us(10); 
   }					 
   if (!ack)
        IIC\_NAck();//发送nACK
   else
        IIC\_Ack(); //发送ACK 
   return receive;
}


u8 MYIIC\_Wait\_Ack(void)
{
    u8 ucErrTime=0;
	delay\_us(5);
    MYIIC_DATA_HIGH;delay\_us(5);       //MCU DATA 置高,外面高就是高,外面低就是低
    MYIIC_CLK_HIGH; delay\_us(5);       //CLK 高电平期间数据有效
    while(MYIIC_DATA_STATE)             //低电平为有应答,高电平无应答 
    {
      ucErrTime++;
		if(ucErrTime>250)
		{
			MYIIC\_Stop();
			return 1;
		}  
    }
		delay\_us(10);
    MYIIC_CLK_LOW;
    return 0;
}

void IIC\_Ack(void)
{
	MYIIC_CLK_LOW;    //SCL为低,SDA为低,SCL为高,SDA为低,应答低电平有效,SCL为低,产生应答信号
	// MYSDA\_OUT;
	MYIIC_DATA_LOW;
	delay\_us(10);
	MYIIC_CLK_HIGH;
	delay\_us(10);
	MYIIC_CLK_LOW;
	delay\_us(10);
	MYIIC_DATA_HIGH;
}

void IIC\_NAck(void)
{
	MYIIC_CLK_LOW;     //SCL为低,SDA为高,SCL为高,SCL为低
	// MYSDA\_OUT;
	MYIIC_DATA_HIGH;
	delay\_us(10);
	MYIIC_CLK_HIGH;
	delay\_us(10);
	MYIIC_CLK_LOW;
}

//IIC发送一个字节
//返回从机有无应答
//1,有应答
//0,无应答 
void IIC\_Send\_Byte(u8 txd)
{                        
   u8 t;   
	// MYSDA\_OUT; 
   MYIIC_CLK_LOW;  //拉低时钟开始数据传输 ,SCL为低,SDA变高或者变低(数据位),SCL变高,SCL变低,期间SDA为1既1,为0既0
   for(t=0;t<8;t++)  //一个字节8位,一位一位发送
    {              
     MYIIC_CLK_LOW;
		if((txd&0x80)>>7)   //从最高位开始发送,如果是1,发送高电平
			MYIIC_DATA_HIGH;
		else
			MYIIC_DATA_LOW;
		txd<<=1; 	      //SDA处理完毕,此时可以将SCL拉高接受数据,拉高以后延时拉低
		delay\_us(10);   //
		MYIIC_CLK_HIGH;
		delay\_us(10); 
		MYIIC_CLK_LOW;	
		delay\_us(5);
    }	 
}


3.2 BH1750 驱动

完成了通用驱动,我们现在就可以完全根据前面的分析流传进行 BH1750 的驱动设计。

我们新建一个 bh1750.cbh1750.h 文件,在头文件中进行一些必要的宏定义:

在这里插入图片描述

把可能需要用到的都给他定义一遍,后面需要改正再说。

然后开始在 c 文件中写驱动,首先当然是传感器初始化,上电就得设置为单次测量模式,那么发送数据就得按照前面给出的分析。

首先传感器上电初始化给他写个函数:

在这里插入图片描述

然后读取函数,因为只需要读取2个字节,所以也比较简单:

在这里插入图片描述

最后在需要的地方调用函数即可:

在这里插入图片描述

这里还是把 传感器测试驱动源码放上。

bh1750.c

#include "bh1750.h"
#include <stdio.h>

/\*
说明,测试程序,函数不判断是否成功
\*/

void bh1750\_init()
{
	MYIIC\_Start();
	IIC\_Send\_Byte(BH1750_ADDRESS << 1); //地址,和读写指令
	MYIIC\_Wait\_Ack();
	delay\_us(150); 
	// IIC\_Send\_Byte(BH1750\_CMD\_POWERON); // 电不一定需要,这里测试看看
	// MYIIC\_Wait\_Ack();
	// delay\_us(150); 
	IIC\_Send\_Byte(BH1750_MODE_ONE_H_RES);  //单次测量
	MYIIC\_Wait\_Ack();


**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
![img](https://img-blog.csdnimg.cn/img_convert/48fe9e2ae7b62ee8e07ebbc01d3fe4b6.png)
![img](https://img-blog.csdnimg.cn/img_convert/7bb503b0aed3c669b9dfbc9cdf6bdd77.png)

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

d\_Byte(BH1750_MODE_ONE_H_RES);  //单次测量
	MYIIC\_Wait\_Ack();


**收集整理了一份《2024年最新物联网嵌入式全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升的朋友。**
[外链图片转存中...(img-ZWD5Cs0D-1715764673518)]
[外链图片转存中...(img-y9kksX2e-1715764673519)]

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618679757)**

**需要这些体系化资料的朋友,可以加我V获取:vip1024c (备注嵌入式)**

**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人**

**都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**

  • 3
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值