DL/T 645-2007 多功能电能表通信协议驱动开发方案
1. 概述
1.1 协议简介
DL/T 645-2007 是多功能电能表通信协议标准,规定了电能表和上位机(如数据采集系统)之间的通信协议,包括数据格式、通信过程、错误检测等内容。该协议主要用于电力系统中的电能表数据采集,支持单相和三相电能表。
DL/T 645-2007 支持多种通信方式:
- 有线通信: RS-485、RS-232
- 无线通信: GSM/GPRS、LoRa
- 以太网通信: TCP/IP
1.2 功能定位
| 功能类别 |
功能描述 |
支持范围 |
| 数据采集 |
电能量采集(有功/无功电能) |
当前/历史结算日数据 |
| 数据采集 |
需量采集(最大需量) |
当前/历史最大需量及发生时间 |
| 数据采集 |
变量采集(电压、电流、功率等) |
三相电压、电流、功率、功率因数 |
| 数据采集 |
谐波数据采集 |
电压/电流谐波含量 |
| 数据采集 |
状态信息采集 |
电表运行状态字 |
| 数据采集 |
冻结数据采集 |
定时冻结、瞬时冻结数据 |
| 地址广播 |
读取电表通信地址 |
支持广播地址识别 |
1.3 设计原则
- 一致性: 遵循项目统一的驱动接口规范,与 S7、EtherNet/IP 等驱动保持一致的设计风格
- 可扩展性: 模块化设计,便于后续功能扩展
- 可靠性: 完善的错误处理和重连机制
- 可测试性: 支持依赖注入,便于单元测试
- 多设备支持: 支持单串口多设备连接
2. 技术架构
2.1 整体架构
┌─────────────────────────────────────────────────────────────────┐
│ EdgeX Gateway │
├─────────────────────────────────────────────────────────────────┤
│ Device Service Layer │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ DriverMgr │ │ Schedule │ │ ConfigMgr │ │
│ └──────┬──────┘ └─────────────┘ └─────────────┘ │
│ │ │
├──────────┼──────────────────────────────────────────────────────┤
│ Protocol Driver Layer │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ DLT645Driver │ │
│ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌────────┐ │ │
│ │ │ transport│◄─│ scheduler│◄─│ decoder │ │ config │ │ │
│ │ │ (串口/TCP) │ │ (读写调度)│ │ (编解码) │ │ │ │ │
│ │ └────┬─────┘ └──────────┘ └──────────┘ └────────┘ │ │
│ │ │ │ │
│ └───────┼─────────────────────────────────────────────────┘ │
├───────────┼──────────────────────────────────────────────────────┤
│ Network Layer │
│ RS-485 / TCP/IP │
└───────────┴──────────────────────────────────────────────────────┘
2.2 模块划分
| 模块 |
文件 |
职责 |
对应参考 |
| 驱动主模块 |
dlt645.go |
实现 Driver 接口,协调整体流程 |
s7.go, ethernetip.go |
| 传输层 |
transport.go |
串口/TCP连接管理、帧收发、超时处理 |
transport.go |
| 调度器 |
scheduler.go |
批量点位读写调度、多设备轮询 |
scheduler.go |
| 解码器 |
decoder.go |
地址解析、数据编解码、协议帧处理 |
decoder.go |
2.3 核心类/结构体设计
2.3.1 DLT645Driver(驱动主类)
type DLT645Driver struct {
config model.DriverConfig
transport *DLT645Transport
decoder *DLT645Decoder
scheduler *DLT645Scheduler
}
2.3.2 DLT645Transport(传输层)
type DLT645Transport struct {
cfg map[string]any
conn interface{} // serial.Port 或 net.Conn
connected atomic.Bool
connectTime time.Time
lastDisconnectTime time.Time
reconnectCount atomic.Int32
localAddr string
remoteAddr string
// 通信类型
commType CommType // Serial 或 Ethernet
// 串口配置
serialPort string
baudRate int
dataBits int
stopBits int
parity string
// TCP配置
ip string
port int
connectionMode ConnectionMode // Client 或 Server
// 超时配置
connectTimeout time.Duration
responseTimeout time.Duration
sendInterval time.Duration
retryInterval time.Duration
maxRetries int
}
type CommType int
const (
CommTypeSerial CommType = iota
CommTypeEthernet
)
type ConnectionMode int
const (
ConnectionModeClient ConnectionMode = iota
ConnectionModeServer
)
2.3.3 DLT645Scheduler(调度器)
type DLT645Scheduler struct {
transport *DLT645Transport
decoder *DLT645Decoder
// 配置
sendInterval time.Duration // 指令发送间隔
retryInterval time.Duration // 重试间隔
maxRetries int // 最大重试次数
// 统计
totalRequests int64
successCount int64
failureCount int64
mu sync.Mutex
}
2.3.4 DLT645Decoder(解码器)
type DLT645Decoder struct {
// 数据标识映射
dataIDMap map[string]DataIDInfo
}
type DataIDInfo struct {
Name string // 数据项名称
DataType model.DataType // 数据类型
Decimal float64 // 小数位
Unit string // 单位
Description string // 描述
}
type Address struct {
MeterAddress string // 电表通信地址
DataID []byte // 数据标识 (DI3-DI2-DI1-DI0)
Extension string // 扩展标识(如 #T, #01 等)
}
3. 接口定义
3.1 驱动接口(实现 driver.Driver)
| 方法 |
功能 |
参数 |
返回值 |
Init(cfg model.DriverConfig) error |
初始化驱动 |
cfg: 驱动配置 |
error: 错误信息 |
Connect(ctx context.Context) error |
建立连接 |
ctx: 上下文 |
error: 错误信息 |
Disconnect() error |
断开连接 |
无 |
error: 错误信息 |
ReadPoints(ctx, points) (map, error) |
批量读取点位 |
points: 点位列表 |
map[string]model.Value: 读取结果 |
WritePoint(ctx, point, value) error |
写入单个点位 |
point: 点位, value: 值 |
error: 错误信息 |
Health() driver.HealthStatus |
获取健康状态 |
无 |
HealthStatus: 健康状态 |
SetSlaveID(slaveID uint8) error |
设置从站ID |
slaveID: 从站地址 |
error: 错误信息 |
SetDeviceConfig(config map[string]any) error |
设置设备配置 |
config: 配置参数 |
error: 错误信息 |
GetConnectionMetrics() (...) |
获取连接指标 |
无 |
连接时长、重连次数、地址信息 |
3.2 内部接口
3.2.1 传输层接口
| 方法 |
功能 |
SendFrame(frame *DLT645Frame) error |
发送协议帧 |
RecvFrame(ctx context.Context) (*DLT645Frame, error) |
接收协议帧 |
ReadData(meterAddr string, dataID []byte) ([]byte, error) |
读取指定数据 |
WriteData(meterAddr string, dataID []byte, data []byte) error |
写入指定数据 |
BroadcastAddress() ([]string, error) |
广播读取电表地址 |
3.2.2 调度器接口
| 方法 |
功能 |
ReadPoints(ctx, points) |
批量读取点位 |
WritePoint(ctx, point, value) |
写入点位 |
GetStats() |
获取统计信息 |
3.2.3 解码器接口
| 方法 |
功能 |
ParseAddress(addr string) (*Address, error) |
解析地址字符串 |
EncodeFrame(data []byte, meterAddr string) ([]byte, error) |
编码协议帧 |
DecodeFrame(data []byte) (*DLT645Frame, error) |
解码协议帧 |
DecodeValue(frame *DLT645Frame, dataType model.DataType) (any, error) |
解码数据值 |
GetDataIDInfo(dataID []byte) (DataIDInfo, error) |
获取数据标识信息 |
4. 配置参数
4.1 设备配置项
| 参数名 |
类型 |
默认值 |
说明 |
commType |
string |
“Serial” |
物理链路:Serial 或 Ethernet |
connectionTimeout |
int |
3000 |
连接超时时间(毫秒) |
responseTimeout |
int |
3000 |
响应超时时间(毫秒) |
retryInterval |
int |
1000 |
指令重发间隔(毫秒) |
sendInterval |
int |
500 |
指令发送间隔(毫秒) |
maxRetries |
int |
3 |
最大重试次数 |
串口模式配置
| 参数名 |
类型 |
默认值 |
说明 |
serialPort |
string |
- |
串口设备路径,如 /dev/ttyS0 |
baudRate |
int |
9600 |
波特率 |
dataBits |
int |
8 |
数据位 |
stopBits |
int |
1 |
停止位 |
parity |
string |
“None” |
校验位:None, Odd, Even |
以太网模式配置
| 参数名 |
类型 |
默认值 |
说明 |
connectionMode |
string |
“Client” |
连接模式:Client 或 Server |
ip |
string |
- |
设备IP地址(Client模式)或本机地址(Server模式) |
port |
int |
9600 |
端口号 |
4.2 点位配置
4.2.1 地址格式
mail_address#DI3-DI2-DI1-DI0[#extension]
mail_address: 电表通信地址(12位十进制或16位BCD码)
DI3-DI2-DI1-DI0: 数据标识,十六进制表示
extension: 可选扩展标识(如 #T 表示时间,#01 表示费率1等)
4.2.2 支持的数据类型
| 数据类型 |
说明 |
适用场景 |
| UINT8 |
无符号8位整数 |
状态字、标志位 |
| INT8 |
有符号8位整数 |
带符号的状态值 |
| UINT16 |
无符号16位整数 |
电压、电流等变量 |
| INT16 |
有符号16位整数 |
带符号的测量值 |
| UINT32 |
无符号32位整数 |
功率、冻结数据 |
| INT32 |
有符号32位整数 |
带符号的功率值 |
| UINT64 |
无符号64位整数 |
电能量(主要使用) |
| INT64 |
有符号64位整数 |
带符号的电能量 |
| STRING |
字符串 |
时间信息、状态描述 |
4.2.3 数据标识说明
DI3 = 00 - 电能量
| 数据标识 |
说明 |
数据类型 |
Decimal |
| 00-00-00-00 |
当前组合有功总电能 |
UINT64 |
0.01 |
| 00-00-00-01 |
上1结算日组合有功总电能 |
UINT64 |
0.01 |
| 00-80-00-00 |
当前关联总电能 |
UINT64 |
0.01 |
| 00-15-00-01 |
上1结算日A相正向有功电能 |
UINT64 |
0.01 |
DI3 = 01 - 最大需量
| 数据标识 |
说明 |
数据类型 |
Decimal |
| 01-01-00-00 |
当前正向有功最大需量 |
UINT64 |
0.0001 |
| 01-01-00-00#T |
当前正向有功最大需量发生时间 |
STRING |
0 |
DI3 = 02 - 变量
| 数据标识 |
说明 |
数据类型 |
Decimal |
| 02-01-01-00 |
A相电压 |
UINT16 |
0.1 |
| 02-02-01-00 |
A相电流 |
UINT32 |
0.001 |
| 02-03-01-00 |
A相有功功率 |
INT32 |
0.1 |
| 02-0A-01-01 |
A相电压1次谐波含量 |
UINT16 |
0.01 |
| 02-80-00-01 |
零线电流 |
UINT16 |
0.01 |
| 02-80-00-02 |
电网频率 |
UINT16 |
0.01 |
DI3 = 04 - 参变量
| 数据标识 |
说明 |
数据类型 |
Decimal |
| 04-00-01-01 |
日期及时间 |
STRING |
0 |
| 04-00-01-03 |
最大需量周期 |
UINT16 |
0 |
| 04-00-04-01 |
通信地址 |
STRING |
0 |
| 04-00-05-01 |
电表运行状态字1 |
UINT32 |
0 |
DI3 = 05 - 冻结数据
| 数据标识 |
说明 |
数据类型 |
Decimal |
| 05-00-01-01 |
上1次定时冻结正向有功总电能 |
UINT32 |
0.01 |
| 05-00-09-01 |
上1次定时冻结正向有功最大需量 |
UINT32 |
0.0001 |
| 05-00-09-01#T |
上1次定时冻结正向有功最大需量发生时间 |
STRING |
0 |
4.2.4 地址示例
| 地址 |
数据类型 |
说明 |
| 123456789012#02-01-01-00 |
UINT16 |
A相电压 |
| 123456789012#02-02-01-00 |
UINT32 |
A相电流 |
| 123456789012#00-00-00-00 |
UINT64 |
当前组合有功总电能 |
| 123456789012#01-01-00-00 |
UINT64 |
当前正向有功最大需量 |
| 123456789012#01-01-00-00#T |
STRING |
当前正向有功最大需量发生时间 |
| 123456789012#04-00-01-01 |
STRING |
日期及时间 |
5. 数据处理流程
5.1 连接建立流程
串口模式
EdgeX 电能表
| |
|--- 打开串口 ------------------->|
| |
|<-- 串口打开成功 ----------------|
| |
|--- 发送唤醒帧 ----------------->| FE FE FE
| |
|<-- 电表响应 -------------------| 地址帧
以太网模式(Client)
EdgeX 电能表/网关
| |
|--- TCP Connect -------------->|
| |
|<-- TCP ACK -------------------|
| |
|--- 发送唤醒帧 ----------------->| FE FE FE
| |
|<-- 电表响应 -------------------| 地址帧
5.2 协议帧结构
┌─────────────────────────────────────────────────────────┐
│ DL/T 645-2007 Frame │
├──────┬──────┬────────┬────────┬────────┬──────┬───────┤
│ STX │ ADDR │ CTRL │ LEN │ DATA │ CS │ ETX │
│ (1) │ (6) │ (1) │ (1) │ (N) │ (1) │ (1) │
└──────┴──────┴────────┴────────┴────────┴──────┴───────┘
STX: 起始符 0x68
ADDR: 电表地址(6字节BCD码)
CTRL: 控制码
LEN: 数据长度
DATA: 数据域
CS: 校验和
ETX: 结束符 0x16
控制码格式:
┌─────────────────────────────────┐
│ D7 D6 D5 D4 D3 D2 D1 D0 │
├─────────────────────────────────┤
│ D7: 主站/从站标志 (1=主站) │
│ D6-D5: 帧类型 │
│ 00: 标准帧 │
│ 01: 扩展帧 │
│ D4-D3: 命令码 │
│ 01: 读数据 │
│ 02: 写数据 │
│ D2: 保留 │
│ D1-D0: 帧序号 │
└─────────────────────────────────┘
5.3 点位读取流程
┌─────────────────────────────────────────────────────────────┐
│ 采集组定时触发 │
└──────────────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ Scheduler: 按电表地址分组点位 │
└──────────────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ Transport: 发送读数据命令 (CTRL=0x41) │
└──────────────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ Transport: 接收响应帧,校验和验证 │
└──────────────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ Decoder: 解码数据,转换为 model.Value │
└──────────────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 返回结果到 Device Service │
└─────────────────────────────────────────────────────────────┘
5.4 多设备轮询流程
┌─────────────────────────────────────────────────────────────┐
│ 多设备轮询调度 │
└──────────────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 获取设备列表(按地址排序) │
└──────────────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 遍历每个设备,依次发送读取命令 │
│ (每设备之间间隔 sendInterval) │
└──────────────────────────┬──────────────────────────────────┘
▼
┌─────────────────────────────────────────────────────────────┐
│ 接收响应,超时则跳过该设备 │
└─────────────────────────────────────────────────────────────┘
6. 错误处理机制
6.1 错误分类
| 错误类型 |
触发条件 |
处理策略 |
| 连接错误 |
串口打开失败、TCP连接失败 |
自动重连(带指数退避) |
| 帧错误 |
帧格式错误、校验和失败 |
记录日志,丢弃错误帧 |
| 协议错误 |
数据标识不支持、参数错误 |
返回错误,不发送请求 |
| 超时错误 |
响应超时 |
重试或标记失败 |
| 设备错误 |
电表返回否定确认 |
记录日志,标记点位质量为Bad |
6.2 DL/T 645-2007 错误码
| 错误码 |
说明 |
| 0x00 |
正常 |
| 0x01 |
不识别的命令 |
| 0x02 |
无效的数据标识 |
| 0x03 |
无效的数据 |
| 0x04 |
不允许的操作 |
| 0x05 |
访问被拒绝 |
| 0x06 |
数据不存在 |
6.3 重连机制
// 重连策略
maxRetries int // 最大重试次数
retryInterval time.Duration // 基础重试间隔
maxBackoff time.Duration // 最大退避时间
// 重试间隔计算(指数退避)
wait = retryInterval * (2^attempt)
if wait > maxBackoff:
wait = maxBackoff
7. 与其他系统集成
7.1 EdgeX Device Service 集成
驱动通过 driver.RegisterDriver 注册,Device Service 通过统一接口调用:
func init() {
driver.RegisterDriver("dlt645-2007", func() driver.Driver {
return NewDLT645Driver()
})
}
7.2 数据流向
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ 电能表 │─────>│ DLT645 │─────>│ EdgeX │
│ (RS-485/TCP)│ │ Driver │ │ Core Data │
└──────────────┘ └──────────────┘ └──────────────┘
^ │ │
│ │ │
│<─────────────────────│<─────────────────────│
│ 广播地址命令 │ 读取请求 │ 北向指令
7.3 北向数据格式
驱动上报的数据点包含以下信息:
| 字段 |
类型 |
说明 |
PointID |
string |
点位唯一标识 |
Value |
any |
数据值 |
Quality |
string |
品质(Good/Bad/Uncertain) |
TS |
time.Time |
时间戳 |
Unit |
string |
单位(可选) |
8. 代码结构
internal/driver/dlt645/
├── dlt645.go # 驱动主模块
├── transport.go # 传输层(串口/TCP连接、帧处理)
├── scheduler.go # 调度器(批量读写、多设备轮询)
├── decoder.go # 解码器(地址解析、数据编解码)
├── protocol.go # 协议常量和数据结构
├── transport_test.go # 传输层测试
├── decoder_test.go # 解码器测试
└── scheduler_test.go # 调度器测试
8.1 文件职责说明
| 文件 |
职责 |
关键功能 |
dlt645.go |
驱动入口 |
实现 Driver 接口,初始化各模块 |
transport.go |
传输层 |
串口/TCP连接管理、帧收发、超时处理 |
scheduler.go |
调度层 |
点位分组、批量读写、多设备轮询 |
decoder.go |
编解码层 |
地址解析、协议帧编解码 |
protocol.go |
协议定义 |
帧结构、控制码、数据标识映射 |
9. 安全性考虑
9.1 注意事项
| 风险点 |
描述 |
关联模块 |
| 未授权访问 |
无认证机制,任何人可连接 |
transport |
| 数据篡改 |
无消息完整性校验(仅简单校验和) |
decoder |
| 拒绝服务 |
恶意设备可发送大量数据 |
transport |
| 地址伪造 |
电表地址无验证机制 |
decoder |
9.2 建议措施
- 网络层面: 部署防火墙,限制访问IP
- 传输加密: 考虑使用 TLS 加密传输(以太网模式)
- 输入验证: 严格校验电表地址和数据标识格式
- 流量控制: 实现请求频率限制,防止总线拥塞
10. 部署与集成
10.1 驱动注册
在 cmd/driver/registry.go 中添加导入:
import (
_ "github.com/anviod/edgex/internal/driver/dlt645"
)
10.2 配置示例
串口模式配置
device:
name: "ElectricMeter-01"
protocol: "dlt645-2007"
config:
commType: "Serial"
serialPort: "/dev/ttyS0"
baudRate: 9600
dataBits: 8
stopBits: 1
parity: "None"
connectionTimeout: 3000
responseTimeout: 3000
retryInterval: 1000
sendInterval: 500
maxRetries: 3
以太网模式配置(Client)
device:
name: "ElectricMeter-01"
protocol: "dlt645-2007"
config:
commType: "Ethernet"
connectionMode: "Client"
ip: "192.168.1.100"
port: 9600
connectionTimeout: 3000
responseTimeout: 3000
retryInterval: 1000
sendInterval: 500
maxRetries: 3
10.3 点位配置示例
points:
- name: "ActiveEnergy-Total"
address: "123456789012#00-00-00-00"
dataType: "UINT64"
attribute: "Read"
unit: "kWh"
- name: "Voltage-PhaseA"
address: "123456789012#02-01-01-00"
dataType: "UINT16"
attribute: "Read"
unit: "V"
- name: "Current-PhaseA"
address: "123456789012#02-02-01-00"
dataType: "UINT32"
attribute: "Read"
unit: "A"
- name: "Power-Active-PhaseA"
address: "123456789012#02-03-01-00"
dataType: "INT32"
attribute: "Read"
unit: "W"
- name: "MaxDemand-Time"
address: "123456789012#01-01-00-00#T"
dataType: "STRING"
attribute: "Read"
- name: "Meter-Time"
address: "123456789012#04-00-01-01"
dataType: "STRING"
attribute: "Read"
11. 测试方案
11.1 电能表连接示例
本章节介绍如何使用 DL/T 645-2007 插件连接电能表,实现读取电能表中的点位值。
11.1.1 前置准备
- 已安装 RS-485 转串口适配器或以太网网关
- 电能表已正确接线并通电
- 已知电能表通信地址(可通过广播命令获取)
11.1.2 硬件连接
RS-485 连接
EdgeX Gateway RS-485 Adapter 电能表
│ │ │
TXD ──────────────────> A (+) ─────────────> A
RXD ──────────────────> B (-) ─────────────> B
GND ─────────────────> GND ───────────────> GND
以太网连接
EdgeX Gateway 串口服务器 电能表/集中器
│ │ │
Ethernet ─────────────> Ethernet ───────────> RS-485
11.1.3 获取电表地址
使用广播命令获取总线上所有电表地址:
device:
name: "Meter-Scanner"
protocol: "dlt645-2007"
config:
commType: "Serial"
serialPort: "/dev/ttyS0"
baudRate: 9600
驱动启动后会自动发送广播命令,扫描总线上的电表地址。
11.1.4 测试验证
| 测试项 |
验证方法 |
预期结果 |
| 连接测试 |
启动驱动后查看健康状态 |
HealthStatusGood |
| 地址扫描 |
发送广播命令 |
收到电表地址响应 |
| 电能量读取 |
读取 00-00-00-00 |
读取到有功总电能 |
| 电压读取 |
读取 02-01-01-00 |
读取到A相电压 |
| 电流读取 |
读取 02-02-01-00 |
读取到A相电流 |
| 时间读取 |
读取 04-00-01-01 |
读取到电表时间 |
11.1.5 常见问题排查
| 问题现象 |
可能原因 |
解决方案 |
| 连接失败 |
串口设备不存在 |
检查串口路径是否正确 |
| 连接失败 |
权限不足 |
确保用户有权限访问串口设备 |
| 无响应 |
RS-485接线错误 |
检查A/B线是否接反 |
| 无响应 |
波特率不匹配 |
确认电表波特率配置 |
| 读取失败 |
地址错误 |
使用广播命令重新获取地址 |
| 读取失败 |
校验和错误 |
检查线路干扰,增加发送间隔 |
11.1.6 支持的电能表类型
| 类型 |
说明 |
支持程度 |
| 单相电能表 |
普通居民用电表 |
完全支持 |
| 三相四线电能表 |
工业用电表 |
完全支持 |
| 三相三线电能表 |
工业用电表 |
完全支持 |
| 多功能电能表 |
支持多种计量功能 |
完全支持 |
附录:DL/T 645-2007 数据标识编码
A.1 数据标识格式
DI3 DI2 DI1 DI0
├──┴──┴──┴──┘
│ │ │ └── 结算日/特殊标识
│ │ └────── 数据项分类
│ └────────── 数据类型
A.2 数据类型编码
| DI3 |
数据类型 |
| 00 |
电能量 |
| 01 |
最大需量 |
| 02 |
变量 |
| 03 |
冻结数据 |
| 04 |
参变量 |
| 05 |
定时冻结数据 |
| 06 |
负荷记录 |
A.3 结算日编码(DI0)
| DI0 |
说明 |
| 00 |
当前 |
| 01 |
上1结算日 |
| 02 |
上2结算日 |
| … |
… |
| 0C |
上12结算日 |