PIC16F 片内比较器实战:33k/10k 低压分压、3 组迟滞与窗口比较七步

电池供电的采集器用 ADC 轮询测电压,低电报警在阈值附近反复抖动,休眠电流也被 ADC 拉高。结论先给:这类"只要一个是否"的判断不该交给 ADC,片内比较器加一组分压电阻就能做掉,关键是分压比、迟滞和中断三件事要一起算。

2026-10-31
PIC16F片内比较器低压检测迟滞窗口比较低功耗

一台电池供电的无线采集器,低电量提示总是在 3% 上下反复跳,现场人员以为电池接触不良;同时休眠电流比预算高出十几微安,查到最后是 ADC 一直挂在轮询里。结论先给:像"电池够不够、门磁开没开、过零到没到"这种只要一个二值结果的判断,本来就不该用 ADC 采样再比较——片内比较器配合一组分压电阻,既没有采样保持的等待时间,也能直接产生中断,把 CPU 从轮询里解放出来。

本文按 Microchip《Comparator Tips 'n Tricks》(DS41215B)整理,所有电阻取值与计算实例均来自该文档。

一、低压检测:分压比决定了什么时候报警

比较器只回答"哪一端电压高",所以低压检测的本质是把电池电压和一路固定基准同时送进两个输入端,让它们在设定的电池电压处相等。文档给了两种拓扑,区别在于单片机自己由稳压电源还是非稳压电源供电。

拓扑基准怎么来文档实例适用场景
稳压供电R1、R2 把 VDD 分到约 25% 作同相端;R3、R4 把电池电压分压到反相端VDD=5 V,R1=33k、R2=10k、R3=39k、R4=10k,电池降到 5.7 V 时翻转单片机有 LDO,VDD 稳定
非稳压供电用二极管 D1 的正向电压作基准,R1、R2 分压后与它比较R1=33k、R2=10k、R3=470 Ω,电池降到 3 V 时翻转电池直接供电,VDD 随电量变化

第一种拓扑的要点是:R1、R2 决定同相端电压,R3、R4 决定反相端电压,取值的原则是让反相端在"系统最低工作电压"那一刻正好等于同相端。第二种拓扑更省,但 R3 必须在最低电池电压下仍能把 D1 偏置在正向导通区,否则基准就消失了,比较器会误判。

二、迟滞:三个电阻把抖动挡在阈值之外

输入电压刚好停在阈值附近时,外部噪声和单片机内部的开关噪声会让输出来回翻转,也就是"颤振"。解决办法是从输出引一路反馈到同相端,形成正反馈:输入低于阈值时把门限抬高,高于阈值时把门限压低,这样输入必须"越过"一段回差才能改变输出。

设计顺序是反过来的:先定要挡住的噪声幅度,也就是上门限 VTH 与下门限 VTL,再倒推电阻。文档给出的关系是:平均门限 VAVG = VDD×VTL /(VDD − VTH + VTL),同时 VAVG = VDD×R2 /(R1 + R2);等效电阻 REQ = R1×R2 /(R1 + R2);回差比例 DR =(VTH − VTL)/ VDD;最后 R3 = REQ×[(1/DR)− 1]。

步骤公式或取值文档实例(VDD=5 V,VTH=3.0 V,VTL=2.5 V)
平均门限VAVG = VDD×VTL /(VDD − VTH + VTL)2.77 V
分压电阻VAVG = VDD×R2 /(R1 + R2)R1=8.2k、R2=10k,实际 VAVG=2.75 V
等效电阻REQ = R1×R2 /(R1 + R2)4.5 kΩ
回差比例DR =(VTH − VTL)/ VDD0.1
反馈电阻R3 = REQ×[(1/DR)− 1]计算值 40.5 kΩ,取 39 kΩ;实测 VTH=2.98 V、VTL=2.46 V

两条工程约束不能忽略。第一,R1 与 R2 上会一直有电流流过,总阻值至少取 1 kΩ 以限制功耗,但也不要超过 10 kΩ,否则 R3 会被迫取得很大。第二,R3 如果在 100 kΩ 到 10 MΩ 量级,比较器输入偏置电流会在同相端产生明显失调,回差就偏离计算值了。所以"电阻越大越省电"在这里不成立,省电要靠降低比较器本身的功耗和缩短上电时间。

三、窗口比较:一个信号,两个边界

传感器输出既不能太高也不能太低时,用两个比较器加三个电阻就能组成窗口比较器:R1、R2、R3 串联分压,分别取出上限和下限,两个输出都是高有效——输入高于上限时"上限"输出变高,低于下限时"下限"输出变高,区间内的正常波动被忽略。

参数公式实例(VDD=5 V,目标 2.5 V / 2.0 V)
上限VTH-HI = VDD×(R3 + R2)/(R1 + R2 + R3)R1=12k、R2=2.7k、R3=10k,实测 2.57 V
下限VTH-LO = VDD×R3 /(R1 + R2 + R3)实测 2.02 V
总阻值至少 1 kΩ 限制功耗,小于 1 MΩ 避免偏置电流引起失调24.7 kΩ,落在范围内

需要回差时,上限比较器可以直接套用上一节的迟滞算法,把 R2 与 R3 的串联值当作"R2"代入;下限比较器则先在同相端串一个 1 kΩ~10 kΩ 的等效电阻,再按同样两个公式算反馈电阻。这样两个边界各自有回差,窗口不会在两端同时抖动。

四、用中断代替轮询:2 条指令对 5 条指令

比较器输出既有电平也有中断标志,检测"状态有没有变化"有两种写法。传统做法是把上次的输出存到 RAM,每个周期读回来和当前值异或再判断;另一种是直接查比较器中断标志 CMIF,有变化才处理。文档给出的量化对比很直观:前者每次检测 5 条指令、发生变化时 9 条、占 1 个 RAM 单元;后者每次 2 条、变化时 3 条、不占 RAM。

方法每次检测发生变化时占用 RAM限制
保存旧值后异或比较5 条指令9 条指令1 字节通用,但要自己维护旧值
查 CMIF 中断标志2 条指令3 条指令不占两个比较器共用一个标志时失效
借 CINV 极性位翻转2 条指令5 条指令不占 GPR只适合单比较器且能改极性
; 方案 A:查 CMIF 标志,每次 2 条指令
Test
        BTFSS   PIR1, CMIF          ; 比较器中断标志置位?
        RETLW   0                   ; 未变化,返回 0
        BTFSS   CMCON, COUT         ; 变化方向:COUT 为 0 还是 1
        RETLW   CHNGBIT             ; 输出变低
        RETLW   COUTMASK + CHNGBIT  ; 输出变高,两个标志一起返回

; 方案 B:两个比较器共用一个中断标志时,用 CINV 强制翻转一次
        BTFSS   CMCON, COUT          ; 当前为 0 直接返回
        RETLW   0
        MOVLW   CINVBIT
        XORWF   CMCON, F             ; 翻转输出极性,使 COUT 归 0
        BTFSS   CMCON, CINV          ; 检查极性位判断刚才的方向
        RETLW   CHNGBIT
        RETLW   COUTMASK + CHNGBIT

方案 B 的思路有点绕:先看 COUT,若为 0 说明没变化;若为 1,就翻转 CINV 把 COUT 强制拉回 0,再用翻转后的 CINV 位反推出"刚才是由低变高还是由高变低"。代价是每次变化多两条指令,但不需要额外的 RAM,适合引脚和 RAM 都很紧的小型号。

五、短脉冲与数据切片:比较器的两个常见副业

脉宽测量可以不用捕获单元:把比较器输出接到 Timer1 的门控输入 T1G,输入为低时 Timer1 计数、为高时停止,计数值就对应低电平宽度;把 CMCON 的 CINV 置位反相比较器输出,同一套硬件就能测另一半。这里有个必须遵守的细节——比较器输出和 Timer1 时钟是异步的,只能用支持输出同步到 Timer1 时钟的比较器并置位 C2SYNC,否则就要外接一个下降沿触发的 D 触发器做同步,用上升沿会引入竞争。

无线或长线传输的数据常有直流偏置漂移,幅度可能超过信号本身的峰峰值,这时固定门限比较必然误码,要用数据切片器:R1、C1 组成低通滤波,取出输入信号的平均直流作为参考,再和原始信号比较。文档给的例子是 10 kbit/s 数据、转折频率 500 Hz,取 R1=10 kΩ、C1=33 μF;R2、R3 是可选的轻微偏置,让无数据时输出有确定状态,取值至少是 R1 的 50~100 倍,也就是 500 kΩ~1 MΩ,而且两者只用一个。

六、七步落地

  1. 先判断需求是不是"只要一个是否":是,就用比较器;需要看具体数值再考虑 ADC。
  2. 按供电方式选拓扑:有 LDO 用 VDD 分压做基准,电池直供用二极管正向电压做基准。
  3. 按最低工作电压反推分压比,确保翻转点落在电池真正需要报警的位置。
  4. 先定 VTH、VTL 再算电阻,R1+R2 控制在 1 kΩ~10 kΩ,R3 不要进 100 kΩ 以上区间。
  5. 需要监控区间就用两个比较器加三个电阻,总阻值控制在 1 kΩ~1 MΩ。
  6. 检测变化优先用 CMIF 中断标志,共用标志时退回 CINV 极性翻转法。
  7. 休眠前确认比较器与分压网络的静态电流,别让"省掉 ADC"换来一条常通的电阻支路。

七、排查对照:现象、根因与改法

现象常见根因改法
低电提示在阈值附近反复跳没有回差,噪声让输出颤振加 R3 正反馈,按 VTH/VTL 反算
实际翻转点比设计值偏低R3 取值过大,输入偏置电流造成失调R3 控制在几十 kΩ 量级,R1+R2 不超过 10 kΩ
电池直供方案完全不报警D1 在低压时未导通,基准消失减小 R3,保证最低电池电压下仍有正向电流
窗口比较两端同时抖动只给上限加了回差下限串 1 kΩ~10 kΩ 后单独算反馈电阻
脉宽测量偶尔差一个计数比较器输出未同步到 Timer1 时钟置位 C2SYNC,或外接下降沿触发的 D 触发器
休眠电流比预期高分压电阻常通,或比较器未关加大总阻值上限内取值,休眠时切断分压支路

一句话总结:片内比较器不是"廉价的 ADC",而是一个带中断的模拟阈值开关。把分压比算准、把回差算够、把变化检测交给 CMIF,低电报警和过零检测这类需求就能用三个电阻加几行汇编解决,CPU 和功耗都省下来了。

还想接着看:PIC16C74A 的体选、PCLATH 与中断现场保护、ATmega168 的 BOD 电平与熔丝位配置、DS2480B 单总线串口桥接网关。

本文基于 Microchip《Comparator Tips 'n Tricks》(DS41215B)技术资料整理优化。

需要定制开发?

沧州艾诺威电子 — 国家高新技术企业,20+项国家专利
嵌入式系统开发 · 物联网方案 · AI智能硬件 · 一站式交付

立即微信咨询

电话:13930711029 | 邮箱:tech@czinv.com | 24小时内响应