当前位置: 首页 > news >正文

STM32和BH1750光照传感器和IIC总线通讯OLED显示程序源码,通过BH1750,光照...

STM32和BH1750光照传感器和IIC总线通讯OLED显示程序源码,通过BH1750,光照传感器采集光照信息,通过oled显示光照值。 包括程序源码和原理图,程序源码注释详细需要的可以看下

刚玩STM32那会儿总想搞点有意思的传感器联动,最近用BH1750光照传感器配了个OLED屏,实测效果还不错。今天就带大家手搓这个光照监测小装置,从硬件连接到代码实现都会讲到,文末有完整工程自取。

先看硬件接线(原理图其实就几条线):BH1750和0.96寸OLED都是I2C设备,直接挂在同一组I2C总线上就行。STM32F103的PB6接SCL,PB7接SDA,记得给两个设备都加上上拉电阻(4.7K就行)。这里有个坑:BH1750的地址默认是0x23,如果遇到设备不响应记得用逻辑分析仪抓包确认。

上代码!先看I2C初始化的骚操作:

// 硬件I2C初始化 void I2C_Config(void) { GPIO_InitTypeDef GPIO_InitStructure; I2C_InitTypeDef I2C_InitStructure; RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE); // PB6-SCL, PB7-SDA 配置为开漏输出 GPIO_InitStructure.GPIO_Pin = GPIO_Pin_6 | GPIO_Pin_7; GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_OD; // 重点!复用开漏 GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; GPIO_Init(GPIOB, &GPIO_InitStructure); I2C_InitStructure.I2C_Mode = I2C_Mode_I2C; I2C_InitStructure.I2C_DutyCycle = I2C_DutyCycle_2; I2C_InitStructure.I2C_OwnAddress1 = 0xAA; // 随便填个不冲突的地址 I2C_InitStructure.I2C_Ack = I2C_Ack_Enable; I2C_InitStructure.I2C_AcknowledgedAddress = I2C_AcknowledgedAddress_7bit; I2C_InitStructure.I2C_ClockSpeed = 400000; // 400KHz够用了 I2C_Init(I2C1, &I2C_InitStructure); I2C_Cmd(I2C1, ENABLE); }

这段配置最容易被忽略的是GPIO模式——必须用开漏!之前用推挽输出结果I2C总线直接卡死,折腾了半天才发现是这里的问题。

STM32和BH1750光照传感器和IIC总线通讯OLED显示程序源码,通过BH1750,光照传感器采集光照信息,通过oled显示光照值。 包括程序源码和原理图,程序源码注释详细需要的可以看下

BH1750的驱动代码有个小技巧,上电后要发个唤醒指令:

void BH1750_PowerOn(void) { I2C_Start(); I2C_Send_Byte(0x23 << 1); // 器件地址+写操作 I2C_Wait_Ack(); I2C_Send_Byte(0x01); // POWER ON I2C_Wait_Ack(); I2C_Stop(); DelayMs(180); // 等待传感器稳定,实测不能少于180ms }

注意这里用的是0x23左移1位,因为I2C协议里地址位最后一位表示读写方向。连续模式下的数据读取更简单:

float BH1750_Read(void) { uint8_t buf[2]; I2C_Start(); I2C_Send_Byte((0x23 << 1) | 0x01); // 读模式 I2C_Wait_Ack(); buf[0] = I2C_Read_Byte(1); // 带ACK读取 buf[1] = I2C_Read_Byte(0); // 最后一个字节NACK I2C_Stop(); uint16_t val = (buf[0]<<8) | buf[1]; return val / 1.2; // 根据手册转换公式 }

这里有个精度问题:BH1750原始数据单位是lux/1.2,所以最终要除以1.2。实测在室内灯光下数值在200-500lux之间,阳光下能到上万。

OLED显示部分用到了u8g2库,重点在数值刷新策略:

void OLED_Refresh(float lux) { char str[16]; sprintf(str, "Lux: %.1f", lux); u8g2_ClearBuffer(&u8g2); u8g2_SetFont(&u8g2, u8g2_font_ncenB14_tr); u8g2_DrawStr(&u8g2, 5, 30, str); u8g2_SendBuffer(&u8g2); // 低功耗时可设置局部刷新 if(lux > 1000) u8g2_SetContrast(&u8g2, 255); // 强光下提高亮度 else u8g2_SetContrast(&u8g2, 120); }

为了省电加了自动亮度调节——当光照足够时降低OLED背光。注意sprintf浮点数会占用较多资源,在资源紧张的单片机上可以考虑用整型运算。

主循环里控制采样频率很重要:

while(1) { static uint32_t last = 0; if(HAL_GetTick() - last > 500) // 500ms采样一次 { float lux = BH1750_Read(); OLED_Refresh(lux); last = HAL_GetTick(); // 超过20000lux时闪屏警告 if(lux > 20000) OLED_Blink(3); } __WFI(); // 进入休眠省电 }

这里用到了WFI指令让CPU在空闲时休眠,实测整机电流从8mA降到了3mA左右。遇到强光照时的闪屏提示是个实用小功能,防止传感器过曝。

最后说几个踩过的坑:

  1. I2C上拉电阻不接或阻值太大会导致波形畸变
  2. BH1750的测量模式要选连续H分辨率模式(0x10)
  3. OLED的I2C地址可能因厂商不同有变化(常用0x3C或0x3D)
  4. 光照值突变时建议做滑动平均滤波

完整工程里包含了自适应I2C扫描、异常重连机制,实测在STM32F103C8T6上稳定运行。下次考虑加上光强阈值报警功能,用蜂鸣器做个智能光控装置应该挺有意思。

http://www.jsqmd.com/news/640716/

相关文章:

  • 10个Illustrator脚本:让设计效率提升300%的终极解决方案
  • 如何高效去除视频水印:基于LAMA模型的智能修复完整指南
  • 域名与DNS的那些坑——被劫持、被污染、续费涨价怎么办
  • 测试工程师的创业跃迁:从技术洞察到最小可行产品实战指南
  • 如何快速上手RVC:10分钟打造专属AI语音模型的终极指南
  • GitHub汉化插件终极指南:五分钟实现中文界面的完整教程
  • 风云T9L上市,仅12.99万元起,引领中型混动SUV进入“235”时代
  • AMD Ryzen调试工具终极指南:解锁处理器隐藏性能的简单方法
  • 4月14日成都地区正大产镀锌管(Q235B;内径DN15-200mm)现货报价 - 四川盛世钢联营销中心
  • 【2026AI工程化分水岭】:SITS2026主会场重磅发布——AIAgent持续学习的3阶段演进路线图与2027淘汰预警
  • Zotero引用插件终极指南:3步搞定Word文献自动化管理
  • Noto字体终极指南:如何免费获得900+语言支持的完整字体解决方案
  • 吉利i-HEV智擎混动技术发布,重新定义新一代油电混动
  • EldenRingSaveCopier:艾尔登法环存档备份与迁移的终极解决方案
  • PCB模块化设计13——LVDS高速差分信号布线中的阻抗控制与优化策略
  • 3分钟解锁Windows 12网页版:无需安装的云端操作系统完整体验
  • 免费开源的Altium电路图转换器:轻松查看SchDoc文件无需专业软件
  • 2026十大小程序开发公司发布,附国内小程序定制制作公司权威选型 - 新闻快传
  • 终极指南:使用CefFlashBrowser轻松重温经典Flash游戏和课件
  • CloudFlare内网穿透实战:从零搭建到稳定运行
  • 2026主治医师全国备考机构排名前十盘点,在职医生必看! - 医考机构品牌测评专家
  • 大模型推理全解析:小白也能看懂,收藏这篇轻松入门大模型!
  • 【红点系统进阶篇】TypeScript实现游戏红点树的动态条件触发机制
  • 题解:P16297 [蓝桥杯 2026 省 Python C 组] 调皮的橘猫
  • 银河麒麟V10 SP2计划任务避坑指南:at命令的7个实用技巧
  • 企业微信小程序接入腾讯TRTC多人会议,从类目审核到上线的完整避坑指南
  • 火山引擎:Seedance 2.0 API 服务全面开放
  • Hermes Agent爆火:是OpenClaw终结者,还是反OpenClaw情绪的烟花?
  • 如何做好家电数码产品的AI生成式引擎优化(GEO)?
  • CS实验室行业报告:数据类岗位就业分析报告