STM32 HAL库——光照强度传感器(GY302/BH1750)

目录

1.BH1750介绍

2.引脚连接

3.代码实现


1.BH1750介绍

2.引脚连接

一共五个引脚,采用模拟IIC通信,ADDR地址引脚悬空即可。(引脚连接可以自己定义,更改参数即可)

SCL——PA12

SDA——PA15

3.代码实现

GY302.C文件          

#include "GY302.h"
 
uint8_t mcy=0;
uint8_t BUF[3];
/***开始信号**/
void BH1750_Start()
{
    HAL_GPIO_WritePin(GPIOA, sda,GPIO_PIN_SET);                    //拉高数据线
    HAL_GPIO_WritePin(GPIOA, scl,GPIO_PIN_SET);                   //拉高时钟线
    delay_us1(5);                 
    HAL_GPIO_WritePin(GPIOA, sda,GPIO_PIN_RESET);                    //产生下降沿
    delay_us1(5);                
    HAL_GPIO_WritePin(GPIOA, scl,GPIO_PIN_RESET);                    //拉低时钟线
}
 
/*****停止信号******/
void BH1750_Stop()
{
    HAL_GPIO_WritePin(GPIOA, sda,GPIO_PIN_RESET);                   //拉低数据线
    HAL_GPIO_WritePin(GPIOA, scl,GPIO_PIN_SET);                      //拉高时钟线
    delay_us1(5);                 
    HAL_GPIO_WritePin(GPIOA, sda,GPIO_PIN_SET);                    //产生上升沿
    delay_us1(5);                 
}
/*****初始化BH1750******/
void Init_BH1750()
{
		BH1750_Start();                                                 //起始信号
		BH1750_SendByte(SlaveAddress);                                  //发送设备地址+写信号
		BH1750_SendByte(0x01);                                  //内部寄存器地址
		BH1750_Stop();                                                  //停止信号
	
}
 
//连续读出BH1750内部数据
void mread(void)
{   
	  uint8_t i;	
    BH1750_Start();                          //起始信号
    BH1750_SendByte(SlaveAddress+1);         //发送设备地址·+读信号
	
	 for (i=0; i<3; i++)                      //连续读取6个地址数据到BUF
    {
        BUF[i] = BH1750_RecvByte();         
        if (i == 3)
        {
           BH1750_SendACK(1);                //最后一个数据需要回NOACK
        }
        else
        {		
          BH1750_SendACK(0);                //回应ACK
        }
   }
 
    BH1750_Stop();                          //停止信号
    Delay_mms(5);
 
}
 
uint32_t Value_GY30(void)
{
		uint16_t dis_data;
	  uint16_t Value_GY_30;
    Single_Write_BH1750(0x01);   // power on
    Single_Write_BH1750(0x10);   // H- resolution mode   
    HAL_Delay(180);            //延时180ms                    
    mread();       //连续读出数据,存储在BUF中
    dis_data=BUF[0];
    dis_data=(dis_data<<8)+BUF[1];//字节合成数据
    Value_GY_30=(float)dis_data/1.2;
    return Value_GY_30;
}
//系统主频72MHZ
void delay_us1(uint16_t us)
{
	while(us--)
	{
		__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
		__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
		__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
		__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
		__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
		__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
		__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();
		__nop();__nop();
	}
}
void Delay_mms(uint16_t tmp)
{
	  uint16_t i=0;
	  while(tmp--)
	  {
		i=12000;
		while(i--);
    }
}
 
/**************************************
发送应答信号
入口参数:ack (0:ACK 1:NAK)
**************************************/
void BH1750_SendACK(int ack)
{
			GPIO_InitTypeDef GPIO_InitStruct;
	
  GPIO_InitStruct.Pin = scl|sda;
  GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
  GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
  HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 
    if(ack == 1)   //写应答信号
			HAL_GPIO_WritePin(GPIOA, sda,GPIO_PIN_SET); 
		else if(ack == 0)
			HAL_GPIO_WritePin(GPIOA, sda,GPIO_PIN_RESET);
		else
			return;
			
    HAL_GPIO_WritePin(GPIOA, scl,GPIO_PIN_SET);     
    delay_us1(5);               
    HAL_GPIO_WritePin(GPIOA, scl,GPIO_PIN_RESET);      
    delay_us1(5);               
}
 
/**************************************
接收应答信号
**************************************/
int BH1750_RecvACK()
{		
		
	  GPIO_InitTypeDef GPIO_InitStruct;
	
	  GPIO_InitStruct.Mode = GPIO_MODE_INPUT;  /*输入上拉*/
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    GPIO_InitStruct.Pin = sda;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); 	
	
    HAL_GPIO_WritePin(GPIOA, scl,GPIO_PIN_SET);            //拉高时钟线
    delay_us1(5);                
	
	  if(HAL_GPIO_ReadPin( GPIOA, sda ) == 1 )//读应答信号
        mcy = 1 ;  
    else
        mcy = 0 ;			
	
    HAL_GPIO_WritePin(GPIOA, scl,GPIO_PIN_RESET);                    //拉低时钟线
    delay_us1(5);               
  
   GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
   HAL_GPIO_Init( GPIOA, &GPIO_InitStruct );
	
    return mcy;
}
 
/**************************************
向iic总线发送一个字节数据
**************************************/
void BH1750_SendByte(uint8_t dat)
{
    uint8_t i;
 
    for (i=0; i<8; i++)         //8位计数器
      {
				if( 0X80 & dat )
          HAL_GPIO_WritePin(GPIOA, sda,GPIO_PIN_SET);
        else
          HAL_GPIO_WritePin(GPIOA, sda,GPIO_PIN_RESET);
			 
				dat <<= 1;
        HAL_GPIO_WritePin(GPIOA, scl,GPIO_PIN_SET);               //拉高时钟线
        delay_us1(5);             
        HAL_GPIO_WritePin(GPIOA, scl,GPIO_PIN_RESET);                //拉低时钟线
        delay_us1(5);            
      }
    BH1750_RecvACK();
}
 
//我们对BH1750发送命令时,要先发送器件地址+写入位,然后发送指令
//读取数据的时候,需要先发送器件地址+读入位,然后读取两字节数据
 
//写入指令
void Single_Write_BH1750(uint8_t REG_Address)//REG_Address是要写入的指令
{
	BH1750_Start();                  //起始信号
	BH1750_SendByte(SlaveAddress);  //发送器件地址+写信号
	BH1750_SendByte(REG_Address);   //写入指令,内部寄存器地址
	BH1750_Stop();                   //结束信号
}
/**************************************
从iic总线读取一个字节地址
**************************************/
uint8_t BH1750_RecvByte()
{
    uint8_t i;
    uint8_t dat = 0;
	  uint8_t bit;
	  
	 GPIO_InitTypeDef GPIO_InitStruct;
	
	 GPIO_InitStruct.Mode = GPIO_MODE_INPUT;   /*上拉输入*/
   GPIO_InitStruct.Pin = sda;
   GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
   HAL_GPIO_Init( GPIOA, &GPIO_InitStruct );
	
    HAL_GPIO_WritePin(GPIOA, sda,GPIO_PIN_SET);          //准备读取数据
    for (i=0; i<8; i++)         //8位计数器
    {
        dat <<= 1;
        HAL_GPIO_WritePin(GPIOA, scl,GPIO_PIN_SET);               //拉高时钟线
        delay_us1(5);            
			
			  if( SET == HAL_GPIO_ReadPin( GPIOA, sda ) )
             bit = 0X01;
       else
             bit = 0x00;  
			
        dat |= bit;             //读数据 
			
        HAL_GPIO_WritePin(GPIOA, scl,GPIO_PIN_RESET);                //拉低时钟线
        delay_us1(5);           
    }
		
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    HAL_GPIO_Init( GPIOA, &GPIO_InitStruct );
    return dat;
}

GY302.h文件

#ifndef __GY302_H
#define __GY302_H
#include "main.h"
#define scl GPIO_PIN_12
#define sda GPIO_PIN_15
 
#define SlaveAddress 0x46  //ADDR接GND时的器件地址
#define BH1750_PWR_DOWN     0x00 //关闭模块
#define BH1750_PWR_ON       0x01 //打开模块等待测量命令
#define BH1750_RST          0x07 //重置数据寄存器值在PowerOn模式下有效
#define BH1750_CON_H        0x10 // 连续高分辨率模式,1lx,120ms
#define BH1750_CON_H2       0x11 // 连续高分辨率模式.5lx,120ms
#define BH1750_CON_L        0x13 // 连续低分辨率模式,4lx,16ms
#define BH1750_ONE_H        0x20 // 一次高分辨率模式,1lx,120ms,测量后模块转到PowerDown模式
#define BH1750_ONE_H2       0x21 // 一次高分辨率模式,0.5lx,120ms,测量后模块转到PowerDown模式
#define BH1750_ONE_L        0x23 // 一次低分辨率模式,4lx,16ms,测量后模块转到PowerDown模式
 
 
void BH1750_Start(void);
void BH1750_Stop(void);
void Init_BH1750(void);
void mread(void);
uint32_t Value_GY30(void);
void delay_us1(uint16_t us);
void Delay_mms(uint16_t tmp);
void BH1750_SendACK(int ack);
int BH1750_RecvACK(void);
void BH1750_SendByte(uint8_t dat);
uint8_t BH1750_RecvByte(void);
int I2C_ReadData(uint8_t slaveAddr, uint8_t regAddr, uint8_t *pData, uint16_t dataLen);
void Single_Write_BH1750(uint8_t REG_Address);
 
#endif

 main.c文件里加入

Value_GY30()

即可 ,该函数输出值为光照强度 单位为xl。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值