西门子模拟量为何偏偏是 27648?
从原理讲透这个“怪数字”
PLC · 模拟量处理 · 工程原理
每一个学西门子 PLC 的人,都绕不开一个数字:27648。
0~10V 对应 0~27648,4~20mA 对应 0~27648,±10V 对应 -27648~+27648。第一次见到它的人几乎都会问同一句话:
“为什么不凑个整?30000 不行吗?32767 不好吗?”
这个数字看起来随意,实际上是西门子几十年工程经验凝结出来的一个精巧设计。今天我们从寄存器底层往上,一层一层把它讲透。
01、先看容器:一个 16 位有符号整数
模拟量转换后的数值,在 S7 里存放在一个 16 位有符号整数(Int) 中,取值范围是:
-32768 ~ +32767
这是整个故事的舞台。注意两个事实:
1. 正方向最大是 32767,不是 32768;
2. 这个容器是带符号的——这一点是理解 27648 的第一把钥匙。
现在问题变成了:在这个 16 位容器里,额定满量程应该放在哪个位置?
最直觉的答案是放到头:0~10V 就用 0~32767。但西门子没有这么做,因为——
02 、留余量:过量程与欠量程的“缓冲带”
真实的工业现场,信号不会乖乖停在量程之内。
• 传感器有一定超限能力,0~10V 的板卡实际可能收到 10.5V 甚至 11V;
• 4~20mA 的仪表断线、短路时,电流会掉到量程之外;
• 温度变送器在超温时,输出可能轻微超过 20mA。
如果 10V 就顶到 32767,那么 10.01V 会发生什么?溢出。数值瞬间翻卷,程序里看到的是一个大负数,报警逻辑完全乱套,你还失去了“信号只是轻微超标”和“信号已经彻底异常”的区分能力。
于是西门子把额定满量程从 32767 往回撤,撤到 27648,硬生生留出了两段缓冲带:
| 数值区间 | 含义 | 对应 0~10V 板卡的实际电压 |
|---|---|---|
| 0 ~ 27648 | 额定量程(正常工作区) | 0 ~ 10.0V |
| 27649 ~ 32511 | 过量程(Overrange) | 约 10.0 ~ 11.76V |
| 32512 ~ 32767 | 溢出(Overflow) | 超出可表示范围 |
负方向对称:-27649 ~ -32511 是欠量程,-32512 ~ -32768 是溢出。
这样一来,程序拿到数值就能直接“读出”现场状态:
• 落在 0~27648:一切正常,正常换算;
• 落在 27649~32511:信号有,但超标了——报警“测量值超限”,但数值仍然可信、可用;
• 落到溢出区:信号不可信——立即打报警、锁存故障。
至于 4~20mA:4mA 对应 0,20mA 对应 27648。低于 0 的负值区间(最低可到约 1.185mA 对应 -4864)专门用来做断线检测——电流掉进这个“活零点以下”的区间,几乎可以断定回路断了。这就是 4~20mA“活零点”设计在数字侧的完整闭环。
一句话总结这一层:27648 = 给异常留出的呼吸空间。量程不是刻度的尽头,而是信任的边界。
03、为什么偏偏是 27648,而不是 27000、30000?
“留余量”解释了满量程应该小于 32767,但为什么是 27648 这个数?这里藏着最“复古”也最优雅的一层。
把 27648 转成十六进制:
27648 = 0x6C00
再看二进制:
27648 = 0110 1100 0000 0000
看出来了吗?低 10 位全是 0。也就是说:
27648 = 27 × 1024 = 27 × 2^10
在上世纪七十~九十年代,PLC 里跑的是没有浮点单元(FPU)的 8 位、16 位处理器,乘除法极其昂贵,而除以 2 的幂次,只需要一条移位指令(甚至免费——进位标志顺带就做了)。
满量程取 27×210,意味着“满量程 ÷ 1024”这种高频运算零成本。0x6C00 在十六进制世界里的地位,就和十进制世界里的“27000”一样——是一个 round number(整数)。西门子工程师选的不是 27648,选的是 0x6C00。
再补充一个巧合般的整洁关系:
27648 / 32768 = 27 / 32 = 0.84375
即额定量程恰好占满 15 位(含符号)空间的 84.375%,两侧各留出约 17.6% 的过量程余量——这个比例正好覆盖了当时绝大多数传感器、运放电路的实际超限能力(0~10V 板卡实测普遍能线性测到约 11.5V)。
顺带一提,32511 = 0x7EFF——过量程的终点在十六进制下同样是个“整数”。整个编码表,处处透着二进制美学。
至于“27”这个系数最原始的出处,要追溯到西门子更早期的 S5 系列乃至 TELEPERM 过程控制系统的编码传统,属于历史遗留的约定。但可以确定的是:留余量 + 移位友好 + 比例合理,这三点让 0x6C00 成了那个年代最合理的答案,并且一用就是半个世纪。
04、更深一层:与硬件分辨率“解耦”
还有一个常被忽略的设计意图。
模拟量板卡的分辨率一直在变:S5 时代是 12 位(0~4095),后来有 13 位、14 位、15 位,高精度模块到 16 位。如果 PLC 程序直接使用 ADC 原始码值,那么换一块板卡,全厂程序里的标定常数都得重算。
西门子的做法是:不管你 ADC 是多少位,模块固件统一把额定满量程归一化到 27648。
• 12 位板卡:1 LSB 原始码 ≈ 6.75 个机器数;
• 16 位板卡:额定量程被压缩映射到同一区间。
结果就是:你的程序永远面对同一个标尺。今天把 ET200SP 的 16 位模块换成 S7-300 的老 12 位模块,用户程序一行都不用改。这在“程序寿命往往超过硬件寿命”的工业界,价值巨大。
TIA Portal 里 NORM_X / SCALE_X 指令、模拟量通道的“硬件标定”,背后都是这套以 27648 为锚点的归一化体系。
05、落到实操:换算代码怎么写
标准换算公式(以 0~10V → 0~100.0% 为例):
工程值 = (模拟量原始值 / 27648.0) × 量程上限
SCL 写法:
// 0~10V → 0.0~100.0 %#rValue := DINT_TO_REAL(#diRaw) / 27648.0 * 100.0;
三个工程提醒:
1. 先判状态再换算。先检查原始值是否在 0~27648 之外,落入过量程/溢出区间就直接走报警分支,别让异常数据混进 PID。
2. 整数路径优先。若精度要求不高,用 raw * 1000 / 27648 的纯整数运算(注意中间结果用 DINT,防止 16 位乘法溢出),比浮点更快更稳。
3. 记住几个换算常数:10V ÷ 27648 ≈ 361.7 µV/码,20mA 量程下 ≈ 0.5787 µA/码,心里对“一个码值代表多少物理量”有数,调试时对异常数据会敏感得多。
06、结语:一个数字里的工程哲学
回头看,27648 至少回答了三个问题:
• 为什么不满量程用 32767?—— 给过量程、断线检测留缓冲带,正常、超标、故障,三态可分;
• 为什么是这么个怪数?—— 它是 0x6C00,27×210,低 10 位全零,对没有浮点单元的老 CPU 极度友好;
• 为什么几十年不变?—— 它把硬件分辨率和用户程序解耦,程序活得比模块久。
27648 不是自然界的常数,它是工程妥协的最优解:在 16 位带符号容器里,同时装下“正常测量、超限预警、故障检测”三种需求,还顺手让老处理器的除法变成了移位。
下次再在博途里看到 27648,希望你想起的不是一个“怪数字”,
而是一整套完整的信号处理哲学——
好的工程数字,从来都不是凑出来的整数,而是算出来的边界。
39
