基于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;}
四、测试结果与光照强度参考
测试结果
光照强度参考值
在智慧城市里建设智能电网的四大意义
智慧无线灌溉在园林中的应用
热像仪保养维修小技巧有哪些呢
放大器中的交叉失真波形及传递特性摘要
什么是双速电机
关于GY-30的简介与驱动及如何操作
芯片超人课堂关于高级驾驶辅助系统的四个部分
DES、AES、TEA加密算法的比较
LED电路的3种保护方法
打通AI芯片到大模型训练的算力桥梁,开放加速设计指南强力助推
比特币多头蠢蠢欲动,现在是看涨不追涨阶段
数字PFC整体控制框图
微软开放嵌入版.Net源码 免除相关授权费
安立公司 PIM Master™ 荣获 Frost & Sullivan 颁发创新奖
互联网+物联网移动医疗行业四大现状趋势分析
一位谷歌大牛程序员的自述
深入了解Excel中的SUMIF函数
智慧连接 •“筑”就未来|CLAN(科兰)通讯出席第24届CIBIS建筑智能化峰会北京站
Kepware助力物流仓储系统公司实现智能化管理
cpu是什么意思 CPU与PUA的区别