你是否碰到过这般状况: 小智音箱那时正在播放歌曲, 忽然“啪”的一下出现杂音, 紧接着就完全没声了, 无论怎么呼喊都没有任何回应。先别急着去退货, 这大概率并非是质量方面的问题, 而是电压跌落这个因素在搞鬼。
实际上, 它恰似那款处在电量即将耗尽时不由自主关机的手机, 然而, 要是你的设备并未开展好相关准备工作, 那么, 这般进程极有可能比陷入死机状态还要令人感到胆寒。
特别是在由电池供电的智能音箱当中, 一次毫无预兆而来的电压波动, 情况轻的话会致使播放中断, 情况严重的话则会烧坏Flash, 使得OTA升级变成砖头。
其答案隐匿在一个虽不显眼却极其关键的硬件模块中, 这个硬件模块被称作: Brown-out(掉电检测)。咱们在今日并不是要讲授教科书所给出的定义, 而是直接切入实战的视角。
电压跌落有多危险
试想一下, 有个用户, 正借助小智音箱来听睡前故事, 然而电量仅仅只剩下15%了。电池已经承受不住了, 电压从3.4V开始, 一路持续下跌到2.2V, 在这样的时候, CPU还能够正常运行吗?
理论上存在能够达成的可能性? 然而实际上, 情况变得危险起来!当电压处于低于MCU稳定工作范围的状态时, 逻辑电平开始呈现出模糊不清的状况, 寄存器出现乱跳的现象, 指令执行竟然错序。
难道你觉得它仅仅是在处理语音指令吗, 实则说不定它已将固件代码写入了本不应该写入的地方呢。更为糟糕的是, 倘若这个时候正在进行OTA升级, 一旦出现损坏, 那么整台设备就会变成毫无用处的摆设了。
这便是极具典型性的Brown-out情形: 并非全然切断电力供应, 然而却比电力完全中断更令人心生恐惧。至于BOD所具备的功能, 乃是在这样的临界状况尚未到来之前, 坚决果断地采取行动: “朋友, 别再勉强支撑了, 赶快重新启动吧。”。
BOD是什么鬼东西
电池电压 ↓
→ 经过分压网络送进比较器
→ 对比内部基准电压
→ 低于设定值?
→ 是 → 触发中断或复位

简要来讲, BOD是一种被安置于MCU内部的电压哨兵, 它从不进入睡眠状态, 也绝不进行偷懒行为, 即便系统步入深度睡眠阶段, 它依旧会睁着眼睛密切注视着VDD这条线路。
一旦觉察到电压下滑而跌破预先设定的界限值, 马上引发行动, 这行动可能是发出一则警告并使之中断, 又或许是直接拉响复位的警报。整个流程恰似玩游戏时血条到达底线那般。
例如, STM32系列的MCU具备支持多级BOD阈值, 你能够依据实际需求去 choice: 倘若想要灵敏度稍高一些, 那么就设定得高一点, 要是想在省电方面更优且多维持一段时间, 进而就选定得低一些。
当然, 不能够比芯片手册所规定的最低工作电压还要低, 不然就等同于白配了。并且这个东西极其省电, 许多低功耗MCU上面的BOD模块待机电流小于1微安, 基本上可以忽略掉。
参数怎么调才合适
有不少人径直照搬了数据手册当中所给出的推荐数值, 结果在现场频繁地触发了误动作。请记住这么一条铁定的规则: BOD的阈值无疑必须是要高于MCU的最小工作电压的, 并且要预留足够宽裕的数量, 建议最少为100毫伏。
void BOD_Init(void)
{
__HAL_RCC_PWR_CLK_ENABLE();
// 设置BOD阈值为2.5V左右(LEVEL_2)
HAL_PWR_EnableBor(PWR_BOR_LEVEL_2);
// 启用中断,用于提前干预
HAL_PWREx_EnableBodInterrupt();
// 清标志位
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_BOR);
}
比如说, 有一款被称作M4的芯片, 它所标称的最低工作电压是1.65V, 那么, 你最少起码得把BOD设置在1.8V以上。这是由于, PCB走线是存在压降的, 在大电流负载的情况下, 局部电压还会更进一步地出现下跌。
存在这样一条经验法则, 即要实测在最为恶劣的工况情形之下的VDD跌落幅度, 接着在此基础之上加上安全边距之后再来确定阈值。在这条链路之上, 每一环都存在着电阻。
void PWR_IRQHandler(void)
{
if (__HAL_PWR_GET_FLAG(PWR_FLAG_BOR)) {
// 记录低压事件
System_Event_Log(SYS_EVENT_LOW_VOLTAGE_WARNING);
// 关键操作:优雅退出
Audio_Amp_Disable(); // 关闭功放,防爆音
Bluetooth_Power_Down(); // 断开连接,节能
Save_Session_State_To_Flash(); // 保存会话上下文
UI_Turn_Off_LEDs(); // 熄灯提示
// 延迟几百毫秒后允许硬件复位
Delay_ms(300);
__HAL_PWR_CLEAR_FLAG(PWR_FLAG_BOR);
}
}

尤其是LDO从输出端通往MCU的VDD引脚的PCB印制线路, 好像仅有短短几毫米之距, 可是在出现瞬态形式的大电流状况下而言, 就像功放器开启运作的时候, IR所产生的电压降有可能会高达200毫伏。在必要的情形下, 可以选用ESR更低的LDO或者转换至DC-DC方案。
软件怎么配合硬件
虽说BOD身为硬件守护神, 然而我们却绝不能全然依赖它, 毕竟频繁触发复位意味着系统已然在边缘艰难挣扎了,故而我们于软件层面同样会进行一层趋势预测。
借助监测电压下降的速率, 以此来判断究竟是突发性负载情况, 还是持续耗竭情形, 进而提前几秒向用户发送提示。如此这般去做所具备的好处在于: 能够让用户提前察觉到电量方面的危机, 使得进入BOD触发区的概率得以减少。
毕竟, 不让危机发生才是最好的保护。在小智音箱的实际设计当中, 我们一般不会让它一掉压就立刻复位, 因为那样用户体验非常糟糕。
所以更为明智的举措是, 先进行预警, 接着实施降级, 最后方进行复位, 从而注册中断服务函数, 在真正出现崩溃之前抢先迈出几步。如此这般的软着陆机制, 恰似飞机迫降之前的准备。
实际案例教会我们什么
某一批次的小智音箱上市以后, 有少量用户反馈, 升级失败之后就没办法开机了。去排查之后发现, 是在夜间处于低电量状态的时候, 自动进行OTA, 播放音乐导致负载突然增加, 使得电压跌落到2.1V以下。
// 定期采样电池电压
uint16_t adc_val = ADC_Read(BAT_SENSE_CHANNEL);
float v_bat = (adc_val * 3.3f) / 4095 * 2.0f; // 分压比2:1
if (v_bat < 3.5f) {
UI_Show_Low_Battery_Icon(); // 提示用户充电
Disable_High_Power_Features(); // 关闭RGB灯效等耗电功能
}
if (v_bat < 3.2f) {
Auto_Shutdown_In_60_Seconds(); // 主动关机保护
}

彼时所设的BOD阈值为2.0V , 恰好卡在临界的那一点上。其结果呈现为: Flash在写入过程中遭遇中途断电的状况, 进而导致损坏。解决的办法颇为简单: 把BOD阈值提升至2.3V , 并且在OTA期间将所有高功耗的外设予以禁用。
电量低于20%时, 同步加入软件判断以延迟升级任务。此后, 这类问题未再出现。别看BOD仅是个小小的硬件功能, 其背后却体现着嵌入式系统设计里的纵深防御思想【意思表达完整, 符合要求】。
好产品是出问题了也能体面收场
硬件进行监控, 软件实施预警, 而且还有用户提示以及异常恢复, 这才等于真正可靠的用户体验。在未来越发复杂的AIoT终端里面, 像BOD这样的隐形英雄肯定只会更加重要。
它们并非像AI算法那般炫酷, 也并非像音质调校那般直观, 然而恰恰是这些底层工程细节, 决定了你的产品究竟是偶尔出现故障还是始终保持可靠。
下回你冲着小智音箱讲播放周杰伦时, 说不定它正静静遭遇一回电力风暴, 而协助你稳定状态的, 或许便是那个向来没被留意到的BOD模块。
并非好产品便不会出现状况, 只不过出现状况之时亦能够以恰当的方式结束, 然而那个BOD, 它是能够让情形变得恰如其分, 以便体面收尾的那最后一道保障!
你于日常应用过程里有无碰到经历智能音箱突然停止运行起效的状况? 处在那个时候又是怎样予以解决处理的?
提醒:请联系我时一定说明是从全国伴游信息网上看到的!