private bool CreateHighPlcInfo(List <DTPlcInfo> dAll) { if (dAll.Count > 0) { for (int i = 0; i < dAll.Count; i++) { DTPlcInfo tmpInfoHigh = new DTPlcInfo((dAll[i].RelAddr + 1), dAll[i].StrArea, dAll[i].ValueMode); tmpInfoHigh.Xuhao = -1; dAll[i].DoubleModeHigh = tmpInfoHigh; } } return(true); }
void PackCmdReadDMDataOut(DataTable dataForm0) { List <DTPlcInfo> plcInfoLst = new List <DTPlcInfo>(); List <DTPlcInfo> MPlcInfo = new List <DTPlcInfo>(); foreach (DataRow row in dataForm0.Rows) { int mAddr = 0; int count = 0; string strSplit1; string strSplit2; string DSmode; //单字还是双字 #region 获取地址 个数 区域 创建plcinfo类 并添加到集合 if (row == null) { return; } if (row["addr"].ToString() == null || row["mode"].ToString() == null || row["count"].ToString() == null) { return; } ; //添加各个单元 //取数字 用替代的字符的方法 取数组就替换字母为空 取字母就替换数字 strSplit1 = Regex.Replace(row["addr"].ToString(), "[A-Z]", "", RegexOptions.IgnoreCase); //取字母 strSplit2 = Regex.Replace(row["addr"].ToString(), "[0-9]", "", RegexOptions.IgnoreCase); DSmode = row["mode"].ToString(); if (!int.TryParse(row["count"].ToString(), out count)) { continue; } //地址超了 无效 暂且定XDM 最大69999 if (!int.TryParse(strSplit1, out mAddr) || (mAddr < 0) || (mAddr > Constant.XJMaxAddr)) { continue; } //字母大于4 无效地址 if (strSplit2.Count() > 3) { continue; } //这里数组进行统计 if (DSmode.Equals(Constant.DoubleMode) && (DTPLCPackCmdAndDataUnpack.AreaGetFromStr(strSplit2) < Constant.M_ID)) { count = count * 1; //默认都是双字了 } //传入数据起始地址 个数 区域 模式 DTPlcInfo[] tmpInfoLst = DTPLCcmd.GetPlcInfo(mAddr, count, strSplit2, DSmode); if (tmpInfoLst.Count() > 0) { plcInfoLst.AddRange(tmpInfoLst); } #endregion } #region 排序 去重复 统计DM 起始点 //排序 按照绝对地址 plcInfoLst = plcInfoLst.OrderBy(x => x.AbsAddr).ToList(); //去重复 plcInfoLst = plcInfoLst.Distinct(new ModelComparerDT()).ToList(); //分离D 区 M区 DPlcInfo = plcInfoLst.FindAll(t => t.IntArea < (Constant.HSD_ID + 1)); MPlcInfo = plcInfoLst.FindAll(t => t.IntArea > (Constant.HSD_ID)); plcInfoLst = DPlcInfo.Union(MPlcInfo).ToList <DTPlcInfo>(); #endregion #region 根据断点 建立命令的表格缓冲lst 然后创建读取DM区域的命令 //开始打包 List <int> addrLst = new List <int>(); //连续地址的起始地址 List <int> idLst = new List <int>(); //地址是D xy HSD List <int> addrcount = new List <int>(); //起始地址开始 读取几个寄存器 List <int> breakPoint = new List <int>(); //在 //首先要确定断点 breakPoint.Add(0); //获取不连续点的位置 D区域 for (int i = 0; i < plcInfoLst.Count - 1; i++) { if (((plcInfoLst[i + 1].RelAddr - plcInfoLst[i].RelAddr) > 1) || (plcInfoLst[i + 1].IntArea != plcInfoLst[i].IntArea)) { int bp = i + 1; breakPoint.Add(bp); } } breakPoint.Add(plcInfoLst.Count); //d区在前面,M区在后面 根据断点来区分 //统计D区起始地址个数 统计M区起始地址个数 //D区返回数据可以根据Dplcinfo集合来预算 //但M区需要知道M起始地址个数 for (int j = 0; j < breakPoint.Count; j++) { if (breakPoint[j] < plcInfoLst.Count) { addrLst.Add(plcInfoLst[breakPoint[j]].AbsAddr); idLst.Add(plcInfoLst[breakPoint[j]].IntArea); addrcount.Add(plcInfoLst[breakPoint[j + 1] - 1].RelAddr - plcInfoLst[breakPoint[j]].RelAddr + 1); } } //这里d区的话 需要指定一下双字情况下的 另外一个字节 //FindHighPlcInfo(DPlcInfo); //台达PLC 默认是双字 那双字 就要自己创建了 CreateHighPlcInfo(DPlcInfo); //这里M区麻烦一点 分成n个M单元组 每个单元组 有个起始地址 MPlcInfoAll = new List <List <DTPlcInfo> >(); for (int i = 0; i < addrLst.Count; i++) { List <DTPlcInfo> mplst = new List <DTPlcInfo>(); if (idLst[i] > Constant.HSD_ID) { for (int k = 0; k < addrcount[i]; k++) { DTPlcInfo p = new DTPlcInfo(); p.ValueMode = Constant.BitMode; p.ByteValue = new byte[1]; p.IntArea = idLst[i]; p.AbsAddr = addrLst[i] + k; p.Xuhao = k; mplst.Add(p); } } if (mplst.Count > 0) { MPlcInfoAll.Add(mplst); } } int mCount = 0; for (int i = 0; i < MPlcInfoAll.Count; i++) { double cntdb = (double)MPlcInfoAll[i].Count / 8; mCount = mCount + (int)Math.Ceiling(cntdb); } //dataform表格里面地址对应dplcinfo和mplcinfo的数据对应起来 FindIndexInPlcInfo(dataForm0, DPlcInfo, MPlcInfoAll); DTPLCcmd.PackSetCmdReadDDataOut(DPlcInfo); DTPLCcmd.PackSetCmdReadMDataOut(MPlcInfoAll); // DTPLCcmd.PackCmdReadDMDataOut(addrLst, idLst, addrcount, 5 + DPlcInfo.Count * 2 + mCount); #endregion addrLst = null; idLst = null; addrcount = null; breakPoint = null; }