一、环境介绍
开发软件:Keil5
代码说明:使用IIC模拟时序驱动,方便移植到其他平台,采集的光照度比较灵敏. 合成的光照度返回值范围是 0~255。 0表示全黑 255表示很亮。
实测: 手机闪光灯照着的状态返回值是245左右,手捂着的状态返回值是10左右.
二、BH1750介绍
三、核心代码
BH1750说明: ADDR引脚接地,地址就是0x46
完整工程代码下载:https://download.csdn.net/download/xiaolong1126626497/18500653
3.1 iic.c
#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;
}
3.2 iic.h
#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
3.3 BH1750.h
#ifndef _BH1750_H
#define _BH1750_H
#include "delay.h"
#include "iic.h"
#include "usart.h"
u8 Read_BH1750_Data(void);
#endif
3.4 BH1750.c
#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;
}
3.5 main.c
#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;
}
}
}
3.6 运行效果图
审核编辑:符乾江
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。
举报投诉
-
传感器
+关注
关注
2548文章
50678浏览量
752015 -
STM32
+关注
关注
2266文章
10871浏览量
354814
发布评论请先 登录
相关推荐
光照传感器和光敏电阻区别在哪
光照传感器和光敏电阻是两种不同的光电元件,它们在光电领域中有着广泛的应用。虽然它们都对光有响应,但它们在工作原理、结构、性能、应用等方面存在显著差异。 一、工作原理 光照
CW32模块使用:光敏电阻光照传感器
光敏电阻是用硫化隔或硒化隔等半导体材料制成的特殊电阻器,其工作原理是基于内光电效应。随着光照强度的升高,电阻值迅速降低,由于光照产生的载流子都参与导电,在外加电场的作用下作漂移运动,电
16位数字输出型环境光强度传感器集成电路bh1750FVI中文数据手册
电子发烧友网站提供《16位数字输出型环境光强度传感器集成电路bh1750FVI中文数据手册.pdf》资料免费下载
发表于 09-11 14:26
•2次下载
光敏电阻在光照下阻值是减小还是增大
光敏电阻是一种特殊的电阻元件,其电阻值会随着光照强度的变化而发生变化。在光照下,光敏电阻的阻值是减小还是增大,取决于光敏电阻的类型和材料。
光敏电阻在无光照射时呈什么状态
光敏电阻是一种特殊的电阻器,其电阻值会随着光照强度的变化而变化。在无光照射时,光敏电阻的电阻值会显著增大,表现出高阻抗的特性。 一、
光敏电阻随光照强度的变化规律
光敏电阻是一种半导体材料,其电阻值会随着光照强度的变化而变化。这种特性使得光敏电阻在许多领域得到广泛应用,如光控开关、光度计、自动控制等。 一、光敏电阻的工作原理
光敏电阻与光照强度的关系是什么
光敏电阻是一种特殊的电阻元件,其电阻值会随着光照强度的变化而变化。 一、光敏电阻的工作原理 光敏电阻是一种半导体材料制成的电阻元件,其电阻值会随着光
光敏电阻与光敏二极管哪个灵敏度高
光敏电阻和光敏二极管都是常见的光敏元件,它们在光电传感器、光控开关、光通信等领域有着广泛的应用。然而,它们的灵敏度和性能特点却存在一定的差异。 光敏
硅光电池测量光照强度
我了解到的原理是,硅光电池的电池内阻远大于R1,且在一定光强范围内,输出电流(uA级别)随光照强度的增加而线性增加,所以我想通过2DU3硅光电池通过以下电路,将硅光电池输出电流通过R1转化为电压,并
发表于 04-02 15:20
【外设移植】I2C 光照度传感器(BH1750)M61开发板驱动
本作品由安信可社区用户 制作 IC光度传感器模块种类很多,我选择一种比较常用的模块(BH1750)做外设移植。BH1750的优点如下: 1、支持标准快速模式的IIC通信 2、模块IIC通信地址可以
【飞腾派4G版免费试用】硬件编程、运行、代码编译之I2C光照传感器调试
。它采用了专门的光敏元件和 ADC(模数转换器),能够将光照强度转换为数字输出。BH1750 芯片具有高分辨率和广泛的动态范围,适用于各种光照
发表于 12-17 18:00
评论