一、环境介绍
MCU: CC2530(Zigbee)
光敏传感器: BH1750数字传感器(IIC接口)
开发软件: IAR
代码说明:使用IIC模拟时序驱动,IIC时序代码与BH1750代码都采用模块化编程,代码清晰,注释完整,方便移植到其他平台,采集的光照度比较灵敏. 合成的光照度返回值范围是 0~255。 0表示全黑 255表示很亮。
实测: 手机闪光灯照着的状态返回值是245左右,手捂着的状态返回值是10左右.
完整工程源码下载地址: https://download.csdn.net/download/xiaolong1126626497/18502155
二、BH1750介绍
ADDR引脚接地地址就是0X46。
三、硬件接线效果
四、核心代码
4.1 iic.c
代码语言:javascript复制#include "iic.h"
/*
函数功能:IIC接口初始化
硬件连接:
SDA:P1.2
SCL:P1.3
*/
void IIC_Init(void)
{
P1SEL&=~(0x3<<2); //配置通用GPIO口模式
P1DIR|=0x3<<2; //配置为输出模式
}
/*
函数功能: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;
}
4.2 iic.h
代码语言:javascript复制#ifndef _IIC_H
#define _IIC_H
#include "sys.h"
#include "delay.h"
/*
硬件连接:
SDA:P1.2
SCL:P1.3
*/
#define IIC_SDA_OUTMODE() {P1DIR|=0x1<<2;}
#define IIC_SDA_INPUTMODE() {P1DIR&=~(0x1<<2);}
#define IIC_SDA_OUT P1_2 //数据线输出
#define IIC_SDA_IN P1_2 //数据线输入
#define IIC_SCL P1_3 //时钟线
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
4.3 bh1750.c
代码语言:javascript复制#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)USART0_Printf("error:1rn");
IIC_WriteOneByteData(0x01);
r_s=IIC_GetACK();//获取应答
if(r_s)USART0_Printf("error:2rn");
IIC_Stop(); //停止信号
IIC_Start(); //发送起始信号
IIC_WriteOneByteData(0x46);
r_s=IIC_GetACK();//获取应答
if(r_s)USART0_Printf("error:3rn");
IIC_WriteOneByteData(0x01);
r_s=IIC_GetACK();//获取应答
if(r_s)USART0_Printf("error:4rn");
IIC_Stop(); //停止信号
IIC_Start(); //发送起始信号
IIC_WriteOneByteData(0x46);
r_s=IIC_GetACK();//获取应答
if(r_s)USART0_Printf("error:5rn");
IIC_WriteOneByteData(0x10);
r_s=IIC_GetACK();//获取应答
if(r_s)USART0_Printf("error:6rn");
IIC_Stop(); //停止信号
DelayMs(300); //等待
IIC_Start(); //发送起始信号
IIC_WriteOneByteData(0x47);
r_s=IIC_GetACK();//获取应答
if(r_s)USART0_Printf("error:7rn");
t0=IIC_ReadOneByteData(); //接收数据
IIC_SendACK(0); //发送应答信号
t1=IIC_ReadOneByteData(); //接收数据
IIC_SendACK(1); //发送非应答信号
IIC_Stop(); //停止信号
t=(((t0<<8)|t1)/1.2);
return t;
}
4.4 bh1750.h
代码语言:javascript复制#ifndef _BH1750_H
#define _BH1750_H
#include "delay.h"
#include "iic.h"
#include "uart.h"
u8 Read_BH1750_Data(void);
#endif