基于 CAN 总线的模块化远程 IO 系统设计与热插拔机制实现

一、引言

在工业自动化控制系统中,远程 IO 系统(Remote IO System) 是实现设备信号扩展、异地控制与模块化维护的核心组件。传统远程 IO 多采用 RS485 或工业以太网,而 CAN 总线因其布线简单、抗干扰能力强、节点数多、实时性好,正在逐渐取代 RS485 成为模块化 IO 扩展的重要通信基础。

本篇文章将围绕 基于 CAN 总线的远程 IO 系统设计 展开分析,重点讲解以下内容:

  • 模块化 IO 结构设计

  • CAN 总线通讯协议与节点地址映射

  • IO 状态同步与输入轮询策略

  • 输出控制机制与回显校验

  • 节点热插拔识别机制

  • 故障自恢复与主控容错处理


二、系统结构与设计目标

1. 应用场景

  • PLC/工控主站 IO 扩展

  • 智能仓储传感器/执行器管理

  • AGV 分布式控制模块

  • 远程继电器/电磁阀驱动单元

2. 设计目标

模块 目标说明
IO 模块可热插拔 插入后自动识别注册,拔出无异常
支持输入/输出混合通道 如 DI + DO / AI + AO 模块
主控统一调度 主控采集所有输入状态并控制输出
CAN 帧标准化设计 所有模块报文结构统一,扩展简单
故障模块隔离 单个模块异常不影响全局系统运行


三、模块化结构设计

1. IO 模块物理结构

  • 电源:24V 工业电源接入

  • 通讯:CAN_H / CAN_L + GND

  • 单片机:STM32F103 / GD32F130 等

  • IO 驱动芯片:

    • DI:光耦隔离输入

    • DO:MOS 或继电器驱动

    • AI:16-bit ADC,如 ADS1115

    • AO:DAC + 电压/电流变换电路

2. 接口定义举例(8路混合 IO)

接口名称 类型 描述
IO1~IO4 DI 数字输入
IO5~IO6 DO 数字输出(继电器)
IO7 AI 模拟输入(0~10V)
IO8 AO 模拟输出(0~10V)


四、CAN 通讯协议设计

1. 通讯架构:主从模型

  • 主控定时轮询所有 IO 模块状态

  • 主控下发控制命令控制 DO、AO 输出

  • 所有模块需按统一报文格式响应

2. CAN ID 分配方案(标准帧 11 位)

类型 起始 ID 用途
控制命令帧 0x200 主控 → 模块(设置输出)
状态上报帧 0x300 模块 → 主控(输入反馈)
注册帧 0x400 模块 → 主控(上线广播)
心跳帧 0x500 模块 → 主控(保活)

模块地址(模块ID)由主控动态分配或模块 EEPROM 烧录预设,避免重复。


五、报文格式定义

1. 控制命令帧(0x200 + 模块ID)

字节位 内容 说明
0 控制字类型 0xA1=DO输出, 0xA2=AO设定
1 通道编号 DO1DO8 / AO1AO2
2~3 输出值 DO为 0/1,AO为模拟量
4~7 预留/CRC8 可用于检错

2. 状态反馈帧(0x300 + 模块ID)

字节位 内容 说明
0 状态标志位 RUN/FAULT 等
1 DI 状态 每 bit 表示一路
2~3 AI 通道 1 电压值(mV)
4~5 AI 通道 2
6~7 CRC8 校验


六、IO 输入轮询与输出控制机制

1. 输入轮询机制

主控每隔 T 毫秒(如 100ms)依次查询每个模块状态:

 
  

c

复制编辑

for (module_id in modules) { send_status_query(module_id); wait_response(); update_DI_status(); refresh_AI_curve(); }

2. 输出控制机制

  • 来自上位机(如 SCADA)的指令下发至主控

  • 主控解析后构造控制帧并下发至目标模块

  • 模块执行输出控制并返回回显帧

  • 主控对比期望值与实际值一致性,保障控制安全


七、模块热插拔机制实现

1. 上电自注册广播(0x400)

模块启动后,自动广播如下注册帧:

字节 内容
0 注册标志 0xB1
1 模块类型码(如 0x10=4DI4DO)
2~3 模块编号(EEPROM 或 DIP)
4~5 固件版本
6~7 CRC8 校验

2. 主控响应注册

主控接收后将该模块加入在线列表,并发送配置帧设定其心跳间隔与响应周期。

3. 心跳检测

模块每隔 N 秒发送心跳(0x500+模块ID):

 
  

c

复制编辑

Byte0: 0xC1 Byte1: 状态字 Byte2~7: 可附加温度、电源电压、通信状态等

主控连续丢失 M 次心跳后,标记模块离线,并可做通知/切换/报警处理。


八、模块节点软件框架(STM32 实现)

1. 初始化阶段

 
  

c

复制编辑

CAN_Init(); Load_ModuleID_From_EEPROM(); GPIO_Init(); ADC_Init(); Timer_Init(); Broadcast_Registration_Frame();

2. 主循环逻辑

 
  

c

复制编辑

while (1) { Receive_CAN_Msg(); // 监听控制命令 Process_DO_Control(); // 控制输出通道 Update_DI_Status(); // 采集输入状态 Sample_Analog_Inputs(); // 模拟采样 Send_Status_Frame(); // 周期上报状态 Send_Heartbeat(); // 定时心跳包 }


九、主控管理逻辑

1. 模块发现与登记

  • 维护模块 ID → 类型 → 状态的映射表

  • 动态添加/删除模块,更新配置 UI

  • 显示每模块在线/离线/故障/IO 状态等

2. IO 操作 API 示例(上位机)

 
  

python

复制编辑

def set_DO(module_id, channel, value): frame = [0xA1, channel, value & 0xFF, value >> 8] can.send(0x200 + module_id, frame) def read_DI(module_id): can.send(0x210 + module_id, [0x01]) return parse_reply()


十、故障检测与系统容错设计

故障类型 原因分析 应对策略
模块掉线 掉电/线缆松动 主控超时判断,发告警
输出不一致 模块未执行或反馈错误 回显对比失败,自动重发命令
控制无响应 主控发送帧失败或 ID 错配 加入软件 ACK 确认机制
CRC 校验失败 通讯干扰 / 程序Bug 丢弃错误帧,记录日志
地址冲突 EEPROM 或 DIP 编码重复 主控记录冲突ID,自动分配新ID


十一、总结与拓展方向

基于 CAN 的远程 IO 系统,具备如下优势:

  • 节点可即插即用,部署灵活

  • 同一条 CAN 总线最多支持 100+ 模块

  • 主控集中管理,系统扩展性强

  • 模块结构统一,维护成本低

后续可拓展方向

  • 增加 CANopen 协议兼容(PDO/SDO 模式)

  • 支持 IO 配置远程升级(Bootloader + Flash)

  • 加入时间同步协议,精确采样时间戳

  • 接入边缘计算/云平台实现分布式控制

你可能感兴趣的:(rabbitmq)