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/25 20:45:44

Venera:重新定义你的跨平台漫画阅读体验

Venera&#xff1a;重新定义你的跨平台漫画阅读体验 【免费下载链接】venera A comic app 项目地址: https://gitcode.com/gh_mirrors/ve/venera 还在为漫画阅读的设备限制而烦恼吗&#xff1f;想在手机、平板、电脑之间无缝切换却找不到合适的工具&#xff1f;Venera作…

作者头像 李华
网站建设 2026/4/23 12:28:15

PyTorch-CUDA-v2.9镜像是否适合团队协作开发?支持多人共享实例

PyTorch-CUDA-v2.9镜像是否适合团队协作开发&#xff1f;支持多人共享实例 在AI研发日益工程化的今天&#xff0c;一个常见的痛点浮出水面&#xff1a;为什么同一个模型代码&#xff0c;在同事的机器上跑得飞快、结果稳定&#xff0c;而到了自己环境却频频报错、性能骤降&#…

作者头像 李华
网站建设 2026/4/24 13:48:46

Venera漫画阅读器全功能深度解析:打造个人专属漫画世界

Venera漫画阅读器全功能深度解析&#xff1a;打造个人专属漫画世界 【免费下载链接】venera A comic app 项目地址: https://gitcode.com/gh_mirrors/ve/venera Venera作为一款专业的跨平台漫画阅读器&#xff0c;集本地管理与网络订阅于一身&#xff0c;为用户提供全方…

作者头像 李华
网站建设 2026/4/19 4:44:41

多模态情感分析实战指南:从技术架构到Web部署深度解析

多模态情感分析实战指南&#xff1a;从技术架构到Web部署深度解析 【免费下载链接】Multimodal-Emotion-Recognition A real time Multimodal Emotion Recognition web app for text, sound and video inputs 项目地址: https://gitcode.com/gh_mirrors/mu/Multimodal-Emoti…

作者头像 李华