打印
[其他ST产品]

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

[复制链接]
297|11
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
一、环境介绍
MCU:  STM32F103ZET6

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

开发软件: Keil5

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

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

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



使用特权

评论回复
沙发
是你的乱码|  楼主 | 2023-1-15 23:26 | 只看该作者

使用特权

评论回复
板凳
是你的乱码|  楼主 | 2023-1-15 23:27 | 只看该作者
BH1750介绍

使用特权

评论回复
地板
是你的乱码|  楼主 | 2023-1-15 23:28 | 只看该作者

使用特权

评论回复
5
是你的乱码|  楼主 | 2023-1-15 23:29 | 只看该作者

使用特权

评论回复
6
是你的乱码|  楼主 | 2023-1-15 23:30 | 只看该作者
核心代码
BH1750说明:  ADDR引脚接地,地址就是0x46

使用特权

评论回复
7
是你的乱码|  楼主 | 2023-1-15 23:31 | 只看该作者
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;
}

使用特权

评论回复
8
是你的乱码|  楼主 | 2023-1-15 23:31 | 只看该作者
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

使用特权

评论回复
9
是你的乱码|  楼主 | 2023-1-15 23:32 | 只看该作者
BH1750.h
#ifndef _BH1750_H
#define _BH1750_H
#include "delay.h"
#include "iic.h"
#include "usart.h"
u8 Read_BH1750_Data(void);
#endif

使用特权

评论回复
10
是你的乱码|  楼主 | 2023-1-15 23:33 | 只看该作者
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;  
}

使用特权

评论回复
11
是你的乱码|  楼主 | 2023-1-15 23:34 | 只看该作者
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;
                }
        }
}

使用特权

评论回复
12
是你的乱码|  楼主 | 2023-1-15 23:35 | 只看该作者
运行效果图

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

19

主题

263

帖子

1

粉丝