|
本帖最后由 hpdell 于 2022-7-12 16:25 编辑
请教下,bh1750 使用硬件 i2c ,读取结果为 0 ??
1750 芯片我的芯片底部没有接地 ,是不是这个原因造成的啊 ??
程序移植 h7 例程里面的
i2c 配置 速度 400K
i2c 的底层驱动是没有问题的,因为我测试读写 at24c512 都是没有问题的
相关程序如下:
bh1750 硬件 addr 接 gnd
#define BH1750_SLAVE_ADDRESS 0x46 /* I2C从机地址 */
// i2c 总线驱动配置
void bsp_i2c2_bus_init(void)
{
I2C2_Handle.Instance = I2C2;
// I2C2_Handle.Init.Timing = 0x307075B1; // i2c speed 100K
I2C2_Handle.Init.Timing = 0x20600714;
// I2C2_Handle.Init.Timing = 0x00B03FDB; // 0x00B03FDB i2c speed 400K
I2C2_Handle.Init.OwnAddress1 = 0;
I2C2_Handle.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
I2C2_Handle.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
I2C2_Handle.Init.OwnAddress2 = 0;
I2C2_Handle.Init.OwnAddress2Masks = I2C_OA2_NOMASK;
I2C2_Handle.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
I2C2_Handle.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
if (HAL_I2C_Init(&I2C2_Handle) != HAL_OK)
{
Error_Handler();
}
// Configure Analogue filter
if (HAL_I2CEx_ConfigAnalogFilter(&I2C2_Handle, I2C_ANALOGFILTER_ENABLE) != HAL_OK)
{
Error_Handler();
}
// Configure Digital filter
if (HAL_I2CEx_ConfigDigitalFilter(&I2C2_Handle, 0) != HAL_OK)
{
Error_Handler();
}
}
/*
*********************************************************************************************************
* 函 数 名: bsp_InitBH1750
* 功能说明: 初始化BH1750
* 形 参: 无
* 返 回 值: 无
*********************************************************************************************************
*/
void bsp_InitBH1750(void)
{
BH1750_WriteCmd(BHOP_POWER_ON); /* 芯片上电 */
BH1750_ChageMode(2); /* 高分辨率连续测量 */
BH1750_AdjustSensitivity(69); /* 芯片缺省灵敏度倍率 = 69 */
}
/*
*********************************************************************************************************
* 函 数 名: BH1750_WriteCmd
* 功能说明: 向芯片发送1字节长度的操作码
* 形 参: _ucOpecode : 寄存器地址
* 返 回 值: 无
*********************************************************************************************************
*/
void BH1750_WriteCmd(uint8_t _ucOpecode)
{
uint32_t Timeout = 1000;
static uint8_t ucOpecode = 0;
ucOpecode = _ucOpecode;
HAL_I2C_Master_Transmit(&I2C2_Handle, BH1750_SLAVE_ADDRESS, &ucOpecode,
1, Timeout);
/* Wait for the end of the transfer */
/* Before starting a new communication transfer, you need to check the current
state of the peripheral; if it抯 busy you need to wait for the end of current
transfer before starting a new one.
For simplicity reasons, this example is just waiting till the end of the
transfer, but application may perform other tasks while transfer operation
is ongoing. */
while (HAL_I2C_GetState(&I2C2_Handle) != HAL_I2C_STATE_READY)
{
}
/* Check if the EEPROM is ready for a new operation */
while (HAL_I2C_IsDeviceReady(&I2C2_Handle, EEPROM_ADDRESS, 10, 300) == HAL_TIMEOUT);
/* Wait for the end of the transfer */
while (HAL_I2C_GetState(&I2C2_Handle) != HAL_I2C_STATE_READY)
{
}
}
/*
*********************************************************************************************************
* 函 数 名: BH1750_AdjustSensitivity
* 功能说明: 调节BH1750测量灵敏度
* 形 参: _ucMTReg : 量程倍率. 值域【31,254】,值越大 灵敏度越高
* 返 回 值: 无
*********************************************************************************************************
*/
void BH1750_AdjustSensitivity(uint8_t _ucMTReg)
{
if (_ucMTReg <= 31)
{
_ucMTReg = 31;
}
else if (_ucMTReg >= 254)
{
_ucMTReg = 254;
}
s_MTReg = _ucMTReg;
BH1750_WriteCmd(0x40 + (s_MTReg >> 5)); /* 更改高3bit */
BH1750_WriteCmd(0x60 + (s_MTReg & 0x1F)); /* 更改低5bit */
/* 更改量程范围后,需要重新发送命令设置测量模式 */
BH1750_ChageMode(s_Mode);
}
/*
*********************************************************************************************************
* 函 数 名: BH1750_ChageMode
* 功能说明: 修改BH1750测量模式,决定测量分辨率
* 形 参: __ucMode : 测量模式 值域(1,2,3)
* 返 回 值: 无
*********************************************************************************************************
*/
void BH1750_ChageMode(uint8_t _ucMode)
{
if (_ucMode == 1) /* 连续高分测量模式1 */
{
BH1750_WriteCmd(BHOP_CON_H_RES);
s_Mode = 1; /* 测量模式1,分辨率 1 lux*/
}
else if (_ucMode == 2) /* 连续高分测量模式2 */
{
BH1750_WriteCmd(BHOP_CON_H_RES2);
s_Mode = 2; /* 测量模式2, 分辨率 0.5 lux */
}
else if (_ucMode == 3) /* 连续低分测量模式 */
{
BH1750_WriteCmd(BHOP_CON_L_RES);
s_Mode = 3; /* 测量模式3,低分辨率 4 lux*/
}
}
/*
*********************************************************************************************************
* 函 数 名: BH1750_ReadData
* 功能说明: 读取BH1750测量结果. 主程序需要在 bsp_InitBH1750() 执行之后 180ms 才能读到正确数据。
* 连续测量模式下,之后主程序可以定时调用本函数读取光强度数据,间隔时间需要大于180ms
* 形 参: 无
* 返 回 值: 原始的测量数据 ,结果未转换
*********************************************************************************************************
*/
uint16_t BH1750_ReadData(void)
{
uint32_t Timeout = 1000;
uint8_t ucData[2] = {0};
uint16_t usLight;
HAL_I2C_Master_Receive(&I2C2_Handle,
BH1750_SLAVE_ADDRESS + 1,
ucData,
2,
Timeout);
usLight = (uint16_t)((ucData[0] << 8) + ucData[1]);
return usLight;
}
/*
*********************************************************************************************************
* 函 数 名: BH1750_GetLux
* 功能说明: 读取BH1750测量结果, 并转换为 Lux单位
* 形 参: 无
* 返 回 值: 光强度 [Lux] 浮点数
*********************************************************************************************************
*/
float BH1750_GetLux(void)
{
uint16_t usLight;
float lux;
usLight = BH1750_ReadData();
/* 计算光强度 = 16位寄存器值 / 1.2 * (69 / X) */
//lux = usLight * (((float)1 / 1.2) * ((float)69 / s_MTReg));
lux = (float)(usLight * 5 * 69) / (6 * s_MTReg);
if (s_Mode == 2) /* 高分辨率测量模式2 */
{
lux = lux / 2;
}
else
{
; /* 不必除2 */
}
return lux;
}
void main()
{
....
while (1)
{
lux = BH1750_GetLux();
My_Printf("BH1750 lux = %f\r\n", lux);
HAL_Delay(1000);
}
}
|
|