写点什么

STM32+BH1750 光敏传感器获取光照强度

作者:DS小龙哥
  • 2022 年 7 月 19 日
  • 本文字数:3120 字

    阅读完需:约 10 分钟

一、环境介绍

MCU: STM32F103ZET6


光敏传感器: BH1750 数字传感器(IIC 接口)


开发软件: Keil5


代码说明: 使用 IIC 模拟时序驱动,方便移植到其他平台,采集的光照度比较灵敏. 合成的光照度返回值范围是 0~255。 0 表示全黑 255 表示很亮。


实测: 手机闪光灯照着的状态返回值是 245 左右,手捂着的状态返回值是 10 左右.


完整工程代码下载: https://download.csdn.net/download/xiaolong1126626497/18500653




二、BH1750 介绍




三、核心代码

BH1750 说明: ADDR 引脚接地,地址就是 0x46

3.1 iic.c

#include "iic.h"
/*函数功能:IIC接口初始化硬件连接:SDA:PB7SCL:PB6*/void IIC_Init(void){ RCC->APB2ENR|=1<<3;//PB GPIOB->CRL&=0x00FFFFFF; GPIOB->CRL|=0x33000000; GPIOB->ODR|=0x3<<6;}
/*函数功能:IIC总线起始信号*/void IIC_Start(void){ IIC_SDA_OUTMODE(); //初始化SDA为输出模式 IIC_SDA_OUT=1; //数据线拉高 IIC_SCL=1; //时钟线拉高 DelayUs(4); //电平保持时间 IIC_SDA_OUT=0; //数据线拉低 DelayUs(4); //电平保持时间 IIC_SCL=0; //时钟线拉低}

/*函数功能:IIC总线停止信号*/void IIC_Stop(void){ IIC_SDA_OUTMODE(); //初始化SDA为输出模式 IIC_SDA_OUT=0; //数据线拉低 IIC_SCL=0; //时钟线拉低 DelayUs(4); //电平保持时间 IIC_SCL=1; //时钟线拉高 DelayUs(4); //电平保持时间 IIC_SDA_OUT=1; //数据线拉高}
/*函数功能:获取应答信号返 回 值:1表示失败,0表示成功*/u8 IIC_GetACK(void){ u8 cnt=0; IIC_SDA_INPUTMODE();//初始化SDA为输入模式 IIC_SDA_OUT=1; //数据线上拉 DelayUs(2); //电平保持时间 IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据 DelayUs(2); //电平保持时间,等待从机发送数据 IIC_SCL=1; //时钟线拉高,告诉从机,主机现在开始读取数据 while(IIC_SDA_IN) //等待从机应答信号 { cnt++; if(cnt>250)return 1; } IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据 return 0;}
/*函数功能:主机向从机发送应答信号函数形参:0表示应答,1表示非应答*/void IIC_SendACK(u8 stat){ IIC_SDA_OUTMODE(); //初始化SDA为输出模式 IIC_SCL=0; //时钟线拉低,告诉从机,主机需要发送数据 if(stat)IIC_SDA_OUT=1; //数据线拉高,发送非应答信号 else IIC_SDA_OUT=0; //数据线拉低,发送应答信号 DelayUs(2); //电平保持时间,等待时钟线稳定 IIC_SCL=1; //时钟线拉高,告诉从机,主机数据发送完毕 DelayUs(2); //电平保持时间,等待从机接收数据 IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据}

/*函数功能:IIC发送1个字节数据函数形参:将要发送的数据*/void IIC_WriteOneByteData(u8 data){ u8 i; IIC_SDA_OUTMODE(); //初始化SDA为输出模式 IIC_SCL=0; //时钟线拉低,告诉从机,主机需要发送数据 for(i=0;i<8;i++) { if(data&0x80)IIC_SDA_OUT=1; //数据线拉高,发送1 else IIC_SDA_OUT=0; //数据线拉低,发送0 IIC_SCL=1; //时钟线拉高,告诉从机,主机数据发送完毕 DelayUs(2); //电平保持时间,等待从机接收数据 IIC_SCL=0; //时钟线拉低,告诉从机,主机需要发送数据 DelayUs(2); //电平保持时间,等待时钟线稳定 data<<=1; //先发高位 }}

/*函数功能:IIC接收1个字节数据返 回 值:收到的数据*/u8 IIC_ReadOneByteData(void){ u8 i,data; IIC_SDA_INPUTMODE();//初始化SDA为输入模式 for(i=0;i<8;i++) { IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据 DelayUs(2); //电平保持时间,等待从机发送数据 IIC_SCL=1; //时钟线拉高,告诉从机,主机现在正在读取数据 data<<=1; if(IIC_SDA_IN)data|=0x01; DelayUs(2); //电平保持时间,等待时钟线稳定 } IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据 (必须拉低,否则将会识别为停止信号) return data;}
复制代码


3.2 iic.h

#ifndef _IIC_H#define _IIC_H#include "stm32f10x.h"#include "sys.h"#include "delay.h"#define IIC_SDA_OUTMODE() {GPIOB->CRL&=0x0FFFFFFF;GPIOB->CRL|=0x30000000;}#define IIC_SDA_INPUTMODE() {GPIOB->CRL&=0x0FFFFFFF;GPIOB->CRL|=0x80000000;}#define IIC_SDA_OUT PBout(7)  //数据线输出#define IIC_SDA_IN PBin(7)  //数据线输入#define IIC_SCL PBout(6)  //时钟线
void IIC_Init(void);void IIC_Start(void);void IIC_Stop(void);u8 IIC_GetACK(void);void IIC_SendACK(u8 stat);void IIC_WriteOneByteData(u8 data);u8 IIC_ReadOneByteData(void);#endif
复制代码


3.3 BH1750.h

#ifndef _BH1750_H#define _BH1750_H#include "delay.h"#include "iic.h"#include "usart.h"u8 Read_BH1750_Data(void);#endif
复制代码


3.4 BH1750.c

#include "bh1750.h"u8 Read_BH1750_Data(){    unsigned char t0;    unsigned char t1;    unsigned char t;    u8 r_s=0;    IIC_Start(); //发送起始信号    IIC_WriteOneByteData(0x46);    r_s=IIC_GetACK();//获取应答    if(r_s)printf("error:1\r\n");    IIC_WriteOneByteData(0x01);    r_s=IIC_GetACK();//获取应答     if(r_s)printf("error:2\r\n");    IIC_Stop(); //停止信号         IIC_Start(); //发送起始信号    IIC_WriteOneByteData(0x46);    r_s=IIC_GetACK();//获取应答    if(r_s)printf("error:3\r\n");    IIC_WriteOneByteData(0x01);    r_s=IIC_GetACK();//获取应答    if(r_s)printf("error:4\r\n");    IIC_Stop(); //停止信号         IIC_Start(); //发送起始信号    IIC_WriteOneByteData(0x46);    r_s=IIC_GetACK();//获取应答    if(r_s)printf("error:5\r\n");    IIC_WriteOneByteData(0x10);    r_s=IIC_GetACK();//获取应答    if(r_s)printf("error:6\r\n");    IIC_Stop(); //停止信号         DelayMs(300); //等待        IIC_Start(); //发送起始信号    IIC_WriteOneByteData(0x47);    r_s=IIC_GetACK();//获取应答    if(r_s)printf("error:7\r\n");        t0=IIC_ReadOneByteData(); //接收数据    IIC_SendACK(0); //发送应答信号    t1=IIC_ReadOneByteData(); //接收数据    IIC_SendACK(1); //发送非应答信号    IIC_Stop(); //停止信号         t=(((t0<<8)|t1)/1.2);     return t;  }
复制代码


3.5 main.c

#include "stm32f10x.h"#include "led.h"#include "delay.h"#include "key.h"#include "usart.h"#include "at24c02.h"#include "bh1750.h"
int main(){ u8 val; LED_Init(); BEEP_Init(); KeyInit(); USARTx_Init(USART1,72,115200); IIC_Init(); while(1) { val=KeyScan(); if(val) { val=Read_BH1750_Data(); printf("光照强度=%d\r\n",val);// BEEP=!BEEP; LED0=!LED0; LED1=!LED1; } }}
复制代码


3.6 运行效果图


发布于: 刚刚阅读数: 3
用户头像

DS小龙哥

关注

之所以觉得累,是因为说的比做的多。 2022.01.06 加入

熟悉C/C++、51单片机、STM32、Linux应用开发、Linux驱动开发、音视频开发、QT开发. 目前已经完成的项目涉及音视频、物联网、智能家居、工业控制领域

评论

发布
暂无评论
STM32+BH1750光敏传感器获取光照强度_7月月更_DS小龙哥_InfoQ写作社区