天天看點

STM32+BH1750光敏傳感器擷取光照強度

一、環境介紹

MCU:  STM32F103ZET6

光敏傳感器: BH1750數字傳感器(IIC接口)

開發軟體: Keil5

代碼說明:使用IIC模拟時序驅動,友善移植到其他平台,采集的光照度比較靈敏.  合成的光照度傳回值範圍是 0~255。 0表示全黑  255表示很亮。

實測:   手機閃光燈照着的狀态傳回值是245左右,手捂着的狀态傳回值是10左右.

完整工程代碼下載下傳:

https://download.csdn.net/download/xiaolong1126626497/18500653
STM32+BH1750光敏傳感器擷取光照強度
STM32+BH1750光敏傳感器擷取光照強度
二、BH1750介紹
STM32+BH1750光敏傳感器擷取光照強度
STM32+BH1750光敏傳感器擷取光照強度
STM32+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

1.#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  運作效果圖 

STM32+BH1750光敏傳感器擷取光照強度

繼續閱讀