你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【年中粉丝节】+BH1750光照度传感器

[复制链接]
liuxingkeji 发布时间:2021-6-8 20:49
【年中粉丝节】+BH1750光照度传感器
今天就再分享下一个光照度传感器。也是比较简单,和之前的温湿度传感器一样的是使用IIC接口,所以两个器件是可以挂载在同一个总线上的,因为他们有不同的地址。
1.png
可以测1-65535lx的光度值。可以用在LCD调光方面。
2.png
下面是芯片内部架构,其实使用的是16位的ADC,输出是12位的,所以可见波动是很小的。
3.png
上面的图是描述的芯片读取数据的一个流程。
4.png
上面是芯片内部寄存器的一个表,同时下面很重要的是器模式配置,可以配置1分度的,也可以配置更高的分辨率0.5和低的4。
5.png
下面直接跳到重点,首先是确定其器件地址,我们这里把ADDR 脚拉低了所以器件地址就是上面是七位同样需要左移一位。变成0100 0110。也就是0x46。
  1. #include "sys.h"

  2. #include "delay.h"

  3. #include "bh1750.h"





  4. #define   SlaveAddress   0x46 //定义器件在IIC总线中的从地址,根据ALT  ADDRESS地址引脚不同修改

  5. uint8_t  BUF[4];                  //接收数据缓存区

  6. extern uint16_t Light_Value;

  7. //uint16_t Light_Value;



  8. void BH1750_PortInit()

  9. {     

  10.        GPIO_InitTypeDef GPIO_InitStructure;



  11.        RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC,ENABLE);

  12.       

  13.        //PB6-SCL PB7-SDA PB12-ADDR

  14.        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6|GPIO_Pin_7;

  15.        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP ;   //推挽输出

  16.        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  17.        GPIO_Init(GPIOB, &GPIO_InitStructure);

  18.        GPIO_SetBits(GPIOB,GPIO_Pin_6|GPIO_Pin_7); //PB6,PB7 输出高

  19.       

  20.        GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2; //PB.14 PB.12

  21.        GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;

  22.        GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;  //复用推挽输出

  23.        GPIO_Init(GPIOC, &GPIO_InitStructure);

  24.             

  25. }





  26. /***************************************************************

  27. ** 功能:     产生IIC起始信号

  28. ** 参数:        无参数

  29. ** 返回值:    无

  30. ****************************************************************/

  31. void BH1750_Start()

  32. {

  33.     SDA_OUT();     //sda线输出

  34.        IIC_SDA=1;            

  35.        IIC_SCL=1;

  36.        delay_us(4);

  37.       IIC_SDA=0;//START:when CLK is high,DATA change form high to low

  38.        delay_us(4);

  39.        IIC_SCL=0;//钳住I2C总线,准备发送或接收数据

  40. }

  41. /***************************************************************

  42. ** 功能:     产生IIC停止信号

  43. ** 参数:        无参数

  44. ** 返回值:    无

  45. ****************************************************************/

  46. void BH1750_Stop()

  47. {

  48.        SDA_OUT();//sda线输出

  49.        IIC_SDA=0;//STOP:when CLK is high DATA change form low to high

  50.        IIC_SCL=1;

  51.       delay_us(4);

  52.        IIC_SDA=1;//发送I2C总线结束信号

  53.        delay_us(4);

  54. }

  55. /***************************************************************

  56. ** 功能:     产生IIC应答信号

  57. ** 参数:        无参数

  58. ** 返回值:    无

  59. ****************************************************************/

  60. void BH1750_SendACK(u8 ack)

  61. {

  62.     SDA_OUT();          //sda线输出

  63.        if(ack)IIC_SDA=1;   //写应答信号

  64.        else IIC_SDA=0;         

  65.     IIC_SCL=1;          //拉高时钟线

  66.     delay_us(2);        //延时

  67.     IIC_SCL=0;          //拉低时钟线

  68.     delay_us(2);        //延时

  69. }



  70. /***************************************************************

  71. ** 功能:     产生IIC接收信号

  72. ** 参数:        无参数

  73. ** 返回值:    无

  74. ****************************************************************/

  75. u8 BH1750_RecvACK()

  76. {

  77.     u8 data;

  78.          SDA_IN();         //SDA设置为输入

  79.     IIC_SCL=1;        //拉高时钟线

  80.     delay_us(2);      //延时

  81.     data = READ_SDA;  //读应答信号

  82.     IIC_SCL=0;        //拉低时钟线

  83.     delay_us(2);      //延时

  84.     return data;

  85. }

  86. /***************************************************************

  87. ** 功能:     向IIC总线发送一个字节数据

  88. ** 参数:        dat:一字节数据

  89. ** 返回值:    无

  90. ****************************************************************/

  91. void BH1750_SendByte(u8 dat)

  92. {

  93.     u8 i,bit;

  94.        SDA_OUT();               //sda线输出

  95.     for (i=0; i<8; i++)      //8位计数器

  96.     {

  97.            bit=dat&0x80;

  98.               if(bit) IIC_SDA=1;

  99.               else IIC_SDA=0;

  100.         dat <<= 1;           //移出数据的最高位

  101.         IIC_SCL=1;           //拉高时钟线

  102.         delay_us(2);         //延时

  103.         IIC_SCL=0;           //拉低时钟线

  104.         delay_us(2);         //延时

  105.     }

  106.     BH1750_RecvACK();

  107. }

  108. /***************************************************************

  109. ** 功能:     从IIC总线接收一个字节数据

  110. ** 参数:        无参数

  111. ** 返回值:   dat:接收一字节数据

  112. ****************************************************************/

  113. u8 BH1750_RecvByte()

  114. {

  115.     u8 i;

  116.     u8 dat = 0;

  117.        SDA_IN();               //SDA设置为输入

  118.     IIC_SDA=1;              //使能内部上拉,准备读取数据,

  119.     for (i=0; i<8; i++)     //8位计数器

  120.     {

  121.         dat <<= 1;

  122.         IIC_SCL=1;          //拉高时钟线

  123.         delay_us(2);        //延时

  124.               if(READ_SDA) dat+=1;              

  125.         IIC_SCL=0;          //拉低时钟线

  126.         delay_us(2);        //延时

  127.     }

  128.     return dat;

  129. }



  130. /***************************************************************

  131. ** 功能:     向bh1750写入命令

  132. ** 参数:        无参数

  133. ** 返回值:   无

  134. ****************************************************************/

  135. void Single_Write_BH1750(u8 REG_Address)

  136. {

  137.     BH1750_Start();                  //起始信号

  138.     BH1750_SendByte(SlaveAddress);   //发送设备地址+写信号

  139.     BH1750_SendByte(REG_Address);    //内部寄存器地址,

  140.     BH1750_Stop();                   //发送停止信号

  141. }



  142. /***************************************************************

  143. ** 功能:     连续读出BH1750内部数据

  144. ** 参数:        无参数

  145. ** 返回值:   无

  146. ****************************************************************/

  147. void Multiple_Read_BH1750(void)

  148. {   u8 i;

  149.     BH1750_Start();                          //起始信号

  150.     BH1750_SendByte(SlaveAddress+1);         //发送设备地址+读信号

  151.       

  152.        for (i=0; i<3; i++)                      //连续读取2个地址数据,存储中BUF

  153.     {

  154.         BUF[i] = BH1750_RecvByte();          //BUF[0]存储0x32地址中的数据

  155.         if (i == 3)

  156.         {

  157.            BH1750_SendACK(1);                //最后一个数据需要回NOACK

  158.         }

  159.         else

  160.         {            

  161.           BH1750_SendACK(0);                //回应ACK

  162.        }

  163.    }

  164.     BH1750_Stop();                          //停止信号

  165. //   delay_ms(150);

  166. }



  167. /***************************************************************

  168. ** 功能:     初始化BH1750

  169. ** 参数:        无参数

  170. ** 返回值:   无

  171. ****************************************************************/

  172. void BH1750_Configure(void)

  173. {

  174.    BH1750_PortInit();

  175.    Single_Write_BH1750(0x01);

  176.    ADDR = 0;                                        //将ADDR位初始化拉低

  177. }



  178. /***************************************************************

  179. ** 功能:     读取光照度

  180. ** 参数:        无参数

  181. ** 返回值:   data:返回光照度值

  182. ****************************************************************/

  183. uint16_t Get_Bh_Value(void)

  184. {

  185.        static float temp;

  186. //     u16 data;

  187.        int dis_data ;

  188.     Single_Write_BH1750(0x01);   // power on

  189.     Single_Write_BH1750(0x10);   // H- resolution mode

  190. //    delay_ms(200);              //延时200ms

  191.     Multiple_Read_BH1750();       //连续读出数据,存储在BUF中

  192.     dis_data=BUF[0];

  193.     dis_data=(dis_data<<8)+BUF[1];//合成数据,即光照数据

  194.     temp=(float)dis_data/1.2;

  195.        Light_Value =(int)temp;

  196.     return Light_Value;      

  197. }
复制代码

上面是所有代码,我们只需要在主函数终循环。Get_Bh_Value(void);就行。
6.png
我们这里就是使用的简单模式H-resolution mode,没有用其模式2,模式二可以更改采样时间,从而提高精度。感兴趣可以自己去看下,就是比较靠后的就是模式二的用法。
7.png
当手机手电筒放到其光窗上可以测到最大54612。还没有到65535。
8.jpg
同样使用的是昨天的板子。

收藏 评论2 发布时间:2021-6-8 20:49

举报

2个回答
STMCU-管管 回答时间:2021-6-9 09:42:48
用的什么STM32的板子可以介绍一下
liuxingkeji 回答时间:2021-6-9 10:57:02
STMCU-管管 发表于 2021-6-9 09:42
用的什么STM32的板子可以介绍一下

用的是自制的STM32F103VET6开发板

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版