[其他ST产品] STM32+BH1750光敏传感器获取光照强度

[复制链接]
718|11
 楼主| 是你的乱码 发表于 2023-1-15 23:23 | 显示全部楼层 |阅读模式
一、环境介绍
MCU:  STM32F103ZET6

光敏传感器: BH1750数字传感器(IIC接口)

开发软件: Keil5

代码说明:使用IIC模拟时序驱动,方便移植到其他平台,采集的光照度比较灵敏.  合成的光照度返回值范围是 0~255。 0表示全黑  255表示很亮。

实测:   手机闪光灯照着的状态返回值是245左右,手捂着的状态返回值是10左右.

完整工程代码下载: https://download.csdn.net/download/xiaolong1126626497/18500653

3406363c41a7fb3dcf.png

 楼主| 是你的乱码 发表于 2023-1-15 23:26 | 显示全部楼层
 楼主| 是你的乱码 发表于 2023-1-15 23:27 | 显示全部楼层
BH1750介绍
5046463c41b657c4c3.png
 楼主| 是你的乱码 发表于 2023-1-15 23:28 | 显示全部楼层
 楼主| 是你的乱码 发表于 2023-1-15 23:29 | 显示全部楼层
 楼主| 是你的乱码 发表于 2023-1-15 23:30 | 显示全部楼层
核心代码
BH1750说明:  ADDR引脚接地,地址就是0x46
 楼主| 是你的乱码 发表于 2023-1-15 23:31 | 显示全部楼层
iic.c
  1. #include "iic.h"

  2. /*
  3. 函数功能:IIC接口初始化
  4. 硬件连接:
  5. SDA:PB7
  6. SCL:PB6
  7. */
  8. void IIC_Init(void)
  9. {
  10.         RCC->APB2ENR|=1<<3;//PB
  11.         GPIOB->CRL&=0x00FFFFFF;
  12.         GPIOB->CRL|=0x33000000;
  13.         GPIOB->ODR|=0x3<<6;
  14. }

  15. /*
  16. 函数功能:IIC总线起始信号
  17. */
  18. void IIC_Start(void)
  19. {
  20.                 IIC_SDA_OUTMODE(); //初始化SDA为输出模式
  21.                 IIC_SDA_OUT=1;                  //数据线拉高
  22.                 IIC_SCL=1;                      //时钟线拉高
  23.                 DelayUs(4);        //电平保持时间
  24.                 IIC_SDA_OUT=0;                  //数据线拉低
  25.                 DelayUs(4);        //电平保持时间
  26.                 IIC_SCL=0;                      //时钟线拉低
  27. }


  28. /*
  29. 函数功能:IIC总线停止信号
  30. */
  31. void IIC_Stop(void)
  32. {
  33.                 IIC_SDA_OUTMODE(); //初始化SDA为输出模式
  34.                 IIC_SDA_OUT=0;                  //数据线拉低
  35.                 IIC_SCL=0;                      //时钟线拉低
  36.                 DelayUs(4);        //电平保持时间
  37.                 IIC_SCL=1;                      //时钟线拉高
  38.                 DelayUs(4);        //电平保持时间
  39.                 IIC_SDA_OUT=1;                  //数据线拉高
  40. }

  41. /*
  42. 函数功能:获取应答信号
  43. 返 回 值:1表示失败,0表示成功
  44. */
  45. u8 IIC_GetACK(void)
  46. {
  47.                 u8 cnt=0;
  48.                 IIC_SDA_INPUTMODE();//初始化SDA为输入模式
  49.                 IIC_SDA_OUT=1;                   //数据线上拉
  50.           DelayUs(2);         //电平保持时间
  51.                 IIC_SCL=0;                       //时钟线拉低,告诉从机,主机需要数据
  52.                 DelayUs(2);         //电平保持时间,等待从机发送数据
  53.           IIC_SCL=1;                       //时钟线拉高,告诉从机,主机现在开始读取数据
  54.                 while(IIC_SDA_IN)   //等待从机应答信号
  55.                 {
  56.                                 cnt++;
  57.                                 if(cnt>250)return 1;
  58.                 }
  59.                 IIC_SCL=0;                       //时钟线拉低,告诉从机,主机需要数据
  60.                 return 0;
  61. }

  62. /*
  63. 函数功能:主机向从机发送应答信号
  64. 函数形参:0表示应答,1表示非应答
  65. */
  66. void IIC_SendACK(u8 stat)
  67. {
  68.                 IIC_SDA_OUTMODE(); //初始化SDA为输出模式
  69.                 IIC_SCL=0;                      //时钟线拉低,告诉从机,主机需要发送数据
  70.                 if(stat)IIC_SDA_OUT=1; //数据线拉高,发送非应答信号
  71.                 else IIC_SDA_OUT=0;          //数据线拉低,发送应答信号
  72.                 DelayUs(2);            //电平保持时间,等待时钟线稳定
  73.                 IIC_SCL=1;                          //时钟线拉高,告诉从机,主机数据发送完毕
  74.                 DelayUs(2);            //电平保持时间,等待从机接收数据
  75.                 IIC_SCL=0;                                //时钟线拉低,告诉从机,主机需要数据
  76. }


  77. /*
  78. 函数功能:IIC发送1个字节数据
  79. 函数形参:将要发送的数据
  80. */
  81. void IIC_WriteOneByteData(u8 data)
  82. {
  83.                 u8 i;
  84.                 IIC_SDA_OUTMODE(); //初始化SDA为输出模式
  85.                 IIC_SCL=0;                      //时钟线拉低,告诉从机,主机需要发送数据
  86.                 for(i=0;i<8;i++)
  87.                 {
  88.                                 if(data&0x80)IIC_SDA_OUT=1; //数据线拉高,发送1
  89.                                 else IIC_SDA_OUT=0;          //数据线拉低,发送0
  90.                                 IIC_SCL=1;                          //时钟线拉高,告诉从机,主机数据发送完毕
  91.                                 DelayUs(2);            //电平保持时间,等待从机接收数据
  92.                                 IIC_SCL=0;                                       //时钟线拉低,告诉从机,主机需要发送数据
  93.                                 DelayUs(2);            //电平保持时间,等待时钟线稳定
  94.                                 data<<=1;              //先发高位
  95.                 }
  96. }


  97. /*
  98. 函数功能:IIC接收1个字节数据
  99. 返 回 值:收到的数据
  100. */
  101. u8 IIC_ReadOneByteData(void)
  102. {
  103.                 u8 i,data;
  104.                 IIC_SDA_INPUTMODE();//初始化SDA为输入模式
  105.           for(i=0;i<8;i++)
  106.           {
  107.                                  IIC_SCL=0;                       //时钟线拉低,告诉从机,主机需要数据
  108.                                 DelayUs(2);         //电平保持时间,等待从机发送数据
  109.                                 IIC_SCL=1;                       //时钟线拉高,告诉从机,主机现在正在读取数据
  110.                                 data<<=1;           
  111.                                 if(IIC_SDA_IN)data|=0x01;
  112.                                 DelayUs(2);         //电平保持时间,等待时钟线稳定
  113.           }
  114.                 IIC_SCL=0;                                       //时钟线拉低,告诉从机,主机需要数据 (必须拉低,否则将会识别为停止信号)
  115.                 return data;
  116. }

 楼主| 是你的乱码 发表于 2023-1-15 23:31 | 显示全部楼层
iic.h
  1. #ifndef _IIC_H
  2. #define _IIC_H
  3. #include "stm32f10x.h"
  4. #include "sys.h"
  5. #include "delay.h"
  6. #define IIC_SDA_OUTMODE() {GPIOB->CRL&=0x0FFFFFFF;GPIOB->CRL|=0x30000000;}
  7. #define IIC_SDA_INPUTMODE() {GPIOB->CRL&=0x0FFFFFFF;GPIOB->CRL|=0x80000000;}
  8. #define IIC_SDA_OUT PBout(7)  //数据线输出
  9. #define IIC_SDA_IN PBin(7)  //数据线输入
  10. #define IIC_SCL PBout(6)  //时钟线

  11. void IIC_Init(void);
  12. void IIC_Start(void);
  13. void IIC_Stop(void);
  14. u8 IIC_GetACK(void);
  15. void IIC_SendACK(u8 stat);
  16. void IIC_WriteOneByteData(u8 data);
  17. u8 IIC_ReadOneByteData(void);
  18. #endif
 楼主| 是你的乱码 发表于 2023-1-15 23:32 | 显示全部楼层
BH1750.h
  1. #ifndef _BH1750_H
  2. #define _BH1750_H
  3. #include "delay.h"
  4. #include "iic.h"
  5. #include "usart.h"
  6. u8 Read_BH1750_Data(void);
  7. #endif
 楼主| 是你的乱码 发表于 2023-1-15 23:33 | 显示全部楼层
BH1750.c
  1. #include "bh1750.h"
  2. u8 Read_BH1750_Data()
  3. {
  4.     unsigned char t0;
  5.     unsigned char t1;
  6.     unsigned char t;
  7.     u8 r_s=0;
  8.     IIC_Start(); //发送起始信号
  9.     IIC_WriteOneByteData(0x46);
  10.     r_s=IIC_GetACK();//获取应答
  11.     if(r_s)printf("error:1\r\n");
  12.     IIC_WriteOneByteData(0x01);
  13.     r_s=IIC_GetACK();//获取应答
  14.      if(r_s)printf("error:2\r\n");
  15.     IIC_Stop(); //停止信号
  16.    
  17.     IIC_Start(); //发送起始信号
  18.     IIC_WriteOneByteData(0x46);
  19.     r_s=IIC_GetACK();//获取应答
  20.     if(r_s)printf("error:3\r\n");
  21.     IIC_WriteOneByteData(0x01);
  22.     r_s=IIC_GetACK();//获取应答
  23.     if(r_s)printf("error:4\r\n");
  24.     IIC_Stop(); //停止信号
  25.    
  26.     IIC_Start(); //发送起始信号
  27.     IIC_WriteOneByteData(0x46);
  28.     r_s=IIC_GetACK();//获取应答
  29.     if(r_s)printf("error:5\r\n");
  30.     IIC_WriteOneByteData(0x10);
  31.     r_s=IIC_GetACK();//获取应答
  32.     if(r_s)printf("error:6\r\n");
  33.     IIC_Stop(); //停止信号
  34.    
  35.     DelayMs(300); //等待
  36.    
  37.     IIC_Start(); //发送起始信号
  38.     IIC_WriteOneByteData(0x47);
  39.     r_s=IIC_GetACK();//获取应答
  40.     if(r_s)printf("error:7\r\n");
  41.    
  42.     t0=IIC_ReadOneByteData(); //接收数据
  43.     IIC_SendACK(0); //发送应答信号
  44.     t1=IIC_ReadOneByteData(); //接收数据
  45.     IIC_SendACK(1); //发送非应答信号
  46.     IIC_Stop(); //停止信号
  47.    
  48.      t=(((t0<<8)|t1)/1.2);
  49.      return t;  
  50. }
 楼主| 是你的乱码 发表于 2023-1-15 23:34 | 显示全部楼层
main.c
  1. #include "stm32f10x.h"
  2. #include "led.h"
  3. #include "delay.h"
  4. #include "key.h"
  5. #include "usart.h"
  6. #include "at24c02.h"
  7. #include "bh1750.h"

  8. int main()
  9. {
  10.         u8 val;
  11.         LED_Init();
  12.         BEEP_Init();
  13.         KeyInit();
  14.   USARTx_Init(USART1,72,115200);
  15.   IIC_Init();
  16.   
  17.         while(1)
  18.         {
  19.                 val=KeyScan();
  20.                 if(val)
  21.                 {
  22.             val=Read_BH1750_Data();
  23.             printf("光照强度=%d\r\n",val);
  24. //                         BEEP=!BEEP;
  25.                          LED0=!LED0;
  26.                          LED1=!LED1;
  27.                 }
  28.         }
  29. }
 楼主| 是你的乱码 发表于 2023-1-15 23:35 | 显示全部楼层
运行效果图
4676163c41d2892b25.png
您需要登录后才可以回帖 登录 | 注册

本版积分规则

35

主题

490

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部