用stm32c8t6读取BH1750光照传感器

根据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");
	}
}

实现效果:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值