第二章:系统架构设计——整体软件架构分层与模块划分

好,咱们进入第二章。这一章很关键,说白了就是给整个智能电表软件平台搭骨架。骨架搭不好,后面写再多代码也是白搭。我个人习惯是先想清楚分层,再谈模块,最后选通信协议。咱们一步步来。

2.1 整体软件架构分层

智能电表这东西,资源有限——RAM可能就几十KB,Flash也就几百KB。你不能像写服务器程序那样随便堆框架。所以分层要清晰,但层与层之间不能太厚。

我一般分三层:应用层中间件层驱动层。你想想看,这其实跟操作系统里的分层思想一脉相承。

分层 职责 典型内容
应用层 业务逻辑、用户交互 费率管理、数据上报、LCD显示、按键处理
中间件层 协议封装、数据管理、任务调度 DL/T645协议栈、FreeRTOS、文件系统、加密库
驱动层 硬件抽象、寄存器操作 GPIO、SPI、UART、ADC、计量芯片驱动

嗯,这里要注意:驱动层绝对不能直接暴露给应用层。我在项目中遇到过有人图省事,直接在应用层里写寄存器操作,结果换了个MCU型号,代码几乎重写。这就是分层没做好的代价。

2.2 模块划分——每个模块只干一件事

模块划分的原则很简单:高内聚、低耦合。说白了,每个模块只关心自己的事,别管别人怎么用。

我习惯把智能电表拆成以下几个核心模块:

  • 计量模块:负责读取电能脉冲、计算有功/无功功率、累计电量。这块通常依赖专用计量芯片(比如RN8302、ADE7878),驱动层封装好读写接口,中间件层做数据校准和滤波。
  • 费率管理模块:处理尖峰平谷时段切换、阶梯电价计算。这个模块纯逻辑,跟硬件无关,放在应用层最合适。
  • 存储管理模块:管理EEPROM或Flash中的数据存储,包括参数配置、冻结数据、事件记录。我建议用中间件层封装一个“键值对存储”接口,上层只管读写,不用管具体存哪。
  • 通信模块:负责RS485、红外、Wi-Fi或NB-IoT的数据收发。这个模块要同时处理物理层和协议层,所以横跨驱动层和中间件层。
  • 显示与按键模块:驱动LCD段码屏或OLED,处理按键轮询。纯驱动层+应用层回调。
  • 任务调度模块:基于FreeRTOS或裸机状态机,管理各任务的执行周期。比如计量任务每100ms执行一次,通信任务每500ms轮询一次。

避坑指南:我曾经在一个项目里把计量和通信写在同一个模块里,结果通信阻塞时计量数据丢了,导致电量累计出错。后来我强制要求:计量模块必须独立运行,优先级最高,不能被其他模块阻塞

2.3 通信协议栈选型

智能电表的通信协议,国内基本绕不开DL/T645。这是国标,强制要求。但光有DL/T645还不够,你还要考虑物理层和上层应用协议。

我列一下常见的选型组合:

场景 物理层 数据链路层 应用层
本地抄表 RS485 DL/T645-2007 DL/T645命令集
远程无线 NB-IoT / 4G TCP/UDP + CoAP DL/T645 over CoAP
红外通信 红外光电头 DL/T645(波特率1200) DL/T645命令集
Wi-Fi(智能家居) Wi-Fi MQTT 自定义JSON + DL/T645映射

为什么会这样选?因为DL/T645在RS485上效率很高,但到了TCP/IP网络里,直接裸传DL/T645帧会出问题——没有会话管理、没有重传机制。所以我在NB-IoT方案里,会在DL/T645外面再包一层CoAP,既保留了原有协议语义,又解决了可靠传输问题。

个人经验:如果你做的是出口电表,那DL/T645就不适用了。国外常用IEC 62056(DLMS/COSEM)或Modbus。我建议你在中间件层做一个协议适配器,把计量数据抽象成统一接口,换协议时只改适配器,不动上层业务逻辑。

2.4 架构图(文字描述)

这里我不画图,但你可以想象一个三层结构:

+-------------------------------------------+
|              应用层                          |
|  费率管理  数据上报  事件记录  LCD显示      |
+-------------------------------------------+
|              中间件层                        |
|  DL/T645协议栈  FreeRTOS  文件系统  加密库  |
|  键值对存储  任务调度  协议适配器           |
+-------------------------------------------+
|              驱动层                          |
|  GPIO  SPI  UART  ADC  计量芯片驱动  LCD驱动|
+-------------------------------------------+
|              硬件层                          |
|  MCU  计量芯片  EEPROM  LCD  RS485  NB-IoT  |
+-------------------------------------------+

嗯,这个结构我用了好几年,从8位MCU到ARM Cortex-M4都跑过。核心思想就是:驱动层只管硬件,中间件层只管数据,应用层只管业务。谁也别越界。

2.5 本章小结

这一章我们聊了三件事:

  • 软件分三层:应用层、中间件层、驱动层,层间接口要稳定
  • 模块划分要独立,计量模块优先级最高
  • 通信协议选型要因地制宜,DL/T645是主流,但别忘了协议适配

下一章我会带你手写驱动层代码,从GPIO和UART开始。到时候咱们再细聊寄存器操作的那些坑。

警告:不要试图在架构阶段把所有细节都定死。留一些扩展点,比如协议适配器接口、存储模块的抽象层。否则后期需求一变,你会想砸键盘的——我砸过,真的。