news 2026/4/30 22:08:18

赶项目必备:C# 读写台达 PLC 全解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
赶项目必备:C# 读写台达 PLC 全解析

C#读写台达PLC源代码,分别操控D、M、X、Y、T寄存器的读写,代码注释详细、分类说明,附带文档有台达PLC与上位机通讯协议(逐条解释详细)、PLC各种寄存器通讯地与16进制对照表。 不需要再花时间精力研究台达PLC官方文档,直接套用。 适合赶项目又未接触过台达的老手和想学上位机的电气工程人员。

在项目开发中,快速上手读写台达 PLC 寄存器对老手和电气工程人员来说十分关键。今天就来给大家分享如何用 C# 操控台达 PLC 的 D、M、X、Y、T 寄存器,并详细解释通讯协议及寄存器地址对照。

台达 PLC 与上位机通讯协议

台达 PLC 与上位机采用特定通讯协议进行交互。以下是协议的逐条详细解释:

1. 通讯帧格式

通讯帧一般由起始字符、设备地址、功能码、数据区、校验码和结束字符组成。例如,起始字符可能为0x02,表示一帧数据的开始;结束字符如0x03,标志数据帧的结束。

2. 设备地址

每台 PLC 在网络中有唯一地址,范围通常是0x01 - 0x7F。通过这个地址,上位机可精准定位要通讯的 PLC 设备。比如地址0x01代表网络中的第一台 PLC。

3. 功能码

功能码决定了通讯的操作类型。像0x03功能码表示读取保持寄存器,0x10功能码表示写入多个保持寄存器。不同功能码对应不同的寄存器操作。

4. 数据区

存放具体要读写的数据内容。根据功能码和操作寄存器的不同,数据区的格式和长度也有差异。比如读取多个寄存器时,数据区会指定起始寄存器地址和寄存器数量。

5. 校验码

用于验证数据传输的正确性。常见的校验方式有 CRC16 校验。通过对通讯帧中除起始、结束字符外的数据进行计算得到校验码,接收方重新计算校验码并与接收到的校验码对比,一致则说明数据传输无误。

PLC 各种寄存器通讯地址与 16 进制对照表

寄存器类型16 进制地址范围说明
D 寄存器0x0000 - 0xFFFF数据寄存器,用于存储各种数据
M 寄存器0x0000 - 0xFFFF辅助继电器,常用于逻辑控制
X 寄存器0x0000 - 0xFFFF输入继电器,反映外部输入信号状态
Y 寄存器0x0000 - 0xFFFF输出继电器,控制外部输出设备
T 寄存器0x0000 - 0xFFFF定时器,用于定时控制

C# 代码实现

1. 引用必要的命名空间

using System; using System.IO.Ports; using System.Text;

这里System.IO.Ports用于串口通讯,System.Text用于字符串编码转换。

2. 计算 CRC16 校验码

public static ushort CalculateCRC16(byte[] data) { ushort crc = 0xFFFF; foreach (byte b in data) { crc ^= b; for (int i = 0; i < 8; i++) { if ((crc & 0x0001)!= 0) { crc >>= 1; crc ^= 0xA001; } else { crc >>= 1; } } } return crc; }

这段代码通过对传入的字节数组进行循环运算,得出 CRC16 校验码。

3. 发送串口数据

public static void SendData(string portName, byte[] data) { using (SerialPort serialPort = new SerialPort(portName, 9600, Parity.None, 8, StopBits.One)) { serialPort.Open(); serialPort.Write(data, 0, data.Length); serialPort.Close(); } }

此方法通过指定的串口,以 9600 波特率、无校验位、8 位数据位和 1 位停止位发送数据。

4. 读取 D 寄存器

public static byte[] ReadDRegister(byte deviceAddress, ushort registerAddress, ushort registerCount) { byte[] data = new byte[8]; data[0] = 0x02; // 起始字符 data[1] = deviceAddress; data[2] = 0x03; // 读取保持寄存器功能码 data[3] = (byte)(registerAddress >> 8); data[4] = (byte)(registerAddress & 0xFF); data[5] = (byte)(registerCount >> 8); data[6] = (byte)(registerCount & 0xFF); ushort crc = CalculateCRC16(new ArraySegment<byte>(data, 1, 6).ToArray()); data[7] = (byte)(crc & 0xFF); data[8] = (byte)(crc >> 8); data[9] = 0x03; // 结束字符 SendData("COM1", data); // 这里可添加接收数据处理逻辑 return data; }

该函数构建读取 D 寄存器的通讯帧,设置设备地址、功能码、寄存器起始地址和数量,计算校验码后发送数据。

5. 写入 D 寄存器

public static byte[] WriteDRegister(byte deviceAddress, ushort registerAddress, byte[] values) { int dataLength = 6 + values.Length; byte[] data = new byte[dataLength + 3]; data[0] = 0x02; data[1] = deviceAddress; data[2] = 0x10; // 写入多个保持寄存器功能码 data[3] = (byte)(registerAddress >> 8); data[4] = (byte)(registerAddress & 0xFF); data[5] = (byte)(values.Length >> 1); data[6] = (byte)(values.Length & 0xFF); Buffer.BlockCopy(values, 0, data, 7, values.Length); ushort crc = CalculateCRC16(new ArraySegment<byte>(data, 1, dataLength - 2).ToArray()); data[dataLength + 1] = (byte)(crc & 0xFF); data[dataLength + 2] = (byte)(crc >> 8); data[dataLength + 3] = 0x03; SendData("COM1", data); // 这里可添加接收数据处理逻辑 return data; }

此函数用于写入 D 寄存器,根据传入的寄存器地址和要写入的值构建通讯帧,同样计算校验码并发送。

6. 读取 M 寄存器

M 寄存器的读取与 D 寄存器类似,只是功能码和地址对应不同。假设 M 寄存器读取功能码为0x01,代码如下:

public static byte[] ReadMRegister(byte deviceAddress, ushort registerAddress, ushort registerCount) { byte[] data = new byte[8]; data[0] = 0x02; data[1] = deviceAddress; data[2] = 0x01; // 读取 M 寄存器功能码 data[3] = (byte)(registerAddress >> 8); data[4] = (byte)(registerAddress & 0xFF); data[5] = (byte)(registerCount >> 8); data[6] = (byte)(registerCount & 0xFF); ushort crc = CalculateCRC16(new ArraySegment<byte>(data, 1, 6).ToArray()); data[7] = (byte)(crc & 0xFF); data[8] = (byte)(crc >> 8); data[9] = 0x03; SendData("COM1", data); // 这里可添加接收数据处理逻辑 return data; }

7. 读取 X、Y、T 寄存器

读取 X、Y、T 寄存器也遵循类似的逻辑,根据各自的功能码和地址范围进行操作。例如读取 X 寄存器:

public static byte[] ReadXRegister(byte deviceAddress, ushort registerAddress, ushort registerCount) { byte[] data = new byte[8]; data[0] = 0x02; data[1] = deviceAddress; // 假设读取 X 寄存器功能码为 0x02 data[2] = 0x02; data[3] = (byte)(registerAddress >> 8); data[4] = (byte)(registerAddress & 0xFF); data[5] = (byte)(registerCount >> 8); data[6] = (byte)(registerCount & 0xFF); ushort crc = CalculateCRC16(new ArraySegment<byte>(data, 1, 6).ToArray()); data[7] = (byte)(crc & 0xFF); data[8] = (byte)(crc >> 8); data[9] = 0x03; SendData("COM1", data); // 这里可添加接收数据处理逻辑 return data; }

通过以上内容,无论是赶项目的老手,还是想学习上位机的电气工程人员,都能快速掌握 C# 读写台达 PLC 寄存器的方法,希望对大家有所帮助!

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/29 19:27:36

Draw.io Obsidian插件终极教程:快速上手专业图表制作

Draw.io Obsidian插件终极教程&#xff1a;快速上手专业图表制作 【免费下载链接】drawio-obsidian Draw.io plugin for obsidian.md 项目地址: https://gitcode.com/gh_mirrors/dr/drawio-obsidian 如果你正在寻找一款能够在Obsidian中创建精美图表的插件&#xff0c;…

作者头像 李华
网站建设 2026/4/26 21:38:20

深岩银河存档编辑器:免费工具完整使用教程与操作指南

想要轻松修改深岩银河游戏存档吗&#xff1f;这款免费的深岩银河存档编辑器正是你需要的强大工具&#xff01;它能够让你快速调整游戏中的各种资源和职业等级&#xff0c;为你的游戏体验带来更多便利和乐趣。 【免费下载链接】DRG-Save-Editor Rock and stone! 项目地址: htt…

作者头像 李华
网站建设 2026/4/23 14:01:05

Venera漫画阅读器高效管理全攻略:从入门到精通的实用技巧

还在为手机里零散的漫画文件发愁吗&#xff1f;想不想拥有一个能同时管理本地收藏和网络追更的专业级漫画阅读器&#xff1f;Venera就是你的不二选择&#xff01;这款跨平台漫画阅读器不仅能帮你高效整理本地漫画&#xff0c;还能让你轻松订阅各种网络漫画源&#xff0c;真正实…

作者头像 李华
网站建设 2026/4/17 18:08:53

Klipper固件全面安装教程:构建高性能3D打印平台

Klipper固件全面安装教程&#xff1a;构建高性能3D打印平台 【免费下载链接】klipper 项目地址: https://gitcode.com/gh_mirrors/kli/klipper Klipper作为一款创新的3D打印机固件&#xff0c;通过将复杂计算任务分配给主计算机&#xff0c;让微控制器专注于精准运动控…

作者头像 李华
网站建设 2026/4/30 4:43:54

益达规则仓库:站点资源解析与高效配置完全指南

作为技术顾问&#xff0c;我经常遇到这样的问题&#xff1a;"为什么我的视频资源总是解析失败&#xff1f;""如何快速配置多个站点的访问规则&#xff1f;"今天&#xff0c;我将通过益达规则仓库这一强大工具&#xff0c;为你提供一站式的解决方案。 【免费…

作者头像 李华