在制作智能花盆的过程中,使用了光敏传感器BH1750。
因为在网上找了很多都是关于51的,32方面的比较少,所以这里记录一下BH750的驱动代码。
链接:https://pan.baidu.com/s/1UOQvp1qKvfeywY0BsDXA2w?pwd=zh92
提取码:zh92
--来自百度网盘超级会员V3的分享
这里由于篇幅限制,串口驱动的代码不给出,如果想要源码可以在上面链接获取。
bh1750.c
#include "BH1750.h"
unsigned char BUF[8]; /* 读取光强中间量 */
int dis_data; /* 读取光强中间量 */
int mcy; /* 读取光强中间量 */
void GPIOConfig( void )
{
GPIO_InitTypeDef GPIO_InitStruct;
/*开启GPIOB的外设时钟*/
RCC_APB2PeriphClockCmd( RCC_APB2Periph_GPIOB, ENABLE );
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = sda | scl;
GPIO_Init( GPIOB, &GPIO_InitStruct );
}
void Delay_5us( void )
{
Delay_us( 5 );
}
void Delay_mms( unsigned int tmp )
{
while ( tmp-- )
{
Delay_ms( 1 );
}
}
/***开始信号***/
void BH1750_Start()
{
GPIO_SetBits( GPIOB, sda ); /* 拉高数据线 */
GPIO_SetBits( GPIOB, scl ); /* 拉高时钟线 */
Delay_5us(); /* 延时 */
GPIO_ResetBits( GPIOB, sda ); /* 产生下降沿 */
Delay_5us(); /* 延时 */
GPIO_ResetBits( GPIOB, scl ); /* 拉低时钟线 */
}
/*****停止信号******/
void BH1750_Stop()
{
GPIO_ResetBits( GPIOB, sda ); /* 拉低数据线 */
GPIO_SetBits( GPIOB, scl ); /* 拉高时钟线 */
Delay_5us(); /* 延时 */
GPIO_SetBits( GPIOB, sda ); /* 产生上升沿 */
Delay_5us(); /* 延时 */
}
/**************************************
* 发送应答信号
* 入口参数:ack (0:ACK 1:NAK)
**************************************/
void BH1750_SendACK( unsigned int ack )
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = sda;
GPIO_Init( GPIOB, &GPIO_InitStruct );
if ( ack == 1 ) /* 写应答信号 */
GPIO_SetBits( GPIOB, sda );
else if ( ack == 0 )
GPIO_ResetBits( GPIOB, sda );
else
return;
GPIO_SetBits( GPIOB, scl ); /* 拉高时钟线 */
Delay_5us(); /* 延时 */
GPIO_ResetBits( GPIOB, scl ); /* 拉低时钟线 */
Delay_5us(); /* 延时 */
}
/**************************************
* 接收应答信号
**************************************/
unsigned int BH1750_RecvACK()
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; /*这里一定要设成输入上拉,否则不能读出数据*/
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_InitStruct.GPIO_Pin = sda;
GPIO_Init( GPIOB, &GPIO_InitStruct );
GPIO_SetBits( GPIOB, scl ); /* 拉高时钟线 */
Delay_5us(); /* 延时 */
if ( GPIO_ReadInputDataBit( GPIOB, sda ) == 1 ) /* 读应答信号 */
mcy = 1;
else
mcy = 0;
GPIO_ResetBits( GPIOB, scl ); /* 拉低时钟线 */
Delay_5us(); /* 延时 */
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init( GPIOB, &GPIO_InitStruct );
return(mcy);
}
/**************************************
* 向IIC总线发送一个字节数据
**************************************/
void BH1750_SendByte( unsigned char dat )
{
unsigned char i;
for ( i = 0; i < 8; i++ ) /* 8位计数器 */
{
if ( 0X80 & dat )
GPIO_SetBits( GPIOB, sda );
else
GPIO_ResetBits( GPIOB, sda );
dat <<= 1;
GPIO_SetBits( GPIOB, scl ); /* 拉高时钟线 */
Delay_5us(); /* 延时 */
GPIO_ResetBits( GPIOB, scl ); /* 拉低时钟线 */
Delay_5us(); /* 延时 */
}
BH1750_RecvACK();
}
unsigned char BH1750_RecvByte()
{
unsigned char i;
unsigned char dat = 0;
unsigned char bit;
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU; /*这里一定要设成输入上拉,否则不能读出数据*/
GPIO_InitStruct.GPIO_Pin = sda;
GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init( GPIOB, &GPIO_InitStruct );
GPIO_SetBits( GPIOB, sda ); /* 使能内部上拉,准备读取数据, */
for ( i = 0; i < 8; i++ ) /* 8位计数器 */
{
dat <<= 1;
GPIO_SetBits( GPIOB, scl ); /* 拉高时钟线 */
Delay_5us(); /* 延时 */
if ( SET == GPIO_ReadInputDataBit( GPIOB, sda ) )
bit = 0X01;
else
bit = 0x00;
dat |= bit; /* 读数据 */
GPIO_ResetBits( GPIOB, scl ); /* 拉低时钟线 */
Delay_5us(); /* 延时 */
}
GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
GPIO_Init( GPIOB, &GPIO_InitStruct );
return(dat);
}
void Single_Write_BH1750( unsigned char REG_Address )
{
BH1750_Start(); /* 起始信号 */
BH1750_SendByte( SlaveAddress ); /* 发送设备地址+写信号 */
BH1750_SendByte( REG_Address ); /* 内部寄存器地址,请参考中文pdf22页 */
/* BH1750_SendByte(REG_data); //内部寄存器数据,请参考中文pdf22页 */
BH1750_Stop(); /* 发送停止信号 */
}
/* 初始化BH1750,根据需要请参考pdf进行修改**** */
void Init_BH1750()
{
GPIOConfig();
Single_Write_BH1750( 0x01 );
}
/* 连续读出BH1750内部数据 */
void mread( void )
{
unsigned char i;
BH1750_Start(); /* 起始信号 */
BH1750_SendByte( SlaveAddress + 1 ); /* 发送设备地址+读信号 */
for ( i = 0; i < 3; i++ ) /* 连续读取6个地址数据,存储中BUF */
{
BUF[i] = BH1750_RecvByte(); /* BUF[0]存储0x32地址中的数据 */
if ( i == 3 )
{
BH1750_SendACK( 1 ); /* 最后一个数据需要回NOACK */
}else {
BH1750_SendACK( 0 ); /* 回应ACK */
}
}
BH1750_Stop(); /* 停止信号 */
Delay_mms( 5 );
}
float get_light_power(void)
{
float lightPower;
mread(); /* 连续读取gy30数据 */
dis_data = BUF[0];
dis_data = (dis_data << 8) + BUF[1]; /* 合成数据 */
lightPower = (float) dis_data / 1.2; /* 得出光强 单位是lx */
Single_Write_BH1750( 0x01 ); /* power on */
Single_Write_BH1750( 0x10 ); /* H- resolution mode */
return(lightPower);
}
BH1750.h
#ifndef __BH1750_H__
#define __BH1750_H__
#include "sys.h"
#include "delay.h"
#define sda GPIO_Pin_6 /* 20 */
#define scl GPIO_Pin_5 /* 21 */
#define SlaveAddress 0x46
/*
* 定义器件在IIC总线中的从地址,根据ALT ADDRESS地址引脚不同修改
* ALT ADDRESS引脚接地时地址为0xA6,接电源时地址为0x3A
*/
void Init_BH1750( void );
void conversion( unsigned int temp_data );
void Single_Write_BH1750( unsigned char REG_Address ); /* 单个写入数据 */
unsigned char Single_Read_BH1750( unsigned char REG_Address ); /* 单个读取内部寄存器数据 */
void mread( void ); /* 连续的读取内部寄存器数据 */
void Delay_5us( void );
void Delay_ms( unsigned int tmp );
void GPIOConfig( void );
float get_light_power(void);
#endif
main.c
int main(void)
{
/* LED 端口初始化 */
LED_G_Confing();
/*初始化USART 配置模式为 115200 8-N-1,中断接收*/
USART_Config();
//bh1750初始化
Init_BH1750(); //初始化BH1750
printf("Start!!!\n");
// Delay_ms(180); //延时180ms
a = get_light_power();//获取光强
printf("光照强度:%d\n",a);
while(1)
{ /* 存储光强的变量 */
a = get_light_power();//获取光强
printf("Start!!!\n");
printf("光照强度:%d\n",a);
Delay_us(1000000);
}
}