嵌牛it观察-STM32--光照强度传感器(BH1750(GY-302))

文章目录

1、BH1750简介

2、具体参数

3、原理图

4、引脚连接

5、代码实现

6、结果显示

7、备注:

1、BH1750简介

 BH1750是一种用于两线式串行总线接口的数字型光强度传感器集成电路。这种集成电路可以根据收集的光线强度数据来调整液晶或者键盘背景灯的亮度。利用它的高分辨率可以探测较大范围的光强度变化。BH1750的内部由光敏二极管、运算放大器、ADC采集、晶振等组成。对应广泛的输入光范围(相当于1-65535lx),最小误差变动在土20%,而且受红外线影响很小。

 1、采用ROHM原装BH1750FVI芯片

 2、光照度范围: 0-655351x,传感器内置16bitAD转换器直接数字输出,省略复杂计算)省略标定

 3、内部包含通信电平转换,与5V单片机I0连接,支持STM32/51/ardunio

 4、XH2.54接口连接线,方便客户DIY

 5、小体积,广泛应用于室内光照检测、蔬菜、苗圃、温室大棚

2、具体参数

采用ROHM原装BH1750FVI芯片

供电电源: 3-5v

数据范围: 0-65535lx

传感器内置16bitAD转换器

直接数字输出,省略复杂的计算,省略标定

不区分环境光源,接近于视觉灵敏度的分光特性

可对广泛的亮度进行1勒克斯的高精度测定

标准NXP 1IC通信协议

模块内部包含通信电平转换,与5v单片机IO直接连接

3、原理图

4、引脚连接

名称 注释

GND 电源地

VCC 电源(3.3v~5v)

SCL 时钟线

SDA 数据线

ADDR 设备地址引脚

通讯方式为IIC具体可见OLED模块那里的具体介绍

5、代码实现

函数bh1750.c

#include "bh1750.h"

#include "sys.h"

/*

应用说明:

在访问I2C设备前,请先调用 i2c_CheckDevice() 检测I2C设备是否正常,该函数会配置GPIO

*/

static void I2C_BH1750_GPIOConfig(void);

/*

*********************************************************************************************************

* 函 数 名: i2c_Delay

* 功能说明: I2C总线位延迟,最快400KHz

* 形    参:无

* 返 回 值: 无

*********************************************************************************************************

*/

static void i2c_Delay(void)

{

uint8_t i;

/*

下面的时间是通过逻辑分析仪测试得到的。

    工作条件:CPU主频72MHz ,MDK编译环境,1级优化


循环次数为10时,SCL频率 = 205KHz

循环次数为7时,SCL频率 = 347KHz, SCL高电平时间1.5us,SCL低电平时间2.87us

循环次数为5时,SCL频率 = 421KHz, SCL高电平时间1.25us,SCL低电平时间2.375us

*/

for (i = 0; i < 10; i++);

}

/*

*********************************************************************************************************

* 函 数 名: i2c_Start

* 功能说明: CPU发起I2C总线启动信号

* 形    参:无

* 返 回 值: 无

*********************************************************************************************************

*/

void i2c_Start(void)

{

/* 当SCL高电平时,SDA出现一个下跳沿表示I2C总线启动信号 */

BH1750_I2C_SDA_1();

BH1750_I2C_SCL_1();

i2c_Delay();

BH1750_I2C_SDA_0();

i2c_Delay();

BH1750_I2C_SCL_0();

i2c_Delay();

}

/*

*********************************************************************************************************

* 函 数 名: i2c_Start

* 功能说明: CPU发起I2C总线停止信号

* 形    参:无

* 返 回 值: 无

*********************************************************************************************************

*/

void i2c_Stop(void)

{

/* 当SCL高电平时,SDA出现一个上跳沿表示I2C总线停止信号 */

BH1750_I2C_SDA_0();

BH1750_I2C_SCL_1();

i2c_Delay();

BH1750_I2C_SDA_1();

}

/*

*********************************************************************************************************

* 函 数 名: i2c_SendByte

* 功能说明: CPU向I2C总线设备发送8bit数据

* 形    参:_ucByte : 等待发送的字节

* 返 回 值: 无

*********************************************************************************************************

*/

void i2c_SendByte(uint8_t _ucByte)

{

uint8_t i;

/* 先发送字节的高位bit7 */

for (i = 0; i < 8; i++)

{

if (_ucByte & 0x80)

{

BH1750_I2C_SDA_1();

}

else

{

BH1750_I2C_SDA_0();

}

i2c_Delay();

BH1750_I2C_SCL_1();

i2c_Delay();

BH1750_I2C_SCL_0();

if (i == 7)

{

BH1750_I2C_SDA_1(); // 释放总线

}

_ucByte <<= 1; /* 左移一个bit */

i2c_Delay();

}

}

/*

*********************************************************************************************************

* 函 数 名: i2c_ReadByte

* 功能说明: CPU从I2C总线设备读取8bit数据

* 形    参:无

* 返 回 值: 读到的数据

*********************************************************************************************************

*/

uint8_t i2c_ReadByte(void)

{

uint8_t i;

uint8_t value;

/* 读到第1个bit为数据的bit7 */

value = 0;

for (i = 0; i < 8; i++)

{

value <<= 1;

BH1750_I2C_SCL_1();

i2c_Delay();

if (BH1750_I2C_SDA_READ())

{

value++;

}

BH1750_I2C_SCL_0();

i2c_Delay();

}

return value;

}

/*

*********************************************************************************************************

* 函 数 名: i2c_WaitAck

* 功能说明: CPU产生一个时钟,并读取器件的ACK应答信号

* 形    参:无

* 返 回 值: 返回0表示正确应答,1表示无器件响应

*********************************************************************************************************

*/

uint8_t i2c_WaitAck(void)

{

uint8_t re;

BH1750_I2C_SDA_1(); /* CPU释放SDA总线 */

i2c_Delay();

BH1750_I2C_SCL_1(); /* CPU驱动SCL = 1, 此时器件会返回ACK应答 */

i2c_Delay();

if (BH1750_I2C_SDA_READ()) /* CPU读取SDA口线状态 */

re = 1;

else

re = 0;

BH1750_I2C_SCL_0();

i2c_Delay();

return re;

}

/*

*********************************************************************************************************

* 函 数 名: i2c_Ack

* 功能说明: CPU产生一个ACK信号

* 形    参:无

* 返 回 值: 无

*********************************************************************************************************

*/

void i2c_Ack(void)

{

BH1750_I2C_SDA_0(); /* CPU驱动SDA = 0 */

i2c_Delay();

BH1750_I2C_SCL_1(); /* CPU产生1个时钟 */

i2c_Delay();

BH1750_I2C_SCL_0();

i2c_Delay();

BH1750_I2C_SDA_1(); /* CPU释放SDA总线 */

}

/*

*********************************************************************************************************

* 函 数 名: i2c_NAck

* 功能说明: CPU产生1个NACK信号

* 形    参:无

* 返 回 值: 无

*********************************************************************************************************

*/

void i2c_NAck(void)

{

BH1750_I2C_SDA_1(); /* CPU驱动SDA = 1 */

i2c_Delay();

BH1750_I2C_SCL_1(); /* CPU产生1个时钟 */

i2c_Delay();

BH1750_I2C_SCL_0();

i2c_Delay();

}

/*

*********************************************************************************************************

* 函 数 名: I2C_BH1750_GPIOConfig

* 功能说明: 配置I2C总线的GPIO,采用模拟IO的方式实现

* 形    参:无

* 返 回 值: 无

*********************************************************************************************************

*/

static void I2C_BH1750_GPIOConfig(void)

{

GPIO_InitTypeDef GPIO_InitStructure;

RCC_APB2PeriphClockCmd(BH1750_RCC_I2C_PORT, ENABLE); /* 打开GPIO时钟 */

GPIO_InitStructure.GPIO_Pin = BH1750_I2C_SCL_PIN | BH1750_I2C_SDA_PIN;

GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_OD;  /* 开漏输出 */

GPIO_Init(BH1750_GPIO_PORT_I2C, &GPIO_InitStructure);

/* 给一个停止信号, 复位I2C总线上的所有设备到待机模式 */

i2c_Stop();

}

/*

*********************************************************************************************************

* 函 数 名: i2c_CheckDevice

* 功能说明: 检测I2C总线设备,CPU向发送设备地址,然后读取设备应答来判断该设备是否存在

* 形    参:_Address:设备的I2C总线地址

* 返 回 值: 返回值 0 表示正确, 返回1表示未探测到

*********************************************************************************************************

*/

uint8_t i2c_CheckDevice(uint8_t _Address)

{

uint8_t ucAck;

i2c_Start(); /* 发送启动信号 */

/* 发送设备地址+读写控制bit(0 = w, 1 = r) bit7 先传 */

i2c_SendByte(_Address | BH1750_I2C_WR);

ucAck = i2c_WaitAck(); /* 检测设备的ACK应答 */

i2c_Stop(); /* 发送停止信号 */

return ucAck;

}

//BH1750写一个字节

//返回值 成功:0 失败:非0

uint8_t BH1750_Byte_Write(uint8_t data)

{

i2c_Start();

//发送写地址

i2c_SendByte(BH1750_Addr|0);

if(i2c_WaitAck()==1)

return 1;

//发送控制命令

i2c_SendByte(data);

if(i2c_WaitAck()==1)

return 2;

i2c_Stop();

return 0;

}

//BH1750读取测量数据

//返回值 成功:返回光照强度 失败:返回0

uint16_t BH1750_Read_Measure(void)

{

uint16_t receive_data=0;

i2c_Start();

//发送读地址

i2c_SendByte(BH1750_Addr|1);

if(i2c_WaitAck()==1)

return 0;

//读取高八位

receive_data=i2c_ReadByte();

i2c_Ack();

//读取低八位

receive_data=(receive_data<<8)+i2c_ReadByte();

i2c_NAck();

i2c_Stop();

return receive_data; //返回读取到的数据

}

//BH1750s上电

void BH1750_Power_ON(void)

{

BH1750_Byte_Write(POWER_ON);

}

//BH1750s断电

void BH1750_Power_OFF(void)

{

BH1750_Byte_Write(POWER_OFF);

}

//BH1750复位 仅在上电时有效

void BH1750_RESET(void)

{

BH1750_Byte_Write(MODULE_RESET);

}

//BH1750初始化

void BH1750_Init(void)

{

I2C_BH1750_GPIOConfig(); /* 配置GPIO */

BH1750_Power_ON(); //BH1750s上电

//BH1750_RESET(); //BH1750复位

BH1750_Byte_Write(Measure_Mode);

//SysTick_Delay_ms(120);

}

//获取光照强度

float LIght_Intensity(void)

{

return (float)(BH1750_Read_Measure()/1.1f*Resolurtion);

}

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

150

151

152

153

154

155

156

157

158

159

160

161

162

163

164

165

166

167

168

169

170

171

172

173

174

175

176

177

178

179

180

181

182

183

184

185

186

187

188

189

190

191

192

193

194

195

196

197

198

199

200

201

202

203

204

205

206

207

208

209

210

211

212

213

214

215

216

217

218

219

220

221

222

223

224

225

226

227

228

229

230

231

232

233

234

235

236

237

238

239

240

241

242

243

244

245

246

247

248

249

250

251

252

253

254

255

256

257

258

259

260

261

262

263

264

265

266

267

268

269

270

271

272

273

274

275

276

277

278

279

280

281

282

283

284

285

286

287

288

289

290

291

292

293

294

295

296

297

298

299

300

301

302

303

304

305

306

307

308

309

310

311

312

313

314

315

316

函数bh1750.h

#ifndef __BH1750_H

#define __BH1750_H

#include "sys.h"

//BH1750的地址

#define BH1750_Addr 0x46

//BH1750指令码

#define POWER_OFF 0x00

#define POWER_ON 0x01

#define MODULE_RESET 0x07

#define CONTINUE_H_MODE 0x10

#define CONTINUE_H_MODE2 0x11

#define CONTINUE_L_MODE 0x13

#define ONE_TIME_H_MODE 0x20

#define ONE_TIME_H_MODE2 0x21

#define ONE_TIME_L_MODE 0x23

//测量模式

#define Measure_Mode CONTINUE_H_MODE

//分辨率 光照强度(单位lx)=(High Byte  + Low Byte)/ 1.2 * 测量精度

#if ((Measure_Mode==CONTINUE_H_MODE2)|(Measure_Mode==ONE_TIME_H_MODE2))

#define Resolurtion 0.5

#elif ((Measure_Mode==CONTINUE_H_MODE)|(Measure_Mode==ONE_TIME_H_MODE))

#define Resolurtion 1

#elif ((Measure_Mode==CONTINUE_L_MODE)|(Measure_Mode==ONE_TIME_L_MODE))

#define Resolurtion 4

#endif

#define BH1750_I2C_WR 0 /* 写控制bit */

#define BH1750_I2C_RD 1 /* 读控制bit */

/* 定义I2C总线连接的GPIO端口, 只需要修改下面4行代码即可任意改变SCL和SDA的引脚 */

#define BH1750_GPIO_PORT_I2C GPIOB /* GPIO端口 */

#define BH1750_RCC_I2C_PORT RCC_APB2Periph_GPIOB /* GPIO端口时钟 */

#define BH1750_I2C_SCL_PIN GPIO_Pin_10 /* 连接到SCL时钟线的GPIO */

#define BH1750_I2C_SDA_PIN GPIO_Pin_11

/* 连接到SDA数据线的GPIO */

/* 定义读写SCL和SDA的宏,已增加代码的可移植性和可阅读性 */

#if 0 /* 条件编译: 1 选择GPIO的库函数实现IO读写 */

#define BH1750_I2C_SCL_1()  GPIO_SetBits(BH1750_GPIO_PORT_I2C, BH1750_I2C_SCL_PIN) /* SCL = 1 */

#define BH1750_I2C_SCL_0()  GPIO_ResetBits(BH1750_GPIO_PORT_I2C, BH1750_I2C_SCL_PIN) /* SCL = 0 */

#define BH1750_I2C_SDA_1()  GPIO_SetBits(BH1750_GPIO_PORT_I2C, BH1750_I2C_SDA_PIN) /* SDA = 1 */

#define BH1750_I2C_SDA_0()  GPIO_ResetBits(BH1750_GPIO_PORT_I2C, BH1750_I2C_SDA_PIN) /* SDA = 0 */

#define BH1750_I2C_SDA_READ()  GPIO_ReadInputDataBit(BH1750_GPIO_PORT_I2C, BH1750_I2C_SDA_PIN) /* 读SDA口线状态 */

#else /* 这个分支选择直接寄存器操作实现IO读写 */

    /* 注意:如下写法,在IAR最高级别优化时,会被编译器错误优化 */

#define BH1750_I2C_SCL_1()  BH1750_GPIO_PORT_I2C->BSRR = BH1750_I2C_SCL_PIN /* SCL = 1 */

#define BH1750_I2C_SCL_0()  BH1750_GPIO_PORT_I2C->BRR = BH1750_I2C_SCL_PIN /* SCL = 0 */

#define BH1750_I2C_SDA_1()  BH1750_GPIO_PORT_I2C->BSRR = BH1750_I2C_SDA_PIN /* SDA = 1 */

#define BH1750_I2C_SDA_0()  BH1750_GPIO_PORT_I2C->BRR = BH1750_I2C_SDA_PIN /* SDA = 0 */

#define BH1750_I2C_SDA_READ()  ((BH1750_GPIO_PORT_I2C->IDR & BH1750_I2C_SDA_PIN) != 0) /* 读SDA口线状态 */

#endif

void i2c_Start(void);

void i2c_Stop(void);

void i2c_SendByte(uint8_t _ucByte);

uint8_t i2c_ReadByte(void);

uint8_t i2c_WaitAck(void);

void i2c_Ack(void);

void i2c_NAck(void);

uint8_t i2c_CheckDevice(uint8_t _Address);

void BH1750_Init(void); //未包含IIC初始化

float LIght_Intensity(void); //读取光照强度的值

uint8_t BH1750_Byte_Write(uint8_t data);

uint16_t BH1750_Read_Measure(void);

void BH1750_Power_ON(void);

void BH1750_Power_OFF(void);

void BH1750_RESET(void);


#endif

主函数main.c

#include "sys.h"

#include "delay.h"

#include "led.h"

#include "key.h"

#include "oled.h"

#include "bmp.h"

#include "dht11.h"

#include "bh1750.h"

u8 temperature =0;     

u8 humidity = 0;

float Light = 0; //光照度

int main(void)

{

u8 t =0;

delay_init();     //延时函数初始化  

LED_Init();   //初始化与LED连接的硬件接口

KEY_Init();            //初始化与按键连接的硬件接口

OLED_Init();          //初始化与OLED显示屏

OLED_Clear();          //清楚屏幕

DHT11_Init();          //初始化DHT11

BH1750_Init();          //初始化BH1750


while(1)

{

if(t%10==0) //每100ms读取一次

{  

DHT11_Read_Data(&temperature,&humidity); //读取温湿度值

if (!i2c_CheckDevice(BH1750_Addr))

{

Light = LIght_Intensity();              //获取光照强度

}


}

delay_ms(10);

t++;

//OLED显示文字 "温度:"

OLED_ShowCHinese(0,3,7);//温

OLED_ShowCHinese(18,3,8);//度

OLED_ShowString(40,4,":",26);//:

OLED_ShowNum(50,3,temperature,2,16);//显示ASCII字符的码值

//OLED显示文字 "湿度:"

OLED_ShowCHinese(0,6,9);//湿

OLED_ShowCHinese(18,6,8);//度

OLED_ShowString(40,7,":",26);//:

OLED_ShowNum(50,6,humidity,2,16);//显示ASCII字符的码值

//OLED显示文字 "光照强度"

OLED_ShowCHinese(0,0,10);//光

OLED_ShowCHinese(15,0,11);//照

OLED_ShowCHinese(30,0,12);//强

OLED_ShowCHinese(45,0,13);//度

OLED_ShowString(60,1,":",36);//:

OLED_ShowNum(75,0,Light,2,16);//显示ASCII字符的码值

if(Light<50)//光照强度小于50,LED1灯亮

{

LED1 = 0;

}

else

{

LED1=1;

}

}

}

————————————————

原文链接:https://blog.csdn.net/weixin_45771489/article/details/123507030

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容