加入星计划,您可以享受以下权益:

  • 创作内容快速变现
  • 行业影响力扩散
  • 作品版权保护
  • 300W+ 专业用户
  • 1.5W+ 优质创作者
  • 5000+ 长期合作伙伴
立即加入

STM32传感器外设集-光照传感器(BH1750)

05/10 10:00
8013
服务支持:
技术交流群

完成交易后在“购买成功”页面扫码入群,即可与技术大咖们分享疑惑和经验、收获成长和认同、领取优惠和红包等。

虚拟商品不可退

当前内容为数字版权作品,购买后不支持退换且无法转移使用。

加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论
放大
实物图
相关方案
  • 方案介绍
    • 资源获取
    • 参考
  • 相关文件
  • 推荐器件
  • 相关推荐
  • 电子产业图谱
申请入驻 产业图谱

介绍

BH1750是一款数字式环境光传感器,能够准确地测量环境光的亮度。BH1750采用数字式输出,具有高精度、快速响应、低功耗的特点,广泛应用于照明自动控制、智能设备、电子识别等领域。BH1750能简化光控设计,接口方便,采用I2C总线通信协议,支持多种测量模式,并可通过设置来调整测量灵敏度。BH1750工作温度范围广,适用于各种环境。除此之外,BH1750还有很多其他的特性,如可控制的精度、可选的地址引脚、多种输出范围等。在物联网智能家居等领域,BH1750正在发挥越来越重要的作用。

原理图

资源获取

欢迎关注微信公众号--星之援工作室 发送关键字(BH1750)

main.c

/**
  * @brief  主函数
  * @param  无  
  * @retval 无
  */
int main(void)
{
	

	/* 初始化系统时钟*/
	SysTick_Init();
  delay_init();//初始化延时函数
	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);	
	USART_Config();//初始化串口1
	printf("rn***  bh1750传感器实验***rn");
	bh1750_Init();//初始化bh1750
	
	while(1)
	{	
		light=getValue();
		UsartPrintf(DEBUG_USARTx,"光照:%d",light);	//打印串口数据	,再加一个光照强度%d    light	
			
		Delay_ms(2000);
	}

	
}

BH1750.h

#ifndef __BH1750_I2C_H
#define __BH1750_I2C_H

#include "stm32f10x.h"
/************************************
*	连接   VCC-->3.3V      GND-->GND
*	 ADDR----->GND
*    SCL ----->pb6
*    sda ----->pb5
*************************************/
 
 
//IO方向设置
//#include "SysTick.h"
#include "time.h"
#include "./usart/bsp_usart.h"
#define BH1750_SDA_IN()  {GPIOB->CRL&=0XFF0FFFFF;GPIOB->CRL|=(u32)8<<20;}
#define BH1750_SDA_OUT() {GPIOB->CRL&=0XFF0FFFFF;GPIOB->CRL|=(u32)3<<20;}
 
//IO操作函数	 
#define BH1750_IIC_SCL    PBout(6) //SCL
#define BH1750_IIC_SDA    PBout(5) //SDA	 
#define BH1750_READ_SDA   PBin(5)  //输入SDA 
 
#define	  BH1750_SlaveAddress   0x46 //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改
                                     //ALT  ADDRESS引脚接地时地址为0x46,接电源时地址为0xB8
 
 
 
extern float lux;
 
void bh1750_iic_init(void);
void bh1750_iic_start(void);
void bh1750_iic_stop(void);
void bh1750_send_ack(char ack);
char bh1750_recv_ack(void);
void bh1750_send_byte(char dat);
char bh1750_recv_byte(unsigned char ack);
 
void bh1750_iic_init(void);
void Single_Write_bh1750(unsigned char Reg_Address);
void bh1750_Init(void);
void bh1750_ReadOneTime(void);
void bh1750_ReadContinuous1(void);
u8 getValue(void);

#endif /* __BH1750_I2C_H */


BH1750.c

#include "BH1750.h"
#include "sys.h"
#include "delay.h"
u8 BUF[8];
u16 temp2=0;
float lux=0;
void bh1750_iic_init(void)
{
	GPIO_InitTypeDef GPIO_InitStructure;
	RCC_APB2PeriphClockCmd(	RCC_APB2Periph_GPIOB, ENABLE );	//使能GPIOB时钟
	   
	GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5|GPIO_Pin_6;
	GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出
	GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOB, &GPIO_InitStructure);
	GPIO_SetBits(GPIOB,GPIO_Pin_5|GPIO_Pin_6); 	//PB6,PB7 输出高
 
}
 
/****向BH1750单次写命令****/
void Single_Write_bh1750(unsigned char Reg_Address)
{
	bh1750_iic_start();
	bh1750_send_byte(0x46);  //发送器件地址0100 0110   最后一位0,表示写
	//IIC_Wait_Ack();
	bh1750_send_byte(Reg_Address);  
	//IIC_Wait_Ack();
	bh1750_iic_stop();
}
 
/****BH1750初始化****/
void bh1750_Init(void)
{
	
//	TIM4_PWM_Init(899,0);
	bh1750_iic_init();
	TIM_SetCompare3(TIM3,0);	
}
 
//光照强度数据接收和处理
u8 getValue(void)
{
	unsigned char value=0;
	Single_Write_bh1750(0x01);
	Single_Write_bh1750(0x10);
	delay_ms(200);
	bh1750_ReadContinuous1();
	temp2=BUF[0];
	temp2=(temp2<<8)+BUF[1];
	lux=(float)temp2/1.2;    //lux是float型	
	if((lux>0)&&(lux<50))
		value=10;
	else if(lux<75)
		value=20;
	else if(lux<100)
		value=40;
	else if(lux<125)
		value=50;
	else if(lux<150)
		value=60;
	else if(lux<175)
		value=70;
	else if(lux<200)
		value=80;
	else if(lux<250)
		value=90;
	else if(lux<280)
		value=110;
	else if(lux<300)
		value=120;
	else if(lux<320)
		value=130;
	else if(lux<340)
		value=140;
	else if(lux<360)
		value=150;
	else if(lux<380)
		value=160;
	else if(lux<400)
		value=170;
	else if(lux<410)
		value=180;
	else if(lux<450)
		value=190;	
	else if(lux<800)
		value=240;
	//printf("光照强度:%f   value:%drn",lux,value);
	TIM_SetCompare3(TIM3,value);
	return value;
	
	//Delay_ms(1000);
}
/****从BH1750单次读Lux****/
/****
模式选择:H-Resolution Mode,分辨率1lux
单次读Opecode:0010 0000 ,即0x20
器件地址:0100011,ADDR接GND
****/
void bh1750_ReadOneTime(void)
{
	
 
	bh1750_iic_start();
	bh1750_send_byte(0x46);  //发送器件地址0100 0110   最后一位0,表示写
	bh1750_recv_ack();
	bh1750_send_byte(0x20);   //发送One time H-Resolution Mode的Opecode 0010 0000,分辨率为1lux
	bh1750_recv_ack();
	bh1750_iic_stop();
	delay_ms(200);
	bh1750_iic_start();
	bh1750_send_byte(0x47);  //
	bh1750_recv_ack();
	BUF[0]=bh1750_recv_byte(1);
	//IIC_Ack();        //主机应答
	//temp1=temp<<8;
	BUF[1]=bh1750_recv_byte(0);
	//IIC_NAck();        //主机不应答	
	bh1750_iic_stop();
	
	
// 	temp2=BUF[0];
// 	temp2=(temp2<<8)+BUF[1];
// 	lux=(float)temp2/1.2;    //lux是float型
	
	//return lux;
	//Delay_ms(200);
}
 
/****从BH1750连续读Lux****/
/****
模式选择:H-Resolution Mode,分辨率1lux
连续读Opecode:0001 0000
器件地址:0100011,ADDR接GND
****/
void  bh1750_ReadContinuous1(void)
{
//	u16 temp=0,temp1=0;
	bh1750_iic_start();
  bh1750_send_byte(0x46);  //发送器件地址0100 0110   最后一位0,表示写
	bh1750_recv_ack();
	bh1750_send_byte(0x10);  //发送Continuous H-Resolution Mode的Opecode 0001 0000,分辨率为1lux
	bh1750_recv_ack();
	bh1750_iic_stop();
	delay_ms(200);
	bh1750_iic_start();
  bh1750_send_byte(0x47);  
	bh1750_recv_ack();
	
	
 	BUF[0]=bh1750_recv_byte(1);
	BUF[1]=bh1750_recv_byte(0);	
	
	
	//temp=bh1750_recv_byte(1);
	//temp1=bh1750_recv_byte(0);
 
 
	bh1750_iic_stop();
	
	//temp2=temp1+(temp<<8);
	//lux=(float)temp2/1.2;    //lux是float型
 
 
}
 
void Conversion(void)
{
	temp2=BUF[0];
	temp2=(temp2<<8)+BUF[1];
	lux=(float)temp2/1.2;    //lux是float型
	
}
 
 
 
/**************************************
起始信号
**************************************/
void bh1750_iic_start(void)
{
		BH1750_SDA_OUT()       //设置SDA线为输出
	//在开始数据传输前,先让SDA和SCL都拉高
		BH1750_IIC_SDA=1;    //发送起始条件的数据信号,释放总线
	  delay_us(2);
		BH1750_IIC_SCL=1;    
 
		delay_us(5);   //Tsu;STA:起始条件的建立时间大于4.7us。
	
		BH1750_IIC_SDA=0;    //SDA由高变为低表示开始信号
		delay_us(4);   //起始条件的保持时间大于4us
		BH1750_IIC_SCL=0;    //钳住IIC总线,准备发送或者接收数据
		delay_us(2);
}
 
/**************************************
停止信号
**************************************/
void bh1750_iic_stop(void)
{
	BH1750_SDA_OUT()       //设置SDA线为输出
	
	//IIC_SCL=0;    //此句是调试BH1750时加,2018.03.03
	
	BH1750_IIC_SDA=0;   //发送停止信号的数据信号
	delay_us(2);
	BH1750_IIC_SCL=1;   //发送停止信号的时钟信号
	delay_us(5);  //停止信号的建立时间大于4us
	BH1750_IIC_SDA=1;   //发送停止信号
	delay_us(4);    //;
}
 
/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void bh1750_send_ack(char ack)
{
	BH1750_IIC_SCL=0;
	BH1750_SDA_OUT();
	BH1750_IIC_SDA=ack;   //主器件应答
	delay_us(2);
	BH1750_IIC_SCL=1;
	delay_us(4);        //SCL高电平周期大于4us
	BH1750_IIC_SCL=0;         //清时钟线,钳住IIC总线以便继续接收
	delay_us(2);
 
}
 
/**************************************
接收应答信号
**************************************/
char bh1750_recv_ack(void)
{
	u8 ucErrorTime=0;
	BH1750_SDA_IN();     //SDA设置成输入
	BH1750_IIC_SDA=1;
	delay_us(2);
	BH1750_IIC_SCL=1;
	delay_us(2);
	while(BH1750_READ_SDA)
	{
		ucErrorTime++;
		if(ucErrorTime>=250)
		{
			bh1750_iic_stop();
			return 1;		
		}
	}
	BH1750_IIC_SCL=0;
	return 0;
}
 
/**************************************
向IIC总线发送一个字节数据
**************************************/
void bh1750_send_byte(char dat)
{
	u8 i;
	BH1750_SDA_OUT();  
 
	for(i=0;i<8;i++)
	{
		if((dat<<i)&0x80)  BH1750_IIC_SDA=1;   //判断发送位
		else BH1750_IIC_SDA=0;
 
		delay_us(2);
		BH1750_IIC_SCL=1;     //拉高SCL,通知被控器开始接收数据位
		delay_us(4);   //保证SCL高电平周期大于4us
		BH1750_IIC_SCL=0;    //拉低SCL,允许SDA传输下一位数据。因为只有在SCL=0时才允许SDA的状态发生变化
	  delay_us(2);
   }
	 //以下四句是调试BH1750时添加的,2018.03.03
	 //特别注意;用方法三时,以下四句不可去掉,去掉后得到的数有问题
	 //用方法二时,以下四句需注释掉,否则也会有问题,至于原因暂时还不清楚。
// 	 IIC_SDA=0;
// 	 Delay_us(2);
// 	 IIC_SCL=1;
// 	 Delay_us(2);
	 
	 BH1750_IIC_SCL=0;      //拉低SCL,为下次数据传输做好准备
	 delay_us(2);
}
 
/**************************************
从IIC总线接收一个字节数据
用来接收从器件传来的数据,ack为1时,发送Ack(产生应答);ack为0时,发送NAck(不产生应答)
**************************************/
char bh1750_recv_byte(unsigned char ack)
{
	unsigned char i,receive=0;
	BH1750_SDA_IN();    
	for(i=0;i<8;i++)
	{
		BH1750_IIC_SCL=0;    //置SCL为低,准备接收数据位
		delay_us(5);  //时钟低电平周期大于4.7us
		BH1750_IIC_SCL=1;   //置SCL为高,使SDA上数据有效
		delay_us(2);
		receive=receive<<1;
		if(BH1750_READ_SDA) receive=receive+1;    //读取SDA,把接收的数据位放入receve中,若此处写成IIC_SDA==1,会失败,思考原因?	
		delay_us(2);
  }
	if(!ack) 
		bh1750_send_ack(1);   //发送NAck
	else 
		bh1750_send_ack(0);    //发送Ack
	//IIC_SCL=0;      //在此处有何用处???(猜测:为下次数据传输做好准备, //钳住IIC总线,准备发送或者接收数据)
	//Delay_us(2);
	return receive;
}



/*************************************END OF FILE******************************/

参考

BH1750( GY-302 )光照传感器icon-default.png?t=N7T8https://blog.csdn.net/Dustinthewine/article/details/127540711?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170212703316800186517198%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=170212703316800186517198&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-127540711-null-null.142^v96^pc_search_result_base7&utm_term=bh1750&spm=1018.2226.3001.4187

联系方式 微信号:13648103287

  • 联系方式.docx

推荐器件

更多器件
器件型号 数量 器件厂商 器件描述 数据手册 ECAD模型 风险等级 参考价格 更多信息
MPXAZ6115AP 1 Rochester Electronics LLC ABSOLUTE, PEIZORESISTIVE PRESSURE SENSOR, 2.2-16.7Psi, 1.5%, 0.20-4.80V, SQUARE, SURFACE MOUNT, PLASTIC, SOP-8
$17.12 查看
MPX2100AP 1 Motorola Semiconductor Products Peizoresistive Sensor, Absolute, 0Psi Min, 14.5Psi Max, 1%, 0-40mV, Through Hole Mount, UNIBODY PACKAGE-4
$17.08 查看
HMC6343 1 Honeywell Microelectronics & Precision Sensors Magnetoresistive Sensor, 0.2mT Max, Plastic/epoxy, Square, 32 Pin, Surface Mount, LCC-32

ECAD模型

下载ECAD模型
$157.21 查看

相关推荐

电子产业图谱

方案定制,程序设计方案、单片机程序设计与讲解、APP定制开发。本公众号致力于向读者传递关于程序设计和开发的相关知识,并分享一些关于软件开发的最佳实践。如果您有什么问题或建议,请随时联系我们。我们将竭诚为您服务