使用BH1750(GY-302)光照传感器的方法

BH1750(GY-302)的使用,(光照传感器)

提示:文章写完后,目录可以 自动生成,如何生成可参考右边的帮助文档

前言

直接在网上购买BH1750 传感器模块
本课题使用STM32F103-mini


提示:以下是本篇文章正文内容,下面案例可供参考

一、BH1750是什么?

BH1750FVI是一款数字型光强度传感器集成芯片。某宝上面很多写着GY30模块,那些其实也是用BH1750FVI芯片,只不过是它把BH1750FVI芯片以及外围的一些电路做到了一个板子上面,然后把BH1750FVI的通讯引脚引出来方便你们用单片机控制而已。(话说大部分国产芯片都是这个套路,把人家的芯片拿过来,加一点外围电路,然后重新包一层外壳,换个型号,就变成自己的产品了)

	 电路工作原理:如图1所示,BH1750的内部由光敏二极管、运算放大器、ADC采集、晶振等组成。PD二极管通过光生伏特效应将输入光信号转换成电信号,经运算放大电路放大后,由ADC采集电压,然后通过逻辑电路转换成16位二进制数存储在内部的寄存器中(注:进入光窗的光越强,光电流越大,电压就越大,所以通过电压的大小就可以判断光照大小,但是要注意的是电压和光强虽然是一一对应的,但不是成正比的,所以这个芯片内部是做了线性处理的,这也是为什么不直接用光敏二极管而用集成IC的原因)。BH1750引出了时钟线和数据线,单片机通过I2C协议可以与BH1750模块通讯,可以选择BH1750的工作方式,也可以将BH1750寄存器的光照度数据提取出来。

**

引脚定义

**:

名称 说明
VCC 供电电压源正极
SCL IIC时钟线,时钟输入引脚,由MCU输出时钟
SDA IIC数据线,双向IO口,用来传输数据
ADDR IIC地址线,接GND时器件地址为0100011 ,接VCC时器件地址为1011100
GND 供电电压源负极

简单介绍一下IIC

IIC由时钟线(SCL)和数据线(SDA)组成。时钟线,听这个名字就知道和时间有关系,没错,它其实管理着IIC的通讯时间。而数据线,顾名思义就是用来传输数据的线。那么时钟线和数据线它们是什么关系呢?你可以把时钟线理解为红绿灯,高电平是绿灯,低电平是红灯,而数据线传输的每一个数据则相当于一辆汽车,高电平是奔驰,低电平是宝马。当绿灯亮了的时候,汽车就可以过去,只不过这里的交通规则是每亮一次绿灯,只能通过一辆汽车。所以,IIC通讯的过程就是红绿灯交替闪烁(也就是时钟线输出方波脉冲),汽车跟着一辆一辆的过去,过去的是奔驰,就是传输了一个“1”,过去的宝马,就是传输了一个“0”,连续传输8次,就可以组成一个8位的二进制数,也就是一个字节的数据,反复这个过程就能实现两个设备之间的通讯。

二、使用步骤

1.编写BH1750的头文件

代码如下(示例):

#ifndef BH1750_H
#define BH1750_H
#include "stm32f10x.h"
#include "sys.h"
#include "delay.h"
 
//IIC总线地址接口定义
#define IIC_SCL PBout(3)
#define IIC_SDA_OUT PAout(15)
#define IIC_SDA_IN PAin(15)
 
#define IIC_INPUT_MODE_SET()  {GPIOA->CRH&=0x0FFFFFFF;GPIOA->CRH|=0x80000000;}
#define IIC_OUTPUT_MODE_SET() {GPIOA->CRH&=0x0FFFFFFF;GPIOA->CRH|=0x30000000;}
 
#define  IIC_WRITE      0     // 写
#define  IIC_READ       1     // 读
#define	 SlaveAddress   0x46  //BH1750地址
extern u8  BUF[3];
//函数声明
void BH1750_IIC_Init(void);
void BH1750_Start();
void BH1750_Stop();
void BH1750_SendACK(char ack);
char BH1750_RecvACK();
void BH1750_SendByte(u8 data);
void Single_Write_BH1750(u8 REG_Address);
void Multiple_Read_BH1750();
float Get_Sunlight_Value();
u8 BH1750_RecvByte();
 
#endif

2.编写BH1750的主程序

代码如下(示例):

#include "BH1750.h"
#include "delay.h"
#include "usart.h"
/*
函数功能: IIC总线初始化
硬件连接:
        SCL-PB3
        SDA-PA15
*/
u8  BUF[3];
 
void BH1750_IIC_Init(void)
{
  /*1. 开时钟*/
	RCC->APB2ENR|=1<<2; //PA
	RCC->APB2ENR|=1<<3; //PB
	RCC->APB2ENR|=1<<0; //开启AFIO时钟
	
	/*2. 配置模式*/
	AFIO->MAPR |= 0x2<<24;//关闭JTAG-DP,启用SW-DP
	GPIOA->CRH&=0x0FFFFFFF;
	GPIOA->CRH|=0x30000000;
	GPIOB->CRL&=0xFFFF0FFF;
	GPIOB->CRL|=0x00003000;
	
	/*3. 上拉*/
	GPIOA->ODR|=0x1<<15;
	GPIOB->ODR|=0x1<<3;
	
	//printf("BH1750 IIC_Init OK! \n");
}
 
/**************************************
起始信号
**************************************/
void BH1750_Start()
{
	IIC_OUTPUT_MODE_SET(); //配置输出模式
	IIC_SDA_OUT = 1;       //拉高数据线
	IIC_SCL = 1;           //拉高时钟线
	delay_us(5);            //延时
	IIC_SDA_OUT = 0;       //产生下降沿
	delay_us(5);            //延时
	IIC_SCL = 0;           //拉低时钟线
}
 
/*
函数功能: 停止信号
*/
void BH1750_Stop()
{
	IIC_OUTPUT_MODE_SET(); 	//配置输出模式
	IIC_SDA_OUT = 0;        //拉低数据线
	IIC_SCL = 1;            //拉高时钟线
	delay_us(5);             //延时
	IIC_SDA_OUT = 1;        //产生上升沿
	delay_us(5);             //延时
}
 
/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void BH1750_SendACK(char ack)
{
	IIC_OUTPUT_MODE_SET(); 	  //配置输出模式
	IIC_SCL = 0;              //拉低时钟线
	if(ack) IIC_SDA_OUT = 1; 
	else IIC_SDA_OUT = 0;     //写应答信号
	delay_us(2);               //延时
	IIC_SCL = 1;              //拉高时钟线
	delay_us(5);               //延时
	IIC_SCL = 0;              //拉低时钟线
}
 
/**************************************
接收应答信号
**************************************/
char BH1750_RecvACK()
{
	u8 cnt=0;
	IIC_INPUT_MODE_SET();//输入模式
	IIC_SDA_OUT=1; 
	delay_us(1);
	IIC_SCL=1;
	delay_us(1);
	while(IIC_SDA_IN)//等待应答
	{
		cnt++;
		delay_us(1);
		if(cnt>=250)//等待时间过长,产生停止信号,返回1,表示接收应答失败
		{
			BH1750_Stop();
			//printf("N0 ACK\n");
			return 1;
		}
	}
	IIC_SCL=0;//应答成功,则SCL变低
	return 0;
}
 
/**************************************
向IIC总线发送一个字节数据
**************************************/
void BH1750_SendByte(u8 data)
{
	u8 i;
	IIC_OUTPUT_MODE_SET();
	IIC_SCL = 0;//拉低时钟线, 数据准备发送
	delay_us(2);//延时
	for (i=0;i<8;i++)//从高位开始一位一位地传送
	{
		if(data&0x80) IIC_SDA_OUT=1;//送数据口
		else IIC_SDA_OUT=0;
		data <<= 1;//移出数据的最高位
		IIC_SCL = 1; //拉高时钟线,发送数据
		delay_us(2);//延时
		IIC_SCL = 0;//拉低时钟线,数据发送完毕
		delay_us(2);//延时
	}
}
/**************************************
从IIC总线接收一个字节数据
**************************************/
u8 BH1750_RecvByte()
{
	u8 i;
	u8 data = 0;
	IIC_INPUT_MODE_SET();//使能内部上拉,准备读取数据,
	for (i=0;i<8;i++)//8位计数器
	{
		IIC_SCL=0;//置时钟线为低,准备接收数据位
		delay_us(2);//时钟低电平周期大于4.7μs
		IIC_SCL=1;//置时钟线为高使数据线上数据有效,主机开始读数据,从机不能再改变数据了,即改变SDA的电平
		data <<= 1;
		IIC_SCL = 1;//拉高时钟线
		if(IIC_SDA_IN) data|=0x01;//读数据               
		delay_us(1);//延时
	}
	IIC_SCL=0;
	return data;
}
 
void Single_Write_BH1750(u8 REG_Address)
{
	BH1750_Start();//起始信号
	BH1750_SendByte(SlaveAddress);//发送设备地址+写信号
	BH1750_RecvACK();
	BH1750_SendByte(REG_Address);//内部寄存器地址,请参考中文pdf22页 
	BH1750_RecvACK();
	BH1750_Stop();//发送停止信号
}
/*********************************************************
连续读出BH1750内部数据
*********************************************************/
void Multiple_Read_BH1750()
{   
  BH1750_Start();//起始信号
  BH1750_SendByte(SlaveAddress+1);//发送设备地址+读信号
	BH1750_RecvACK();
	BUF[0] = BH1750_RecvByte();//BUF[0]存储0x32地址中的数据
	BH1750_SendACK(0);
	BUF[1] = BH1750_RecvByte();//BUF[0]存储0x32地址中的数据
	BH1750_SendACK(1);
	BH1750_Stop();//停止信号
	delay_ms(5);
}
 
/*********************************************************
读出数据并合成实际光强值
*********************************************************/
float Get_Sunlight_Value()
{
	int dis_data=0;
	float temp;
	u8 i=0;
	Single_Write_BH1750(0x01);// power on
	Single_Write_BH1750(0x10);// H- resolution mode
	delay_ms(180);//延时180ms
	Multiple_Read_BH1750();//连续读出数据,存储在BUF中  
	for(i=0;i<3;i++)
	//printf("0X%X ",BUF[i]);
	dis_data=BUF[0];
	dis_data=(dis_data<<8)+BUF[1];//合成数据 
	temp=(float)dis_data/1.2;
	UsartPrintf(USART_DEBUG,"Sunlight=%0.2f lx\n",temp);
	return temp;
}

总结

以上就是今天要讲的内容,本文仅仅简单介绍BH1750的使用,在使用BH1750前要学好C语言和32单片机。
下面是一些参考资料:链接:https://pan.baidu.com/s/130FgxdHM6iHjuuoQNk_GEQ?pwd=jk07
提取码:jk07(f103-mini原理图)
链接:https://pan.baidu.com/s/1bBw2-GxwMST1IQwkkUEQQg?pwd=0pko
提取码:0pko (野火- 零死角玩转stm32)

物联沃分享整理
物联沃-IOTWORD物联网 » 使用BH1750(GY-302)光照传感器的方法

发表评论