首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Modbus函数0x06

Modbus函数0x06
EN

Stack Overflow用户
提问于 2019-07-26 07:47:11
回答 1查看 324关注 0票数 1

面临着一个问题。有一个0x03函数,但是我需要在0x06中重做它,我不知道怎么做。

我知道函数06没有可变的部分。一个寄存器的值总是传递给它。但我不明白有什么需要纠正的。拜托救救我。

在这里我为函数创建了一个包:

代码语言:javascript
复制
 private void BuildMessage(byte address, byte type, ushort start, ushort registers, ref byte[] message)
                {
                    if (type == 3 || type == 16)
                    {
                        //Array to receive CRC bytes:
                        byte[] CRC = new byte[2];

                        message[0] = address;
                        message[1] = type;
                        message[2] = (byte)(start >> 8);
                        message[3] = (byte)start;
                        message[4] = (byte)(registers >> 8);
                        message[5] = (byte)registers;

                        GetCRC(message, ref CRC);
                        message[message.Length - 2] = CRC[0];
                        message[message.Length - 1] = CRC[1];
                    }
                    else if (type == 6)
                    {
                        byte[] CRC = new byte[2];

                        message[0] = address;
                        message[1] = type;
                        message[2] = (byte)(start >> 8);
                        message[3] = (byte)start;
                        message[4] = (byte)(registers >> 8);
                        message[5] = (byte)registers;

                        GetCRC(message, ref CRC);
                        message[6] = CRC[0];
                        message[7] = CRC[1];
                    }
        }

,这是我的函数3:

代码语言:javascript
复制
 public bool SendFunc(int funcNumer, string connectType, byte address, ushort start, ushort registers, ref short[] values)
            {
                #region №3
                if (funcNumer == 3)
                {
                    #region serial-port
                    if (connectType.Equals("COM"))
                    {
                        //Ensure port is open:
                        if (sp.IsOpen)
                        {
                            //Clear in/out buffers:
                            sp.DiscardOutBuffer();
                            sp.DiscardInBuffer();
                            //Function 3 request is always 8 bytes:
                            byte[] message = new byte[8];
                            //Function 3 response buffer:
                            byte[] response = new byte[5 + 2 * registers];
                            //Build outgoing modbus message:
                            BuildMessage(address, (byte)3, start, registers, ref message);
                            //Send modbus message to Serial Port:
                            try
                            {
                                sp.Write(message, 0, message.Length);
                                GetResponse("COM", ref response);
                            }
                            catch (Exception err)
                            {
                                modbusStatus = "" + err.Message;
                                return false;
                            }
                            //Evaluate message:
                            if (CheckResponse(response))
                            {
                                //Return requested register values:
                                for (int i = 0; i < (response.Length - 5) / 2; i++)
                                {
                                    values[i] = response[2 * i + 3];
                                    values[i] <<= 8;
                                    values[i] += response[2 * i + 4];
                                }
                                modbusStatus = "";
                                return true;
                            }
                            else
                            {
                                modbusStatus = "";
                                return false;
                            }
                        }
                        else
                        {
                            modbusStatus = "";
                            return false;
                        }
                    }

,在这里,我试图实现函数6:

代码语言:javascript
复制
if (funcNumer == 6)
            {
                #region serial-port
                if (connectType.Equals("COM"))
                {
                    //Ensure port is open:
                    if (sp.IsOpen)
                    {
                        //Clear in/out buffers:
                        sp.DiscardOutBuffer();
                        sp.DiscardInBuffer();
                        //Function 3 request is always 8 bytes:
                        byte[] message = new byte[8];
                        //Function 3 response buffer:
                        byte[] response = new byte[5 + 2 * registers];
                        //Build outgoing modbus message:
                        BuildMessage(address, (byte)6, start, registers, ref message);
                        //Send modbus message to Serial Port:
                        try
                        {
                            sp.Write(message, 0, message.Length);
                            GetResponse("COM", ref response);
                        }
                        catch (Exception err)
                        {
                            modbusStatus = "" + err.Message;
                            return false;
                        }
                        //Evaluate message:
                        if (CheckResponse(response))
                        {
                            //Return requested register values:
                            for (int i = 0; i < (response.Length - 5) / 2; i++)
                            {
                                values[i] = response[2 * i + 3];
                                values[i] <<= 8;
                                values[i] += response[2 * i + 4];
                            }
                            modbusStatus = "";
                            return true;
                        }
                        else
                        {
                            modbusStatus = "";
                            return false;
                        }
                    }
                    else
                    {
                        modbusStatus = "";
                        return false;
                    }
                }

--这是我检查响应的函数:

代码语言:javascript
复制
 private bool CheckResponse(byte[] response)
        {
            //Perform a basic CRC check:
            byte[] CRC = new byte[2];
            GetCRC(response, ref CRC);
            if (CRC[0] == response[response.Length - 2] && CRC[1] == response[response.Length - 1])
                return true;
            else
                return false;
        }

--这是我的get响应函数:

代码语言:javascript
复制
private void GetResponse(string connect, ref byte[] response)
        {
            if (connect.Equals("COM"))
            {
                for (int i = 0; i < response.Length; i++)
                {
                    response[i] = (byte)(sp.ReadByte());
                }
            }
            else if (connect.Equals("TCP"))
            {
                NetworkStream stream = tcpClient.GetStream();

                for (int i = 0; i < response.Length; i++)
                {
                    response[i] = (byte)(stream.ReadByte());
                }
            }
            else
            {

            }            
        }
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-07-26 10:51:00

Modbus函数0x030x06之间的区别实际上是在您的问题:CheckResponse(response)上没有显示的代码的一部分。

函数0x03读取许多寄存器,这些寄存器中的值(来自从服务器)包含在响应中。

函数0x06编写一个单个寄存器并返回回显。因此,响应与查询相同。

有了这些信息,应该可以很容易地修改代码:删除检索寄存器值的for循环。

除此之外,您可能还需要修改您的CheckResponse()函数,但这也应该是非常直接的:只需检查响应与查询(消息)完全相同。

编辑:--如果您的CheckResponse()函数只检查响应的正确CRC,我想您可以保持它的原样。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57215433

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档