资讯详情

STM32 驱动 GY-302 光照传感器 BH1750 模块(软件IIC与硬件IIC驱动)

如果不想看原理和流程,可以直接下拉找代码。都是测试过的,很稳定,有的,也有的,基于STM32F103系列和STM32F4系列实现,基于标准库,组织清晰。

2.软硬件准备

(1) Kile 5.27

(2) 串口助手

(3) STM32F103与STM32F4系列单片机

(4) CH340 串口转 TTL 工具

(5) BH1750-即-GY-302光照传感器

在这里插入图片描述 这是基于标准的官方数据手册的驱动说明I2C传感器的设计,即它的支撑(实测确实没问题);这个流程图大概说的是程序设计:

VCC 5V~3.3V
GND GND
SCL PB6
SDA PB7
ADDR VCC/GND

首先,这个模块更友好,,其次,特别注意ADDR引脚接线:

在这里插入图片描述

高电平硬件地址与低电平硬件地址不同:

硬件地址: ()

硬件地址: ()

3.3驱动时序

在这里插入图片描述

3.3.指令集说明

功能 寄存器地址指令 注释说明
断电 0000_0000 没有活动。
接通电源 0000_0001 等待测量命令。
重置 0000_0111 重置数据寄存器值。重置命令不能在关机模式下接受。
连续H分辨率模式 0001_0000 以1lx开始测量分辨率。测量时间通常为120ms。
连续h分辨率模式2 0001_0001 在0.5lx开始测量分辨率。测量时间通常为120ms。
连续L分辨率模式 0001_0011 以4lx开始测量分辨率。测量时间通常为16ms。
一次H分辨率模式 0010_0000 以1lx开始测量分辨率。测量时间通常为120ms。测量后自动设置为关机模式。
一次H分辨率模式2 0010_0001 在0.5lx开始测量分辨率。测量时间通常为120ms。测量后自动设置为关机模式。
一次性L分辨率模式 0010_0011 以4lx开始测量分辨率。测量时间通常为16ms。测量后自动设置为关机模式。
改变测量时间(高位) 01000_MT[7,6,5] 改变测量时间。※请参考调整测量结果对光学窗口的影响。
改变测量时间(低位) 011_MT[4,3,2,1,0] 改变测量时间。※请参考调整测量结果对光学窗口的影响。

3.4数据转换

在这里插入图片描述

(uint16_t)Data_LX = (uint16_t)(H_data << 8) (uint8_t)L_data

无符号短 8 位整形接收,移位对齐数据再加;

4.上代码

4.1硬件IIC驱动

特别说明硬件驱动刚开始的时候出了一个小问题:完全按照手册的顺序写,就是会卡在接收高 8 位数据的 EV7事件上;

解决方案:发送阅读指令并收到回应后(EV6 事件)主机向光照模块发送 ACK 信号相当于告诉它我们准备好接受数据,然后等待光模块发送数据(EV7事件),然后就没问题了。

4.1.1 适用STM32F103系列的硬件IIC驱动

BH1750.c

#include  "BH1750.h"/****************************************************************************** 函数名称:I2C_Configuration()** 函数功能:显示用到的引脚初始化与 IIC初始化** 参数说明:**** 返回值:无** IIC_InitTypeDef 说明: I2C_ClockSpeed; //设置SCL时钟频率,此值最高 400 000 I2C_Mode; //指定工作模式,可选IIC模式及SMBUS模式 I2C_DutyCycle; //时钟占空比,可选low/high = 2:0或16:9 I2C_OwnAddress1; //自身的IIC设备地址 I2C_Ack; //使能或者关闭响应,一般是使能 I2C_AcknowledgedAddress;//指定地址长度,可为7或10****************************************************************************** STM32F103C8T6芯片的硬件: IIC_1: PB6 -- SCL; PB7 -- SDA IIC_1(重映射):PB8 -- SCL; PB9 -- SDA IIC_2:*****************************************************************************/void I2C_Configuration(void){
         GPIO_InitTypeDef  GPIO_InitStructure;    /* 重映射开启AFIO时钟 */    RCC_APB2PeriphClockCmd(RCC_APB2Periph_AFIO, ENABLE);    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB,ENABLE);    GPIO_PinRemapConfig(GPIO_Remap_I2C1, ENABLE);	//重映射 IIC    /* 重映射引脚 使用IIC_1 PB8 -- SCL; PB9 -- SDA */    GPIO_InitStructure.GPIO_Pin =  GPIO_Pin_8 | GPIO_Pin_9;    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD;	//I2C必须开漏输出    GPIO_Init(GPIOB, &GPIO_InitStructure);    I2C_InitTypeDef  I2C_InitStructure;    RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1,ENABLE);    I2C_DeInit(I2C1);	//使用I2C1    I2C_InitStructure.I2C_Mode = I2C_Mode_I2C;			//选择IIC模式    I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2;	//占空比 1/2    I2C_InitStructure.I2C_OwnAddress1 = 0x30;			//主机的I2C地址    I2C_InitStructure.I2C_Ack = I2C_Ack_Enable;			//应答信号使能    I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit;	//IIC 7 位寻址    I2C_InitStructure.I2C_ClockSpeed = 100000;			//设置最大400K    I2C_Cmd(I2C1, ENABLE);				//使能IIC1    I2C_Init(I2C1, &I2C_InitStructure);	//初始化 IIC_1 相关}/****************************************************************************** 函数名称:BH1750_WriteByte()** 函数功能:BH1750 写数据** 参数说明:** uint8_t addr: 寄存器地址**** 返回值:无** IIC函数说明:** I2C_GetFlagStatus(IIC_x, IIC_Flag_x)-- 检查标志位是否置 1*******************************************************************************/void BH1750_WriteByte(uint8_t addr){
         /* 先判断总线是否忙 */    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));    /* 发送Start信号,切换到主模式(M/SL 位置 1) */    I2C_GenerateSTART(I2C1, ENABLE);    /* 等待EV5事件,IIC开始信号已经发出 */    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));    /* 发送器件地址,发送方向: I2C_Direction_Transmitter */    I2C_Send7bitAddress(I2C1, (BH1750_Addr_GND_REG<<1|0), I2C_Direction_Transmitter);    /* 等待EV6事件:表示地址已经发送 */    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));        /* 发送操作的寄存器地址 */    I2C_SendData(I2C1, addr);    /* 等待EV8事件:数据寄存器DR为空,地址数据已经发送 */    while (!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTING));		    /* 产生应答信号 */    I2C_AcknowledgeConfig(I2C1, ENABLE);    I2C_GenerateSTOP(I2C1, ENABLE);//产生停止信号,关闭I2C1总线}/****************************************************************************** 函数名称:BH1750_Read_Data()** 函数功能:BH1750 读取数据** 参数说明:** uint8_t addr :寄存器地址**** 返回值:RX_Data** IIC函数说明:** I2C_GetFlagStatus(IIC_x, IIC_Flag_x)-- 检查标志位是否置 1*******************************************************************************/uint16_t BH1750_Read_Data(void){
         uint8_t 	H_Data;							//高 8 位数据	uint8_t 	L_Data;							//低 8 位 数据	uint16_t 	Rx_Data;						//完整 16 位数据    while(I2C_GetFlagStatus(I2C1, I2C_FLAG_BUSY));					/* 先判断总线是否忙 */    I2C_GenerateSTART(I2C1, ENABLE); 								/* 发送Start信号,切换到主模式 */    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));		/* 等待EV5事件,IIC开始信号已经发出 */    /* 发送读地址指令,发送方向: I2C_Direction_Receiver */    I2C_Send7bitAddress(I2C1, BH1750_Addr_GND_REG<<1|1, I2C_Direction_Receiver);    /* 等待EV6事件:地址已发送 (接收类型) */    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));	        I2C_AcknowledgeConfig(I2C1, ENABLE);							/* 产生应答信号 */    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED)); 	/* 等待EV7事件 */    H_Data = I2C_ReceiveData(I2C1);									/* 读取高8位数据 */        I2C_AcknowledgeConfig(I2C1, ENABLE);							/* 产生应答信号 */    while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));	/* 等待EV7事件 */	/* 与高8位合成16位完整数据 */	L_Data = I2C_ReceiveData(I2C1);									/* 读取低8位 */	       I2C_AcknowledgeConfig(I2C1, DISABLE); 							/* 产生非应答信号 */	I2C_GenerateSTOP(I2C1, ENABLE);									/** 发送停止信号 **/        Rx_Data = ((uint16_t)H_Data << 8) + L_Data;						/* 16位数据合成 */    return RX_Data;}/** BH1750上电 **/void BH1750_Power_ON(void){
     	BH1750_WriteByte(BH1750_Power_ON_REG);}/** BH1750断电 **/void BH1750_Power_OFF(void){
     	BH1750_WriteByte(BH1750_Power_OFF_REG);}/** BH1750数据寄存器复位 **/void BH1750_RESET(void){
     	BH1750_WriteByte(BH1750_MODULE_RESET_REG);}/** BH1750初始化 **/void BH1750_Init(void){
         I2C_Configuration()

标签: 断电传感器怎么安装

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台