MCU: STM32F103ZET6
光敏传感器: BH1750数字传感器(IIC接口)
开发软件: Keil5
代码说明:使用IIC模拟时序驱动,方便移植到其他平台,采集的光照度比较灵敏. 合成的光照度返回值范围是 0~255。 0表示全黑 255表示很亮。
实测: 手机闪光灯照着的状态返回值是245左右,手捂着的状态返回值是10左右.
BH1750说明: ADDR引脚接地,地址就是0x46
- #include "iic.h"
-
- /*
- 函数功能:IIC接口初始化
- 硬件连接:
- SDA:PB7
- SCL:PB6
- */
- void IIC_Init(void)
- {
- RCC->APB2ENR|=1<<3;//PB
- GPIOB->CRL&=0x00FFFFFF;
- GPIOB->CRL|=0x33000000;
- GPIOB->ODR|=0x3<<6;
- }
-
- /*
- 函数功能:IIC总线起始信号
- */
- void IIC_Start(void)
- {
- IIC_SDA_OUTMODE(); //初始化SDA为输出模式
- IIC_SDA_OUT=1; //数据线拉高
- IIC_SCL=1; //时钟线拉高
- DelayUs(4); //电平保持时间
- IIC_SDA_OUT=0; //数据线拉低
- DelayUs(4); //电平保持时间
- IIC_SCL=0; //时钟线拉低
- }
-
-
- /*
- 函数功能:IIC总线停止信号
- */
- void IIC_Stop(void)
- {
- IIC_SDA_OUTMODE(); //初始化SDA为输出模式
- IIC_SDA_OUT=0; //数据线拉低
- IIC_SCL=0; //时钟线拉低
- DelayUs(4); //电平保持时间
- IIC_SCL=1; //时钟线拉高
- DelayUs(4); //电平保持时间
- IIC_SDA_OUT=1; //数据线拉高
- }
-
- /*
- 函数功能:获取应答信号
- 返 回 值:1表示失败,0表示成功
- */
- u8 IIC_GetACK(void)
- {
- u8 cnt=0;
- IIC_SDA_INPUTMODE();//初始化SDA为输入模式
- IIC_SDA_OUT=1; //数据线上拉
- DelayUs(2); //电平保持时间
- IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据
- DelayUs(2); //电平保持时间,等待从机发送数据
- IIC_SCL=1; //时钟线拉高,告诉从机,主机现在开始读取数据
- while(IIC_SDA_IN) //等待从机应答信号
- {
- cnt++;
- if(cnt>250)return 1;
- }
- IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据
- return 0;
- }
-
- /*
- 函数功能:主机向从机发送应答信号
- 函数形参:0表示应答,1表示非应答
- */
- void IIC_SendACK(u8 stat)
- {
- IIC_SDA_OUTMODE(); //初始化SDA为输出模式
- IIC_SCL=0; //时钟线拉低,告诉从机,主机需要发送数据
- if(stat)IIC_SDA_OUT=1; //数据线拉高,发送非应答信号
- else IIC_SDA_OUT=0; //数据线拉低,发送应答信号
- DelayUs(2); //电平保持时间,等待时钟线稳定
- IIC_SCL=1; //时钟线拉高,告诉从机,主机数据发送完毕
- DelayUs(2); //电平保持时间,等待从机接收数据
- IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据
- }
-
-
- /*
- 函数功能:IIC发送1个字节数据
- 函数形参:将要发送的数据
- */
- void IIC_WriteOneByteData(u8 data)
- {
- u8 i;
- IIC_SDA_OUTMODE(); //初始化SDA为输出模式
- IIC_SCL=0; //时钟线拉低,告诉从机,主机需要发送数据
- for(i=0;i<8;i++)
- {
- if(data&0x80)IIC_SDA_OUT=1; //数据线拉高,发送1
- else IIC_SDA_OUT=0; //数据线拉低,发送0
- IIC_SCL=1; //时钟线拉高,告诉从机,主机数据发送完毕
- DelayUs(2); //电平保持时间,等待从机接收数据
- IIC_SCL=0; //时钟线拉低,告诉从机,主机需要发送数据
- DelayUs(2); //电平保持时间,等待时钟线稳定
- data<<=1; //先发高位
- }
- }
-
-
- /*
- 函数功能:IIC接收1个字节数据
- 返 回 值:收到的数据
- */
- u8 IIC_ReadOneByteData(void)
- {
- u8 i,data;
- IIC_SDA_INPUTMODE();//初始化SDA为输入模式
- for(i=0;i<8;i++)
- {
- IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据
- DelayUs(2); //电平保持时间,等待从机发送数据
- IIC_SCL=1; //时钟线拉高,告诉从机,主机现在正在读取数据
- data<<=1;
- if(IIC_SDA_IN)data|=0x01;
- DelayUs(2); //电平保持时间,等待时钟线稳定
- }
- IIC_SCL=0; //时钟线拉低,告诉从机,主机需要数据 (必须拉低,否则将会识别为停止信号)
- return data;
- }
-
-
-
- #ifndef _IIC_H
- #define _IIC_H
- #include "stm32f10x.h"
- #include "sys.h"
- #include "delay.h"
- #define IIC_SDA_OUTMODE() {GPIOB->CRL&=0x0FFFFFFF;GPIOB->CRL|=0x30000000;}
- #define IIC_SDA_INPUTMODE() {GPIOB->CRL&=0x0FFFFFFF;GPIOB->CRL|=0x80000000;}
- #define IIC_SDA_OUT PBout(7) //数据线输出
- #define IIC_SDA_IN PBin(7) //数据线输入
- #define IIC_SCL PBout(6) //时钟线
-
- void IIC_Init(void);
- void IIC_Start(void);
- void IIC_Stop(void);
- u8 IIC_GetACK(void);
- void IIC_SendACK(u8 stat);
- void IIC_WriteOneByteData(u8 data);
- u8 IIC_ReadOneByteData(void);
- #endif
-
-
- #ifndef _BH1750_H
- #define _BH1750_H
- #include "delay.h"
- #include "iic.h"
- #include "usart.h"
- u8 Read_BH1750_Data(void);
- #endif
-
- #include "bh1750.h"
- u8 Read_BH1750_Data()
- {
- unsigned char t0;
- unsigned char t1;
- unsigned char t;
- u8 r_s=0;
- IIC_Start(); //发送起始信号
- IIC_WriteOneByteData(0x46);
- r_s=IIC_GetACK();//获取应答
- if(r_s)printf("error:1\r\n");
- IIC_WriteOneByteData(0x01);
- r_s=IIC_GetACK();//获取应答
- if(r_s)printf("error:2\r\n");
- IIC_Stop(); //停止信号
-
- IIC_Start(); //发送起始信号
- IIC_WriteOneByteData(0x46);
- r_s=IIC_GetACK();//获取应答
- if(r_s)printf("error:3\r\n");
- IIC_WriteOneByteData(0x01);
- r_s=IIC_GetACK();//获取应答
- if(r_s)printf("error:4\r\n");
- IIC_Stop(); //停止信号
-
- IIC_Start(); //发送起始信号
- IIC_WriteOneByteData(0x46);
- r_s=IIC_GetACK();//获取应答
- if(r_s)printf("error:5\r\n");
- IIC_WriteOneByteData(0x10);
- r_s=IIC_GetACK();//获取应答
- if(r_s)printf("error:6\r\n");
- IIC_Stop(); //停止信号
-
- DelayMs(300); //等待
-
- IIC_Start(); //发送起始信号
- IIC_WriteOneByteData(0x47);
- r_s=IIC_GetACK();//获取应答
- if(r_s)printf("error:7\r\n");
-
- t0=IIC_ReadOneByteData(); //接收数据
- IIC_SendACK(0); //发送应答信号
- t1=IIC_ReadOneByteData(); //接收数据
- IIC_SendACK(1); //发送非应答信号
- IIC_Stop(); //停止信号
-
- t=(((t0<<8)|t1)/1.2);
- return t;
- }
-
-
- #include "stm32f10x.h"
- #include "led.h"
- #include "delay.h"
- #include "key.h"
- #include "usart.h"
- #include "at24c02.h"
- #include "bh1750.h"
-
- int main()
- {
- u8 val;
- LED_Init();
- BEEP_Init();
- KeyInit();
- USARTx_Init(USART1,72,115200);
- IIC_Init();
-
- while(1)
- {
- val=KeyScan();
- if(val)
- {
- val=Read_BH1750_Data();
- printf("光照强度=%d\r\n",val);
- // BEEP=!BEEP;
- LED0=!LED0;
- LED1=!LED1;
- }
- }
- }
-
-