2025年4月17日 星期四 乙巳(蛇)年 正月十八 设为首页 加入收藏
rss
您当前的位置:首页 > 电子 > 单片机

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

时间:11-20来源:作者:点击数:18
CDSY,CDSY.XYZ

一、环境介绍

MCU:  STM32F103ZET6

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

开发软件: Keil5

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

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

二、BH1750介绍

三、核心代码

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

3.1 iic.c

  • #include "iic.h"
  • /*
  • 函数功能:IIC接口初始化
  • 硬件连接:
  • SDA:PB7
  • SCL: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  运行效果图 

CDSY,CDSY.XYZ
方便获取更多学习、工作、生活信息请关注本站微信公众号城东书院 微信服务号城东书院 微信订阅号
推荐内容
相关内容
栏目更新
栏目热门
本栏推荐