首页 > 其他分享 >BH1750光照强度传感器详解(STM32)

BH1750光照强度传感器详解(STM32)

时间:2024-12-17 21:48:00浏览次数:11  
标签:SCL BH1750 光照强度 void STM32 SDA IIC GPIO

传感器介绍

BH1750是一款数字型光照强度传感器,能够获取周围环境的光照强度。内置16bitAD转换器,其测量范围在0~65535 lx(勒克斯,光照强度的单位),不区分环境光源。BH1750可用于调节手机屏幕和键盘的背光功率,或者用于智能灯光控制,比如,随着外界光照强度的变化调节灯光亮度。

 

 

以下是BH1750光照传感器的参数:

    

供电电压 

DC:3-5V

供给电流

200uA

工作温度

-40~+85℃

测量分辨率

0~65535 lx

接口

IIC

最小误差变动

20%

尺寸

13.9mm×18.5mm(GY-302)

15.1mm×32.6mm(GY-20)

 传感器原理

 

 

 

1.原理图

 

以下是传感器的引脚描述:

 

引脚名称

描述

VCC

供给电压3~5V

SCL

I2C总线时钟线

SDA

I2C总线数据线

ADDR

I2C地址引脚

GND

电源地

 

2.工作原理(结构框图)

 

  • PD —— 接近人眼反应的光敏二极管

  • AMP —— 集成运算放大器(将PD电流转换为PD电压)

  • ADC —— 模数转换获取16位数字数据

  • Logic + I2C Interface(逻辑+I2C界面)

  • OSC —— 内部振荡器(内部逻辑时钟,频率典型值:320kHz)

 

PD二极管通过光伏效应将输入光信号转换成电信号,经运放电路放大后,电压经ADC采集,再经逻辑电路转换成16位二进制数,存储在内部的寄存器中。

BH1750引出了时钟线和数据线,单片机可以通过I2C协议与BH1750进行通讯,可选择BH1750的工作模式,提取BH1750寄存器中的照度数据

程序设计 

 

1. main.c文件

#include "stm32f10x.h"#include "led.h"#include "usart.h"#include "delay.h"#include "oled.h"#include "bh1750.h"
/*****************毕业设计****************** STM32 * 项目 : 2.BH1750光照强度传感器实验 * 版本 : V1.0 * 日期 : 2024.8.5 * MCU : STM32F103C8T6 * 接口 : 参看bh1750.h
**********************BEGIN***********************/
u16 light;u8 buff[30];
int main(void){ SystemInit();//配置系统时钟为72M delay_init(72); LED_Init(); LED_On();
USART1_Config();//串口初始化 OLED_Init(); BH1750_Init(); printf("Start \n"); delay_ms(1000);
//显示“光照强度:” OLED_ShowChinese(1,1, 4); OLED_ShowChinese(1,2, 5); OLED_ShowChinese(1,3, 34); OLED_ShowChinese(1,4, 1); OLED_ShowChar(1, 9, ':'); while (1) { light = bh_data_read(); printf("光照强度: %d \r\n",light); LED_Toggle(); sprintf((char *)buff,"%5d",light); OLED_ShowString(1,10,buff); delay_ms(500);
}}

 

2. bh1750.h文件

#ifndef __BH1750_H#define __BH1750_H#include "sys.h"#include "delay.h"
/*****************毕业设计****************** STM32 * 文件 : BH1750光照强度传感器h文件 * 版本 : V1.0 * 日期 : 2024.8.5 * MCU : STM32F103C8T6 * 接口 : 见代码
**********************BEGIN***********************/
/***************根据自己需求更改****************///BH1750引脚宏定义#define BH1750_GPIO_CLK RCC_APB2Periph_GPIOB#define BH1750_GPIO_PORT GPIOB#define BH1750_SCL_GPIO_PIN GPIO_Pin_13#define BH1750_SDA_GPIO_PIN GPIO_Pin_12
#define IIC_SCL PBout(13) //SCL#define IIC_SDA PBout(12) //SDA #define READ_SDA PBin(12) //输入SDA #define ADDR 0x23//0100011#define uchar unsigned char /*********************END**********************/
#define BHAddWrite 0x46 //从机地址+最后写方向位#define BHAddRead 0x47 //从机地址+最后读方向位#define BHPowDown 0x00 //关闭模块#define BHPowOn 0x01 //打开模块等待测量指令#define BHReset 0x07 //重置数据寄存器值在PowerOn模式下有效#define BHModeH1 0x10 //高分辨率 单位1lx 测量时间120ms#define BHModeH2 0x11 //高分辨率模式2 单位0.5lx 测量时间120ms#define BHModeL 0x13 //低分辨率 单位4lx 测量时间16ms#define BHSigModeH 0x20 //一次高分辨率 测量 测量后模块转到 PowerDown模式#define BHSigModeH2 0x21 //同上类似#define BHSigModeL 0x23 // 上类似
void Single_Write_BH1750(uchar REG_Address);void BH1750_Init(void);void bh_data_send(u8 command);u16 bh_data_read(void);
//IIC所有操作函数void BH1750_IIC_Init(void); //初始化IIC的IO口 void BH1750_IIC_Start(void); //发送IIC开始信号void BH1750_IIC_Stop(void); //发送IIC停止信号void BH1750_IIC_Send_Byte(u8 txd); //IIC发送一个字节u8 BH1750_IIC_Read_Byte(unsigned char ack);//IIC读取一个字节u8 BH1750_IIC_Wait_Ack(void); //IIC等待ACK信号void BH1750_IIC_Ack(void); //IIC发送ACK信号void BH1750_IIC_NAck(void); //IIC不发送ACK信号
void BH1750_IIC_Write_One_Byte(u8 daddr,u8 addr,u8 data);u8 BH1750_IIC_Read_One_Byte(u8 daddr,u8 addr);
#endif

 

3. bh1750.c文件

#include "BH1750.h"#include "delay.h"
/*****************毕业设计****************** STM32 * 文件 : BH1750光照强度传感器h文件 * 版本 : V1.0 * 日期 : 2024.8.5 * MCU : STM32F103C8T6 * 接口 : 见代码
**********************BEGIN***********************/
typedef unsigned char BYTE;//BYTE BUF[8]; //接收数据缓存区 //iic接口初始化
/**** 设置SDA为输出**/void SDA_OUT(void){ GPIO_InitTypeDef GPIO_InitStructer; GPIO_InitStructer.GPIO_Pin= BH1750_SDA_GPIO_PIN; GPIO_InitStructer.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructer.GPIO_Mode=GPIO_Mode_Out_PP; GPIO_Init(BH1750_GPIO_PORT, &GPIO_InitStructer);}

/**** 设置SDA为输入**/void SDA_IN(void){ GPIO_InitTypeDef GPIO_InitStructer; GPIO_InitStructer.GPIO_Pin= BH1750_SDA_GPIO_PIN; GPIO_InitStructer.GPIO_Speed=GPIO_Speed_50MHz; GPIO_InitStructer.GPIO_Mode=GPIO_Mode_IPU; GPIO_Init(BH1750_GPIO_PORT, &GPIO_InitStructer);}

void Single_Write_BH1750(uchar REG_Address){ BH1750_IIC_Start(); //起始信号 BH1750_IIC_Send_Byte(BHAddWrite); //发送设备地址+写信号 BH1750_IIC_Send_Byte(REG_Address); //内部寄存器地址, // BH1750_SendByte(REG_data); //内部寄存器数据, BH1750_IIC_Stop(); //发送停止信号}
void BH1750_Init(void){ GPIO_InitTypeDef GPIO_InitStructure;
RCC_APB2PeriphClockCmd(BH1750_GPIO_CLK, ENABLE); //使能A端口时钟 GPIO_InitStructure.GPIO_Pin = BH1750_SCL_GPIO_PIN|BH1750_SDA_GPIO_PIN; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; //推挽输出 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;//速度50MHz GPIO_Init(BH1750_GPIO_PORT, &GPIO_InitStructure); //初始化GPIOD3,6 GPIO_SetBits(BH1750_GPIO_PORT,BH1750_SCL_GPIO_PIN|BH1750_SDA_GPIO_PIN);
//Single_Write_BH1750(0x01); bh_data_send(BHPowOn); //BH1750上电 bh_data_send(BHReset); //BH1750复位 bh_data_send(BHModeH2); //BH1750写入测量模式:选择的是分辨率是4lx,测量时间是16ms的}
//产生IIC起始信号void BH1750_IIC_Start(void){ SDA_OUT(); //sda线输出 IIC_SDA=1; IIC_SCL=1; delay_us(4); IIC_SDA=0;//START:when CLK is high,DATA change form high to low delay_us(4); IIC_SCL=0;//钳住I2C总线,准备发送或接收数据 } //产生IIC停止信号void BH1750_IIC_Stop(void){ SDA_OUT();//sda线输出 IIC_SCL=0; IIC_SDA=0;//STOP:when CLK is high DATA change form low to high delay_us(4); IIC_SCL=1; IIC_SDA=1;//发送I2C总线结束信号 delay_us(4); }//等待应答信号到来//返回值:1,接收应答失败// 0,接收应答成功u8 BH1750_IIC_Wait_Ack(void){ u8 ucErrTime=0; SDA_IN(); //SDA设置为输入 IIC_SDA=1;delay_us(1); IIC_SCL=1;delay_us(1); while(READ_SDA) { ucErrTime++; if(ucErrTime>250) { BH1750_IIC_Stop(); return 1; } } IIC_SCL=0;//时钟输出0 return 0; } //产生ACK应答void BH1750_IIC_Ack(void){ IIC_SCL=0; SDA_OUT(); IIC_SDA=0; delay_us(2); IIC_SCL=1; delay_us(2); IIC_SCL=0;}//不产生ACK应答 void BH1750_IIC_NAck(void){ IIC_SCL=0; SDA_OUT(); IIC_SDA=1; delay_us(2); IIC_SCL=1; delay_us(2); IIC_SCL=0;} //IIC发送一个字节//返回从机有无应答//1,有应答//0,无应答 void BH1750_IIC_Send_Byte(u8 txd){ u8 t; SDA_OUT(); IIC_SCL=0;//拉低时钟开始数据传输 for(t=0;t<8;t++) { //IIC_SDA=(txd&0x80)>>7; if((txd&0x80)>>7) IIC_SDA=1; else IIC_SDA=0; txd<<=1; delay_us(2); //对TEA5767这三个延时都是必须的 IIC_SCL=1; delay_us(2); IIC_SCL=0; delay_us(2); } } //读1个字节,ack=1时,发送ACK,ack=0,发送nACK u8 BH1750_IIC_Read_Byte(unsigned char ack){ unsigned char i,receive=0; SDA_IN();//SDA设置为输入 for(i=0;i<8;i++ ) { IIC_SCL=0; delay_us(2); IIC_SCL=1; receive<<=1; if(READ_SDA)receive++; delay_us(1); } if (!ack) BH1750_IIC_NAck();//发送nACK else BH1750_IIC_Ack(); //发送ACK return receive;}
/*************************************************************************************/void bh_data_send(u8 command){ do{ BH1750_IIC_Start(); //iic起始信号 BH1750_IIC_Send_Byte(BHAddWrite); //发送器件地址 }while(BH1750_IIC_Wait_Ack()); //等待从机应答 BH1750_IIC_Send_Byte(command); //发送指令 BH1750_IIC_Wait_Ack(); //等待从机应答 BH1750_IIC_Stop(); //iic停止信号}
u16 bh_data_read(void){ u16 buf; BH1750_IIC_Start(); //iic起始信号 BH1750_IIC_Send_Byte(BHAddRead); //发送器件地址+读标志位 BH1750_IIC_Wait_Ack(); //等待从机应答 buf=BH1750_IIC_Read_Byte(1); //读取数据 buf=buf<<8; //读取并保存高八位数据 buf+=0x00ff&BH1750_IIC_Read_Byte(0); //读取并保存第八位数据 BH1750_IIC_Stop(); //发送停止信号 return buf; }

实验演示

 

 

 

 

标签:SCL,BH1750,光照强度,void,STM32,SDA,IIC,GPIO
From: https://www.cnblogs.com/jefften/p/18613437

相关文章

  • 【STM32练习】基于STM32的PM2.5环境监测系统
    一.项目背景    最近为了完成老师交付的任务,遂重制了一下小项目用STM32做一个小型的环境监测系统。    项目整体示意框图如下:二.器件选择单片机(STM32F103)数字温湿度模块(DHT11)液晶显示模块(0.8寸OLED)粉尘传感器模块(GP2Y10)报警模块(蜂鸣器)按键控制模块(独立按......
  • stm32读写外部flash失败怎么回事
    STM32读写外部Flash失败可能由多种原因引起,以下是一些常见的问题及其解决方案:一、硬件连接问题SPI接口连接错误:确保STM32的SPI接口与外部Flash的连接正确,包括时钟线(SCK)、数据线(MOSI、MISO)以及片选线(CS)。检查连接是否松动或存在断路。电源和地连接:确保外部Flash......
  • 江科大STM32学习:06 TIM输出比较
    1.输出比较简介OC(OutputCompare)输出比较输出比较可以通过比较CNT和CCR寄存器值得关系,来对输出电平进行置1、置0或反转得操作,用于输出一定频率和占空比得PWM波形每个高级定时器和通用定时器都拥有4个输出比较通道高级定时器得前三个通道额外拥有死区生成和互补输出的功能2......
  • 江科大STM32学习:07 定时器输入捕获
    本节对应STM32F10XXX参考手册中的14.3.5输入捕获模式和14.3.6PWM输入模式1.输入捕获简介IC(InputCapture)输入捕获输出比较可以通过比较CNT与CCR寄存器值的关系,来对输出电平进行置1、置0或翻转的操作,用于输出一定频率和占空比的PWM波形输入捕获模式下,当通道输入引脚出......
  • 基于STM32F103的数字电压表设计
    基于STM32F103的数字电压表设计仿真软件:      Proteus8.17编程软件:      Keil5仿真实现:      使用STM32F103的内部ADC(模数转换器)测量外部电压(用电位器来进行电压的改变),将测量到的电压值显示在数码管上,同事与仿真中的电压表进行对比,误差很小。......
  • STM32F407ZGT6-UCOSIII笔记2:UCOSIII任务创建实验-Printf 函数卡住 UCOSIII 系统问题解
    今日简单编写熟悉一下UCOSIII系统的任务创建代码,理解一下OS系统:并发现以及解决了Printf函数卡住UCOSIII系统问题解决文章提供测试代码讲解、完整工程下载、测试效果图目录文件结构解释:任务函数文件:目前各个文件任务:#include"main.h"#include"ComTask.h"#includ......
  • STM32卡死、跑飞、进入HardFault_Handler如何精准的确定问题
    目录前言一、程序跑飞原因软件原因1.堆栈溢出2.指针操作错误3.中断优先级配置错误4.外设错误配置5.存储器管理问题6.代码逻辑错误7.时钟配置错误8.Watchdog超时硬件原因1.电气问题2.硬件故障软件复位与硬件问题结合二、调试工具如何进入仿真?进入......
  • Proteus基于STM32的联网楼宇智能灯光防火检测控制系统
    基于STM32的联网楼宇智能灯光防火检测控制系统感觉有帮助的点个赞谢谢演示视频:【Proteus仿真大赛】基于stm32的联网楼宇智能灯光防火检测控制系统系统方案设计设计背景与系统功能目前,‌现代楼宇普遍存在的问题主要包括房间数量众多、‌走廊通道长度较长,‌这使得......
  • STM32学习笔记(四)TIM定时中断、PWM的简单应用(舵机、直流电机)
    一、TIM简介定时器(Timer,简称TIM)是STM32中非常重要的外设之一,广泛应用于定时、计数、PWM输出、事件触发等多种场景。STM32提供了多个定时器,每个定时器的功能和性能有所不同,但基本原理类似。定时器的工作原理是通过不断计数来产生定时事件,计数器会在每个周期到达预设值时......
  • STM32F103c8t6基于I2C协议的AHT20温湿度传感器的数据采集
    STM32F103c8t6基于I2C协议的AHT20温湿度传感器的数据采集一、了解I2C总线通信协议1、软件I2C2、硬件I2C二、工程建立1、设计要求2、STM32CubeMX的环境配置(一)STM32CubeMX的配置(二)KEIL配置三、代码编写1、AHT20-21_DEMO_V1_3.h2、AHT20-21_DEMO_V1_3.c3、main.c四、硬......