提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

前言

一、BH1750是什么?

二、如何使用BH1750

2.1 BH1750的通信方式

2.2 BH1750的指令集

2.3 BH1750的时序图

三、 BH1750代码详解

3.1 硬件IIC配置

3.2 BH1750的读和写

3.3 主函数

四、演示

工程:


前言

写这篇文章的原因是自己写毕设的时候用到了这个模块,故分享一下BH1750的使用经验,记录一下自己的代码,这里是萌新一枚,还请各位大佬多多包涵。


一、BH1750是什么?

一个光照传感器,使用IIC进行通信的数字传感器,主要功能为测量光照强度;

二、如何使用BH1750

使用任何陌生的元器件,第一步都应该是掏出他的数据手册。

图一 BH1750数据手册

看到这个数据手册,有的同学可能会说,“极光啊,我的英语是一窍不通啊”。没关系,我也是我英语老学渣了,大学英语全都是60分飘过,全靠老师饶我一条狗命。我都能弄懂数据手册,你们也一定可以。

首先在看数据手册时,我们需要认识到一点,我们是要去了解关键信息去的,我们是要了解怎么让他动起来,而不是去做阅读理解。什么是关键信息?一、通信方式,二、指令集,三、时序图。如果你要搞硬件,你可能还需要看它的电气特性和封装之类的,如果你只是买个模块来玩,这看这三个就足够了。

2.1 BH1750的通信方式

这在数据手册上的第一句话就已经说明了:

图二 BH1750的通信方式

这是通过I2C来进行通信,I2C我就不过多介绍了,CSDN上很多人都有讲,我个人是通过火哥的视频来学的,在这里附上火哥的B站视频链接。

特别注意,I2C非常重要,想往单片机嵌入式方面发展的,要好好学。

【单片机】野火STM32F103教学视频 (配套霸道/指南者/MINI)【全】(刘火良老师出品) (无字幕)_哔哩哔哩_bilibili

2.2 BH1750的指令集

指令集这种东西通常来说是以表格的形式存在于数据手册之中,而且伴随着二进制和十六进制的数值。BH1750的指令集如下所示:

图3 BH1750指令集


第一列为功能,第二列为具体的数值,第三列为功能的补充说明。举例:第四行写的是自动测量高分辨率模式,想要实现这个功能,你需要往传感器中发送0x10。这样,每大约120ms,传感器会得到一个数据,这个数据的精度为1lx,你通过IIC读取这个数据即可。

2.3 BH1750的时序图

图4 BH1750时序图

其实学过I2C的人能够很轻易的看出这是啥了,这其实就是一个IIC。

序号1:是往BH1750中写入,首先发送一个起始信号,通过IIC的总线发送BH1750的地址,同时在地址的后面表明我们是要写入BH1750,具体做法就是在7位的地址后面凑一个0,如果你要声明自己是要读出就往后面凑个1,然后等待一个应答信号。再然后,发送指令0x10,就是我们上面提到过的连续采集高分辨率模式,等待一个应答信号,收到应答后,再发送一个结束信号。完成BH1750的写入工作。

序号2:等待最多180ms,这段时间,BH1750正在采集数据,并将数据存入到寄存器之中。

序号3:将寄存器中的数据取出。同样发送一个起始信号,通过IIC的总线发送BH1750的地址,同时在地址的后面表明我们是要读BH1750,在7位的地址后面凑一个1,等待一个应答信号,接收数据的高八位,再发送一个应答信号,表示我们还没有接收完,再接收高八位,发送非应答,同时发送结束信号,完成接收。这样我们就得到了传感器发送来的数据了。

三、 BH1750代码详解

下面就是代码部分,我自认是写注释比较勤快的,这部分就不做过多的赘述了,如果还是看不懂的可以私信问或者评论区里留言。

3.1 硬件IIC配置

我个人偏好硬件IIC,可以不用写时序。不会硬件的可以往上翻一翻,我有发一个视频链接里面有讲硬件IIC,火哥讲的课还是很不错的。

/*******************************硬件IIC初始化**********************************/
/*IIC_GPIO配置*/
/*采用静态函数,限制其作用域*/
static void I2C_GPIO_Config(void)
{GPIO_InitTypeDef  GPIO_InitStructure; /* 使能与 I2C 有关的时钟 */BH1750_I2C_APBxClock_FUN ( BH1750_I2C_CLK, ENABLE );BH1750_I2C_GPIO_APBxClock_FUN ( BH1750_I2C_GPIO_CLK, ENABLE );/* I2C_SCL、I2C_SDA*/GPIO_InitStructure.GPIO_Pin = BH1750_I2C_SCL_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;           // 开漏输出GPIO_Init(BH1750_I2C_SCL_PORT, &GPIO_InitStructure);GPIO_InitStructure.GPIO_Pin = BH1750_I2C_SDA_PIN;GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;         // 开漏输出/*使能IO口*/GPIO_Init(BH1750_I2C_SDA_PORT, &GPIO_InitStructure);
}/*I2C工作模式配置*/
/*采用静态函数,限制其作用域*/
static void I2C_Mode_Configu(void)
{I2C_InitTypeDef  I2C_InitStructure; /*I2C 配置*/I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;/*高电平数据稳定,低电平数据变化 SCL 时钟线的占空比*/I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;/*设置STM32自身的地址*/I2C_InitStructure.I2C_OwnAddress1 =I2Cx_OWN_ADDRESS7;/*接收数据产生应答*/I2C_InitStructure.I2C_Ack = I2C_Ack_Enable ;/*I2C的寻址模式,设为7位地址*/I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;/*通信速率*/I2C_InitStructure.I2C_ClockSpeed = I2C_Speed;/*I2C 初始化*/I2C_Init(BH1750_I2Cx, &I2C_InitStructure);/*使能I2C*/I2C_Cmd(BH1750_I2Cx, ENABLE);
}/*IIC初始化*/
void BH1750_I2C_Init(void)
{I2C_GPIO_Config(); I2C_Mode_Configu();
}

3.2 BH1750的读和写

/*BH1750写入*/
void IIC_BH1750_Write(uint8_t command)
{/*检测IIC是否空闲*/while(I2C_GetFlagStatus(BH1750_I2Cx, I2C_FLAG_BUSY));/*发送一个开始信号*/I2C_GenerateSTART(BH1750_I2Cx, ENABLE);/*等待EV5事件*/while(!I2C_CheckEvent(BH1750_I2Cx, I2C_EVENT_MASTER_MODE_SELECT));/*发送地址外加写命令*/I2C_Send7bitAddress(BH1750_I2Cx, BH1750_ADDRESS, I2C_Direction_Transmitter);/*等待EV6事件*/while(!I2C_CheckEvent(BH1750_I2Cx, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));/*发送指令*/I2C_SendData(BH1750_I2Cx, command);/*等待EV8事件*/while(!I2C_CheckEvent(BH1750_I2Cx, I2C_EVENT_MASTER_BYTE_TRANSMITTED));/*发送结束信号*/I2C_GenerateSTOP(BH1750_I2Cx, ENABLE);
}/*BH1750读取*/
uint32_t IIC_BH1750_Read(void)
{   uint32_t Data=0;/*检测IIC是否空闲*/while(I2C_GetFlagStatus(BH1750_I2Cx, I2C_FLAG_BUSY));/*发送一个开始信号*/I2C_GenerateSTART(BH1750_I2Cx, ENABLE);/*等待EV5事件*/while(!I2C_CheckEvent(BH1750_I2Cx, I2C_EVENT_MASTER_MODE_SELECT));/*发送地址外加写命令*/I2C_Send7bitAddress(BH1750_I2Cx, BH1750_ADDRESS, I2C_Direction_Receiver);/*等待EV6事件*/while(!I2C_CheckEvent(BH1750_I2Cx, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));/*等待EV7事件*/while(I2C_CheckEvent(BH1750_I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)==0);/*获取数据的高八位*/Data=I2C_ReceiveData(BH1750_I2Cx);/*右移八位*/Data=Data<<8;/*变更为非应答信号*/I2C_AcknowledgeConfig(BH1750_I2Cx, DISABLE);/*发送结束信号*/I2C_GenerateSTOP(BH1750_I2Cx, ENABLE);/*等待EV7事件*/while(I2C_CheckEvent(BH1750_I2Cx, I2C_EVENT_MASTER_BYTE_RECEIVED)==0);/*获取数据的低八位*/Data|=I2C_ReceiveData(BH1750_I2Cx);/*变更为应答信号*/I2C_AcknowledgeConfig(BH1750_I2Cx, ENABLE);/*返回数据*/return Data;
}

3.3 主函数

/**************************BH1750简单的使用例程****************************/#include "stm32f10x.h"
#include "./led/bsp_led.h"
#include "./usart/bsp_usart.h"
#include "./i2c/bsp_i2c_ee.h"
#include "bsp_i2c_bh1750.h"
#include <string.h>/*简单的延时函数*/
void delayms(uint16_t time)
{uint16_t i;while(time--){i=12000;while(i--);}
}/*读取BH1750寄存器的数据*/
uint16_t BH1750_Read(void)
{uint16_t temp;/*读测量数据*/temp=IIC_BH1750_Read();/*数组计算*/temp=(uint32_t)(temp/1.2);return temp;
}
/*********************************主函数*************************************/int main(void)
{ uint16_t Data;LED_GPIO_Config();LED_BLUE;/* 串口初始化 */USART_Config();printf("\r\n 这是一个BH1750测试例程 \r\n");BH1750_I2C_Init();printf("\r\n 作者:极光 \r\n"); /*发送上电指令*/IIC_BH1750_Write(0x01);/*发送连续测量指令*/IIC_BH1750_Write(0x10);while (1){   Data=BH1750_Read();printf("\r\n 光照强度为 %d lx \r\n",Data);delayms(2000);}
}/********************************END OF FILE******************************/

四、演示

图五 效果演示

工程:

链接:https://pan.baidu.com/s/1MlDgRXKAwiJ23hmZAYvrzA?pwd=1111 
        提取码:1111

BH1750的一些使用心得(STM32,内置工程)相关推荐

  1. 【ARM】STM32内置DFU的使用

    所有STM32系列芯片都自带ISP功能,进入ISP的方式就是BOOT0置1,然后上电或复位,这时候芯片从系统存储区启动,进入ISP功能,可以使用串口0进行软件烧写. STM32F2/3/4系列芯片不仅 ...

  2. 带内部参考电压(VREFINT)校正的STM32 DMA 内置温度采集

    笔者今天来介绍一下STM32ADC内置温度的采集,重点是通过内置参考电压来避免ADC参考电压VDDA对温度ADC采集的影响. 1.STM32ADC简介   stm32F4系列ADC,逐次趋近型AD.1 ...

  3. STM32白话文教程(三)内置按键模块、外接按键检测 三句话让你玩明白按键 水银倾斜模块

    还不知道检测输入电平信号用什么输入模式? 就简单的记住: 检测端口输入低电平0要用上拉 GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; 检测端口输入高电平1 ...

  4. U盘GPIO文件系统映射-STM32利用内置FLASH做U盘

    受到linux对一切设备的控制都当成文件对待的启发 于是便有了这个将GPIO映射到U盘中的想法,这样一来便可以在任何支持U盘的设备中扩展系统的硬件功能了 我的QQ是243786753,这属于原创作品, ...

  5. 用STM32的内置DAC制作一个波形生成器(发生器)

    社团作业=_= 任务一:波形生成.1.使用STM32的DAC功能,生成0~10kHz的方波,频率精确到1%以内: 2.能够生成三角波.正弦波: 3.实现频率设置,可以实现一定步进数的调节,最高为100 ...

  6. Android 学习心得(2)——Android内置数据库SQLite

    一.简介: Android有一个内置数据库SQLite,它是一种轻型数据库,它有五种数据类型:NULL(空型).BLOB(二进制).INTEGER(整型).REAL(浮点型).TEXT(字符串文本), ...

  7. 最全Python函数总结和应用(超详细+建议收藏),基本所有内置函数,心得都在这了,踩的坑也在里面了,最后还有函数的魂

    希望能帮助到你 前言 基础的函数了解 惊喜类 all() 和 any() lambda函数 sorted()函数 map()函数 filter()函数 reduce()函数 eval()函数 zip函 ...

  8. 读android内置存储芯片数据,WEIPOS开店宝安卓收银机内置存储DIY硬改扩容成功,分享一下心得和体会...

    认识众多玩家高手/拆客/DIYer,查阅更多资源,一起学习技术知识 您需要 登录 才可以下载或查看,没有帐号?立即注册 x 帖子比较长,请耐心观看哈! 一.前言 之前在坛子里发过贴,向坛子里的大佬们讨 ...

  9. JavaWeb学习心得之JSP内置对象

    一.内置对象(九个) request.response.session.application.config已有详细介绍,这里重点介绍pageContext.out.page对象. 二.page对象 ...

最新文章

  1. IOS中CoreLocation框架地理定位
  2. undefined reference to 'pthread_create'问题解决
  3. MATLAB 获取某个文件夹下所有文件夹或者文件的名字
  4. pandas保存新增sheet表,且不overwrite原有内容
  5. boost::test::string_token_iterator相关的测试程序
  6. yum search php7,yum install php7 in centos6
  7. string和StringBuilder的选择
  8. Python HTTP Error 403: Forbidden
  9. Pytorch基础(一) 初始tensor
  10. TortoiseSVN修改服务器地址的方法
  11. 圈圈教你玩USB(第二版) 笔记
  12. GIM三维建模设计软件
  13. 月薪11970元的网络运维工程师需要掌握哪些必备技能?
  14. EMERGENCY! EUREKA MAY BE INCORRECTLY CLAIMING INSTANCES ARE UP WHEN THEY'RE NOT. RENEWALS ARE
  15. 【修真院java小课堂】什么是restful?rest的请求方法有哪些,有什么区别?
  16. 从飞猪智能酒店到优酷视频,探索阿里智能研发协同流程
  17. C盘瘦身:QQ文件的清理及Group2文件夹
  18. 为什么做机器学习的很少使用假设检验? (转载)
  19. Android项目120项
  20. 编辑距离(Edit Distance) 一文读懂(Python实现)

热门文章

  1. ECharts - 15.旭日图
  2. 推荐系统工程系列(1):浅谈推荐系统架构
  3. 三天学会网络爬虫之Day03
  4. 【图形学】计算机图形学-练习题7
  5. 哈工大计算机学院学号,【复试机试内容回忆汇总帖】2019年哈尔滨工业大学计算机考研...
  6. openjudge 7920 统计单词数
  7. PPP中常用定位和误差模型
  8. MaxCompute SQL大数据公开数据集实战
  9. 使用腾讯云sms实现短信验证功能
  10. C语言动态申请内存空间之malloc(),calloc(),realloc()函数