根据csdn博主是ta实现了BH1750读取功能。
原文链接:stm32f103C8T6使用硬件IIC读取BH1750光强传感器数值_stm32f103c8t6gpio接收传感器信息-CSDN博客
若想更了解BH1750则可以去看看:
STM32应用开发——BH1750光照传感器详解_stm32驱动bh1750-CSDN博客
硬件I2C主发送器传送序列图:
硬件I2C主接收器传送序列图:
BH1750指令集:
I2C读写流程:
发送指令流程:起始信号—>从机地址+读写位—>从机应答—>发送指令集—>从机应答—>结束
读取测量结果流程:起始信号—>从机地址+读写位—>从机应答—>从机发送高8位—>主机应答—>从机发送低8位—>主机未应答—>结束
(当发送方发送完一个数据后,接收方未应答便会结束通讯)
代码(软件用的Kile5):
bh1750.c
#include "stm32f10x.h" // Device header
#include"OLED.h"
#define SlaveAddress 0x46 //定义器件在I2C的从地址,ADDR接地为0x46,接电源为0xB8
uint8_t Lightgrad[2]={0};//光照度数值
//待超时退出的事件等待函数
void WaitEvent(I2C_TypeDef* I2Cx,uint32_t I2C_EVENT)
{
uint32_t timecount=40000;
while(I2C_CheckEvent(I2Cx,I2C_EVENT) == ERROR)
{
timecount--;
if(timecount == 0)//超时等待退出
{
break;
}
}
}
//写一个命令字节
void BH1750_WriteCommand(uint8_t command)
{
I2C_GenerateSTART(I2C1,ENABLE);//生成起始条件
WaitEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT);//等待ev5事件的到来
//参数1:选择的I2Cx,参数2:从机地址,参数3:指定I2C的设备是发送器(Transmitter)或接收(Receiver)
I2C_Send7bitAddress(I2C1,SlaveAddress,I2C_Direction_Transmitter);
//硬件I2C会自动获取应答标志位,根据标志位,若未应答则申请中断
WaitEvent(I2C1,I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED);//等待ev6事件的到来
I2C_SendData(I2C1,command);//发送命令
WaitEvent(I2C1,I2C_EVENT_MASTER_BYTE_TRANSMITTED);//等待ev8_2事件的到来
I2C_GenerateSTOP(I2C1,ENABLE);
}
//连续读出光照度传感器中的数据
void BH1750_Read(void)
{
uint8_t i;
uint16_t t=40000;
while(I2C_GetFlagStatus(I2C1,I2C_FLAG_BUSY))
{
t--;
if(t==0)//超时等待退出
{
return;
}
}
I2C_GenerateSTART(I2C1,ENABLE);//生成起始条件
WaitEvent(I2C1,I2C_EVENT_MASTER_MODE_SELECT);//等待EV5事件的到来
I2C_Send7bitAddress(I2C1,SlaveAddress,I2C_Direction_Receiver);//发送设备地址加读信号
WaitEvent(I2C1,I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED);//等待EV6事件到来
for(i=0;i<2;i++)
{
if(i==1)//最后一个数据读到之前,发送非应答和停止信号
{
I2C_AcknowledgeConfig(I2C1,DISABLE);//取消应答
I2C_GenerateSTOP(I2C1,ENABLE);//停止信号
}
WaitEvent(I2C1,I2C_EVENT_MASTER_BYTE_RECEIVED);//等待EV7事件的到来
Lightgrad[i]=I2C_ReceiveData(I2C1);//读数据
}
I2C_AcknowledgeConfig(I2C1,ENABLE);//恢复应答
}
void LightGard_Init(void)
{
//RCC开启时钟
RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO | RCC_APB2Periph_GPIOB,ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);
//配置GPIO
GPIO_InitTypeDef GPIO_InitStructure;
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;//开漏输出
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7;
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOB,&GPIO_InitStructure);
//I2C配置
I2C_InitTypeDef I2C_InitStructure;
I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;//接受数据是否应答
I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;//7位地址
I2C_InitStructure.I2C_ClockSpeed = 50000;//速度
I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;//占空比2:1
I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;//I2C模式
I2C_InitStructure.I2C_OwnAddress1 = 0x00;//作为从机时自身地址
I2C_Init(I2C1,&I2C_InitStructure);
//开启I2C
I2C_Cmd(I2C1,ENABLE);
//光跟强度传感器控制信号
//因为此处初始化为”连续“模式,所以只器要在初始化时发送一次通电宿令,和一次分辨率模式宿令
//在主函业的while循环中不要磊要在写这两个命令
BH1750_WriteCommand(0x01);//通电指令
BH1750_WriteCommand(0x10);//连续高分辨率模式
}
bh1750.h
#ifndef __BH1750_H
#define __BH1750_H
extern uint8_t Lightgrad[2];//光照度强度数值
void BH1750_WriteCommand(uint8_t command);//写入B1750命令
void BH1750_Read(void);//读取BH1750数值
void LightGard_Init(void);//初始化BH1750
#endif
main.c
#include "stm32f10x.h" // Device header
#include "Delay.h"
#include "BH1750.h"
#include "OLED.h"
uint16_t data=0;
int main(void)
{
OLED_Init();//OLED初始化
LightGard_Init();
while (1)
{
BH1750_Read ();
data=Lightgrad[0];
data=(data<<8) | Lightgrad[1];
OLED_ShowBinNum(1,1,Lightgrad[0],8);
OLED_ShowBinNum(2,1,Lightgrad[1],8);
OLED_ShowString(3,1,"Light:");
OLED_ShowNum(3,7,data,4);
OLED_ShowString(3,11,"lx");
}
}
实现效果: