电子说
基于HAL库的BH1750驱动代码,通讯方式为模拟IIC,非常适合在使用hal库的stm开发版上移植
一、GY-30简介
GY-30是一款内置ROHM-BH1750FLV芯片的数字光照强度模块。芯片内置16bitAD转换器,可直接数字输出,测量光照强度范围为0-65535lx(精度可选)。除此之外,模块内置电平转换,支持3-5V供电,可与5V单片机IO直接连接;对外提供IIC接口,方便使用。
1.1GY-30原理图
1.2模块引脚
ps:ADDR默认接地,此时IIC地址为0x46
二、GY-30驱动
2.1GPIO配置
由于本人使用的是hal库,使能时钟
__HAL_RCC_GPIOB_CLK_ENABLE();
GPIO配置
/*Configure GPIO pin Output Level */ HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0|GPIO_PIN_1, GPIO_PIN_RESET);
/*Configure GPIO pins : PB0 PB1 */ GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
PB0 -- 模拟SDA
PB1 -- 模拟SCL
2.2初始化BH1750
IIC起始(SCL高电平时,SDA下降沿)
/***开始信号***/void BH1750_Start(){ HAL_GPIO_WritePin(GPIOB, sda,GPIO_PIN_SET); //拉高数据线 HAL_GPIO_WritePin(GPIOB, scl,GPIO_PIN_SET); //拉高时钟线 delay_us(5); //延时 HAL_GPIO_WritePin(GPIOB, sda,GPIO_PIN_RESET); //产生下降沿 delay_us(5); //延时 HAL_GPIO_WritePin(GPIOB, scl,GPIO_PIN_RESET); //拉低时钟线}
发送设备地址,寄存器地址
IIC结束(SCL高电平,SDA上升沿)
/*****停止信号******/void BH1750_Stop(){ HAL_GPIO_WritePin(GPIOB, sda,GPIO_PIN_RESET); //拉低数据线 HAL_GPIO_WritePin(GPIOB, scl,GPIO_PIN_SET); //拉高时钟线 delay_us(5); //延时 HAL_GPIO_WritePin(GPIOB, sda,GPIO_PIN_SET); //产生上升沿 delay_us(5); //延时}
2.3设置精度
设置精度只需向BH1750发送指令,本人采用的是H- Resolution mode(0x10)
如需设置其他精度亲参考下表
2.4读取光强数据
读取BH1750内部数据
//连续读出BH1750内部数据void mread(void){ uchar i; BH1750_Start(); //起始信号 BH1750_SendByte(SlaveAddress+1); //发送设备地址+读信号
for (i=0; i《3; i++) //连续读取6个地址数据,存储中BUF { BUF[i] = BH1750_RecvByte(); //BUF[0]存储0x32地址中的数据 if (i == 3) { BH1750_SendACK(1); //最后一个数据需要回NOACK } else { BH1750_SendACK(0); //回应ACK } }
BH1750_Stop(); //停止信号 Delay_mms(5);}
合成数据
dis_data=BUF[0];dis_data=(dis_data《《8)+BUF[1]; //合成数据
Value_GY_30=(float)dis_data/1.2;
三、元操作
3.1延时
//系统主频72MHZvoid delay_us(uint16_t us){ while(us--) { __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop();__nop(); __nop();__nop(); }}
void Delay_mms(uint16_t tmp){ uint16_t i=0; while(tmp--) { i=12000; while(i--); }}
3.2IIC开始/结束信号
时序图如下代码见2.2初始化BH1750
3.4发送应答信号
/**************************************发送应答信号入口参数:ack (0:ACK 1:NAK)**************************************/void BH1750_SendACK(int ack){ GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1; GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
if(ack == 1) //写应答信号 HAL_GPIO_WritePin(GPIOB, sda,GPIO_PIN_SET); else if(ack == 0) HAL_GPIO_WritePin(GPIOB, sda,GPIO_PIN_RESET); else return;
HAL_GPIO_WritePin(GPIOB, scl,GPIO_PIN_SET); //拉高时钟线 delay_us(5); //延时 HAL_GPIO_WritePin(GPIOB, scl,GPIO_PIN_RESET); //拉低时钟线 delay_us(5); //延时}
3.5接收应答信号
/**************************************接收应答信号**************************************/int BH1750_RecvACK(){ GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; /*这里一定要设成输入上拉,否则不能读出数据*/ GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; GPIO_InitStruct.Pin = sda; HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
HAL_GPIO_WritePin(GPIOB, scl,GPIO_PIN_SET); //拉高时钟线 delay_us(5); //延时
if(HAL_GPIO_ReadPin( GPIOB, sda ) == 1 )//读应答信号 mcy = 1 ; else mcy = 0 ;
HAL_GPIO_WritePin(GPIOB, scl,GPIO_PIN_RESET); //拉低时钟线 delay_us(5); //延时
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; HAL_GPIO_Init( GPIOB, &GPIO_InitStruct );
return mcy;}
3.6 IIC发送一个字节
/**************************************向IIC总线发送一个字节数据**************************************/void BH1750_SendByte(uchar dat){ uchar i;
for (i=0; i《8; i++) //8位计数器 { if( 0X80 & dat ) HAL_GPIO_WritePin(GPIOB, sda,GPIO_PIN_SET); else HAL_GPIO_WritePin(GPIOB, sda,GPIO_PIN_RESET);
dat 《《= 1; HAL_GPIO_WritePin(GPIOB, scl,GPIO_PIN_SET); //拉高时钟线 delay_us(5); //延时 HAL_GPIO_WritePin(GPIOB, scl,GPIO_PIN_RESET); //拉低时钟线 delay_us(5); //延时 } BH1750_RecvACK();}
3.7 IIC读取一个字节
/**************************************从IIC总线读取一个字节数据**************************************/uchar BH1750_RecvByte(){ uchar i; uchar dat = 0; uchar bit;
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT; /*这里一定要设成输入上拉,否则不能读出数据*/ GPIO_InitStruct.Pin = sda; GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW; HAL_GPIO_Init( GPIOB, &GPIO_InitStruct );
HAL_GPIO_WritePin(GPIOB, sda,GPIO_PIN_SET); //使能内部上拉,准备读取数据, for (i=0; i《8; i++) //8位计数器 { dat 《《= 1; HAL_GPIO_WritePin(GPIOB, scl,GPIO_PIN_SET); //拉高时钟线 delay_us(5); //延时
if( SET == HAL_GPIO_ReadPin( GPIOB, sda ) ) bit = 0X01; else bit = 0x00;
dat |= bit; //读数据
HAL_GPIO_WritePin(GPIOB, scl,GPIO_PIN_RESET); //拉低时钟线 delay_us(5); //延时 }
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP; HAL_GPIO_Init( GPIOB, &GPIO_InitStruct ); return dat;}
四、测试结果与光照强度参考
测试结果
光照强度参考值
编辑:lyn
全部0条评论
快来发表一下你的评论吧 !