Пример #1
0
        public override bool Read <T>(out List <T> value, Dictionary <string, string> parm)
        {
            lock (lockObject)
            {
                value = new List <T>();
                bool result = true;
                //读取开始点
                if (!parm.ContainsKey("Start") && !parm.ContainsKey("Address"))
                {
                    All.Class.Error.Add("数据读取参数中不包含寄存器地址", Environment.StackTrace);
                    return(false);
                }
                ushort tmpAddress = 0;
                if (parm.ContainsKey("Start"))
                {
                    tmpAddress = parm["Start"].ToUshort();
                }
                if (parm.ContainsKey("Address"))
                {
                    tmpAddress = parm["Address"].ToUshort();
                }
                Class.TypeUse.TypeList t = All.Class.TypeUse.GetType <T>();
                //读取区域
                if (!parm.ContainsKey("Code"))
                {
                    switch (t)
                    {
                    case Class.TypeUse.TypeList.Boolean:
                        parm.Add("Code", "M");
                        break;

                    case Class.TypeUse.TypeList.String:
                    case Class.TypeUse.TypeList.UShort:
                    case Class.TypeUse.TypeList.Int:
                    case Class.TypeUse.TypeList.Long:
                    case Class.TypeUse.TypeList.Byte:
                    case Class.TypeUse.TypeList.Float:
                    case Class.TypeUse.TypeList.Double:
                        parm.Add("Code", "D");
                        break;
                    }
                }
                else
                {
                    switch (t)
                    {
                    case Class.TypeUse.TypeList.Boolean:
                        if (parm["Code"].ToUpper() != "X" && parm["Code"].ToUpper() != "M" && parm["Code"].ToUpper() != "Y")
                        {
                            All.Class.Error.Add("读取参数中区域类型和返回数据类型不一致", Environment.StackTrace);
                            return(false);
                        }
                        break;

                    case Class.TypeUse.TypeList.String:
                    case Class.TypeUse.TypeList.UShort:
                    case Class.TypeUse.TypeList.Int:
                    case Class.TypeUse.TypeList.Long:
                    case Class.TypeUse.TypeList.Byte:
                    case Class.TypeUse.TypeList.Float:
                    case Class.TypeUse.TypeList.Double:
                        if (parm["Code"].ToUpper() != "D")
                        {
                            All.Class.Error.Add("读取参数中区域类型和返回数据类型不一致", Environment.StackTrace);
                        }
                        break;
                    }
                }
                //读取结束点
                ushort tmpLen     = 1;
                int    tmpBoolLen = 0;
                int    tmpStart   = 0;
                if (!parm.ContainsKey("End"))
                {
                    parm.Add("End", tmpAddress.ToString());
                }
                ushort end = parm["End"].ToUshort();
                if (end < tmpAddress)
                {
                    All.Class.Error.Add("读取参数中结束点大于起始点", Environment.StackTrace);
                    return(false);
                }
                switch (parm["Code"].ToUpper())
                {
                case "M":
                    tmpLen     = (ushort)(((int)Math.Floor(end / 8f) - (int)Math.Floor(tmpAddress / 8f) + 1) & 0xFFFF);
                    tmpStart   = tmpAddress % 8;
                    tmpBoolLen = (tmpLen - 1) * 8 - tmpStart + (end % 8) + 1;
                    tmpAddress = (ushort)((int)Math.Floor(tmpAddress / 8f) + 0x100);
                    break;

                case "X":
                    tmpLen     = (ushort)(((int)Math.Floor(end / 10f) - (int)Math.Floor(tmpAddress / 10f) + 1) & 0xFFFF);
                    tmpStart   = tmpAddress % 10;
                    tmpBoolLen = (tmpLen - 1) * 8 - tmpStart + (end % 10) + 1;
                    tmpAddress = (ushort)((int)Math.Floor(tmpAddress / 10f) + 0x80);
                    break;

                case "Y":
                    tmpLen     = (ushort)(((int)Math.Floor(end / 10f) - (int)Math.Floor(tmpAddress / 10f) + 1) & 0xFFFF);
                    tmpStart   = tmpAddress % 10;
                    tmpBoolLen = (tmpLen - 1) * 8 - tmpStart + (end % 10) + 1;
                    tmpAddress = (ushort)((int)Math.Floor(tmpAddress / 10f) + 0xA0);
                    break;

                case "D":
                    tmpLen     = (ushort)(2 * (end - tmpAddress + 1) & 0xFFFF);
                    tmpAddress = (ushort)((tmpAddress * 2 + 0x1000) & 0xFFFF);
                    break;

                case "T":
                case "C":
                case "S":
                    All.Class.Error.Add("读取参数中的区域暂时没有驱动,须要添加", Environment.StackTrace);
                    break;

                default:
                    All.Class.Error.Add("读取参数中的区域错误,PLC没有此区域", Environment.StackTrace);
                    break;
                }
                int    len      = 4 + 2 * tmpLen;
                byte[] sendBuff = new byte[11];
                byte[] readBuff;
                sendBuff[0] = 0x02;
                sendBuff[1] = 0x30;
                Array.Copy(Encoding.ASCII.GetBytes(string.Format("{0:X4}", tmpAddress)), 0, sendBuff, 2, 4);
                Array.Copy(Encoding.ASCII.GetBytes(string.Format("{0:X2}", tmpLen)), 0, sendBuff, 6, 2);
                sendBuff[8] = 0x03;
                byte sumLow, sumHigh;
                All.Class.Check.SumCheck(sendBuff.ToArray(), 1, sendBuff.Length - 3, out sumLow, out sumHigh);
                Array.Copy(Encoding.ASCII.GetBytes(string.Format("{0:X2}", sumLow)), 0, sendBuff, 9, 2);
                if (WriteAndRead <byte[], byte[]>(sendBuff, len, out readBuff))
                {
                    if (readBuff[0] != 0x02 && readBuff[readBuff.Length - 3] != 0x03)
                    {
                        All.Class.Error.Add("读取参数帧头或帧尾校验失败", Environment.StackTrace);
                        return(false);
                    }
                    All.Class.Check.SumCheck(readBuff.ToArray(), 1, readBuff.Length - 3, out sumLow, out sumHigh);
                    if (Encoding.ASCII.GetString(readBuff, readBuff.Length - 2, 2) != string.Format("{0:X2}", sumLow))
                    {
                        All.Class.Error.Add("读取参数和校验失败", Environment.StackTrace);
                        return(false);
                    }
                    byte[] tmp;
                    bool[] tmpBool;
                    switch (parm["Code"].ToUpper())
                    {
                    case "X":
                    case "Y":
                    case "M":
                        tmp     = Encoding.ASCII.GetString(readBuff, 1, readBuff.Length - 4).ToHexBytes();
                        tmpBool = All.Class.Num.Byte2Bool(tmp);
                        for (int i = tmpStart, j = 0; i < tmpBool.Length && j < tmpBoolLen; i++, j++)
                        {
                            value.Add((T)(object)tmpBool[i]);
                        }
                        break;

                    case "D":
                        tmp = All.Class.Num.SwitchHighAndLow(Encoding.ASCII.GetString(readBuff, 1, readBuff.Length - 4).ToHexBytes());
                        switch (t)
                        {
                        case Class.TypeUse.TypeList.Byte:
                            for (int i = 0; i < tmp.Length; i++)
                            {
                                value.Add((T)(object)tmp[i]);
                            }
                            break;

                        case Class.TypeUse.TypeList.UShort:
                            for (int i = 0; i < tmp.Length - 1; i = i + 2)
                            {
                                value.Add((T)(object)(ushort)((((tmp[i] << 8) + tmp[i + 1])) & 0xFFFF));
                            }
                            break;

                        case Class.TypeUse.TypeList.Long:
                            for (int i = 0; i < tmp.Length - 1; i = i + 2)
                            {
                                value.Add((T)(object)(long)(((tmp[i] << 8) + tmp[i + 1])));
                            }
                            break;

                        case Class.TypeUse.TypeList.Float:
                            if ((tmp.Length % 4) != 0)
                            {
                                All.Class.Error.Add("Fxplc读取单精度浮点数时,必须一次读4个字节");
                                return(false);
                            }
                            for (int i = 0; i < tmp.Length - 1; i = i + 4)
                            {
                                value.Add((T)(object)BitConverter.ToSingle(tmp, i));
                            }
                            break;

                        case Class.TypeUse.TypeList.Double:
                            if ((tmp.Length % 8) != 0)
                            {
                                All.Class.Error.Add("Fxplc读取双精度浮点数时,必须一次读8个字节");
                                return(false);
                            }
                            for (int i = 0; i < tmp.Length - 1; i = i + 8)
                            {
                                value.Add((T)(object)BitConverter.ToDouble(tmp, i));
                            }
                            break;

                        case Class.TypeUse.TypeList.String:
                            value.Add((T)(object)Encoding.ASCII.GetString(tmp));
                            break;

                        case Class.TypeUse.TypeList.Int:
                            int tmpInt = 0;
                            for (int i = 0; i < tmp.Length - 1; i = i + 2)
                            {
                                tmpInt = (tmp[i] << 8) + tmp[i + 1];
                                if ((tmpInt & 0x8000) == 0x8000)
                                {
                                    tmpInt = -(tmpInt ^ 0xFFFF) - 1;
                                }
                                value.Add((T)(object)tmpInt);
                            }
                            break;
                        }
                        break;

                    default:
                        throw new Exception("Error");
                    }
                }
                else
                {
                    result = false;
                }
                return(result);
            }
        }
Пример #2
0
        public override bool Read <T>(out List <T> value, Dictionary <string, string> parm)
        {
            lock (lockObject)
            {
                bool result = true;
                value = new List <T>();
                if (!parm.ContainsKey("Start") && !parm.ContainsKey("Address"))
                {
                    All.Class.Error.Add("数据读取参数中不包含寄存器地址", Environment.StackTrace);
                    return(false);
                }
                ushort tmpAddress = 0;
                if (parm.ContainsKey("Start"))
                {
                    tmpAddress = parm["Start"].ToUshort();
                }
                if (parm.ContainsKey("Address"))
                {
                    tmpAddress = parm["Address"].ToUshort();
                }
                if (!parm.ContainsKey("End"))
                {
                    parm.Add("End", tmpAddress.ToString());
                }
                ushort end = parm["End"].ToUshort();
                if (end < tmpAddress)
                {
                    All.Class.Error.Add("读取参数中结束点大于起始点", Environment.StackTrace);
                    return(false);
                }
                Class.TypeUse.TypeList t = All.Class.TypeUse.GetType <T>();
                string code = "BR";
                //读取区域
                if (!parm.ContainsKey("Code"))
                {
                    switch (t)
                    {
                    case Class.TypeUse.TypeList.Boolean:
                        parm.Add("Code", "M");
                        code = "BR";
                        break;

                    case Class.TypeUse.TypeList.String:
                    case Class.TypeUse.TypeList.UShort:
                    case Class.TypeUse.TypeList.Int:
                    case Class.TypeUse.TypeList.Long:
                    case Class.TypeUse.TypeList.Byte:
                    case Class.TypeUse.TypeList.Float:
                    case Class.TypeUse.TypeList.Double:
                        parm.Add("Code", "D");
                        code = "WR";
                        break;
                    }
                }
                else
                {
                    switch (t)
                    {
                    case Class.TypeUse.TypeList.Boolean:
                        if (parm["Code"].ToUpper() != "X" && parm["Code"].ToUpper() != "M" && parm["Code"].ToUpper() != "Y")
                        {
                            All.Class.Error.Add("读取参数中区域类型和返回数据类型不一致", Environment.StackTrace);
                            return(false);
                        }
                        code = "BR";
                        break;

                    case Class.TypeUse.TypeList.String:
                    case Class.TypeUse.TypeList.UShort:
                    case Class.TypeUse.TypeList.Int:
                    case Class.TypeUse.TypeList.Long:
                    case Class.TypeUse.TypeList.Byte:
                    case Class.TypeUse.TypeList.Float:
                    case Class.TypeUse.TypeList.Double:
                        if (parm["Code"].ToUpper() != "D")
                        {
                            All.Class.Error.Add("读取参数中区域类型和返回数据类型不一致", Environment.StackTrace);
                        }
                        code = "WR";
                        break;
                    }
                }
                //读取长度
                int readCount = end - tmpAddress + 1;
                if (parm["Code"].ToUpper() == "X" || parm["Code"].ToUpper() == "Y")
                {
                    try
                    {
                        readCount = Convert.ToInt16(string.Format("{0}", tmpAddress), 8) - Convert.ToInt16(string.Format("{0}", end), 8) + 1;
                    }
                    catch
                    {
                        All.Class.Error.Add(string.Format("读取参数中,读取地址错误,读取的地址{0}或结束的地址{1}不是8进制数", tmpAddress, end), Environment.StackTrace);
                        return(false);
                    }
                }
                //返回长度
                int len = 6 + readCount + (check ? 2 : 0) + (crlf ? 2 : 0);
                if (parm["Code"].ToUpper() == "D")
                {
                    len = 6 + readCount * 4 + (check ? 2 : 0) + (crlf ? 2 : 0);
                }
                List <byte> sendBuff = new List <byte>();
                sendBuff.Add(0x05);
                sendBuff.AddRange(Encoding.ASCII.GetBytes(string.Format("{0:X2}", address)));
                sendBuff.AddRange(Encoding.ASCII.GetBytes(string.Format("{0:X2}", 0xFF)));
                sendBuff.AddRange(Encoding.ASCII.GetBytes(string.Format("{0}", code)));
                sendBuff.AddRange(Encoding.ASCII.GetBytes(string.Format("{0:X1}", delay)));
                sendBuff.AddRange(Encoding.ASCII.GetBytes(string.Format("{0}", parm["Code"].ToUpper())));
                sendBuff.AddRange(Encoding.ASCII.GetBytes(string.Format("{0:X4}", tmpAddress)));
                sendBuff.AddRange(Encoding.ASCII.GetBytes(string.Format("{0:X2}", readCount)));
                if (check)
                {
                    sendBuff.AddRange(Encoding.ASCII.GetBytes(string.Format("{0:X2}", All.Class.Check.SumCheck(sendBuff.ToArray(), 1, sendBuff.Count - 1))));
                }
                if (crlf)
                {
                    sendBuff.Add(0x0D);
                    sendBuff.Add(0x0A);
                }
                byte[] readBuff;
                if (WriteAndRead <byte[], byte[]>(sendBuff.ToArray(), len, out readBuff))
                {
                    if (readBuff[0] != sendBuff[0] || readBuff[1] != sendBuff[1] || readBuff[2] != sendBuff[2] || readBuff[3] != sendBuff[3] || readBuff[4] != sendBuff[4])
                    {
                        All.Class.Error.Add("读取参数帧头或帧尾校验失败", Environment.StackTrace);
                        All.Class.Error.Add(string.Format("读取帧为:{0}", All.Class.Num.Hex2Str(readBuff)));
                        return(false);
                    }
                    switch (parm["Code"].ToUpper())
                    {
                    case "X":
                    case "Y":
                    case "M":
                        for (int i = 0; i < readCount; i++)
                        {
                            value.Add((T)(object)(readBuff[5 + i] == 0x31));
                        }
                        break;

                    case "D":
                        switch (t)
                        {
                        case Class.TypeUse.TypeList.String:
                            value.Add((T)(object)Encoding.ASCII.GetString(readBuff, 5, readCount * 4));
                            break;

                        case Class.TypeUse.TypeList.Byte:
                            for (int i = 0; i < readCount * 4; i++)
                            {
                                value.Add((T)(object)readBuff[5 + i]);
                            }
                            break;

                        case Class.TypeUse.TypeList.Double:
                            if ((readCount % 4) != 0)
                            {
                                All.Class.Error.Add("Fxplc读取双精度浮点数时,必须一次读4个D点");
                                return(false);
                            }
                            for (int i = 0; i < readCount; i++)
                            {
                                value.Add((T)(object)BitConverter.ToDouble(All.Class.Num.Str2Hex(Encoding.ASCII.GetString(readBuff, 5 + i * 16, 16)), 0));
                            }
                            break;

                        case Class.TypeUse.TypeList.Float:
                            if ((readCount % 2) != 0)
                            {
                                All.Class.Error.Add("Fxplc读取单精度浮点数时,必须一次读2个D点");
                                return(false);
                            }
                            for (int i = 0; i < readCount; i++)
                            {
                                value.Add((T)(object)BitConverter.ToDouble(All.Class.Num.Str2Hex(Encoding.ASCII.GetString(readBuff, 5 + i * 8, 8)), 0));
                            }
                            break;

                        case Class.TypeUse.TypeList.Int:
                            int tmpInt = 0;
                            for (int i = 0; i < readCount; i++)
                            {
                                tmpInt = (Convert.ToInt32(Encoding.ASCII.GetString(readBuff, 5 + i * 4, 2), 16) << 8) + (Convert.ToInt32(Encoding.ASCII.GetString(readBuff, 7 + i * 4, 2), 16));
                                if ((tmpInt & 0x8000) == 0x8000)
                                {
                                    tmpInt = -((tmpInt ^ 0xFFFF) + 1);
                                }
                                value.Add((T)(object)tmpInt);
                            }
                            break;

                        case Class.TypeUse.TypeList.Long:
                            for (int i = 0; i < readCount; i++)
                            {
                                value.Add((T)(object)(long)((Convert.ToInt32(Encoding.ASCII.GetString(readBuff, 5 + i * 4, 2), 16) << 8) + (Convert.ToInt32(Encoding.ASCII.GetString(readBuff, 7 + i * 4, 2), 16))));
                            }
                            break;

                        case Class.TypeUse.TypeList.UShort:
                            for (int i = 0; i < readCount; i++)
                            {
                                value.Add((T)(object)(ushort)((Convert.ToInt32(Encoding.ASCII.GetString(readBuff, 5 + i * 4, 2), 16) << 8) + (Convert.ToInt32(Encoding.ASCII.GetString(readBuff, 7 + i * 4, 2), 16))));
                            }
                            break;
                        }
                        break;

                    default:
                        throw new Exception("Error");
                    }
                }
                else
                {
                    result = false;
                }
                return(result);
            }
        }