ModbusRTU.cs 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277
  1. using System;
  2. using System.IO.Ports;
  3. using System.Windows.Forms;
  4. using System.Threading;
  5. using HardwareConfig;
  6. using BaseLibRWFile;
  7. namespace BaseLibComm
  8. {
  9. public class ModbusRTU
  10. {
  11. public static ModbusRTU Ins = new ModbusRTU();
  12. //private SerialPort MyCom;//定义串口类对象
  13. //private int CurrentAddr;//定义当前通讯设备的地址
  14. //private byte[] bReceiveData = new byte[1024];//最大接受的1024个字节
  15. //private string mTempStr;
  16. //private byte ReceiveByte;
  17. private int mReceiveByteCount;
  18. //private bool bCommWell;
  19. private byte CRCHi = 0xFF;
  20. private byte CRCLo = 0xFF;
  21. //定义超时定时器 250mm
  22. private System.Timers.Timer tmrTimeOut = new System.Timers.Timer(500);//实例化Timer类,设置间隔时间为10000毫秒;
  23. //public string strErrMsg;//错误信息
  24. //public string strReceivCommandData, strSendCommandData;//定义发送及接收数据字符串
  25. //public bool RtuRunFlag = true;
  26. public long iWordStartAddr, iBitStartAddr;//保持寄存器及输出线圈的起始地址
  27. public int WordLength, iBitLen;//保持寄存器及输出线圈长度
  28. //public short[,] WordValueArray = new short[16, 256];//定义最大保持寄存器二维数组,1维表示设备站号,二维表示数据
  29. //public bool[,] BitVaueArray = new bool[16, 256];//定义输出线圈二维数组,1维表示设备站号,二维表示数据
  30. //public bool[] bComRunNomalFlag = new bool[16];//false 通讯正常 true 通讯异常 最大16个设备
  31. //public bool comBusying; //串口忙
  32. //public bool isOpend; //串口打开状态
  33. public ModbusRTU()
  34. {
  35. //MyCom = new SerialPort();
  36. //RtuRunFlag = true;
  37. //throw new System.NotImplementedException();
  38. }
  39. // LRC CHECK FROM CSDN MODIFY
  40. #region
  41. private string LRC(string strLRC)
  42. {
  43. int d_lrc = 0;
  44. string h_lrc = "";
  45. int l = strLRC.Length;
  46. for (int c = 0; c < l; c = c + 2)
  47. {
  48. string c_data = strLRC.Substring(c, 2);
  49. d_lrc = d_lrc + (Int32)Convert.ToByte(c_data, 16);
  50. //d_lrc = d_lrc + Convert.ToInt32(c_data);
  51. }
  52. if (d_lrc >= 255)
  53. d_lrc = d_lrc % 0x100;
  54. h_lrc = Convert.ToInt32(~d_lrc + 1).ToString("X");
  55. if (h_lrc.Length > 2)
  56. h_lrc = h_lrc.Substring(h_lrc.Length - 2, 2);
  57. return h_lrc;
  58. }
  59. #endregion
  60. //CRC校验 FROM Google
  61. #region
  62. private static readonly byte[] aucCRCHi = {
  63. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  64. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  65. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  66. 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  67. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  68. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  69. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  70. 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  71. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  72. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  73. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  74. 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  75. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  76. 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  77. 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  78. 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  79. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  80. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
  81. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  82. 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
  83. 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
  84. 0x00, 0xC1, 0x81, 0x40
  85. };
  86. private static readonly byte[] aucCRCLo = {
  87. 0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7,
  88. 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E,
  89. 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09, 0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9,
  90. 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC,
  91. 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
  92. 0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32,
  93. 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D,
  94. 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A, 0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38,
  95. 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF,
  96. 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
  97. 0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1,
  98. 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4,
  99. 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F, 0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB,
  100. 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA,
  101. 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
  102. 0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0,
  103. 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97,
  104. 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C, 0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E,
  105. 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89,
  106. 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
  107. 0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83,
  108. 0x41, 0x81, 0x80, 0x40
  109. };
  110. private void Crc16(byte[] pucFrame, int usLen)
  111. {
  112. int i = 0;
  113. CRCHi = 0xFF;
  114. CRCLo = 0xFF;
  115. UInt16 iIndex = 0x0000;
  116. while (usLen-- > 0)
  117. {
  118. iIndex = (UInt16)(CRCLo ^ pucFrame[i++]);
  119. CRCLo = (byte)(CRCHi ^ aucCRCHi[iIndex]);
  120. CRCHi = aucCRCLo[iIndex];
  121. }
  122. }
  123. #endregion
  124. //设置串口并打开串口
  125. public bool OpenMyCom(StSerialPort st)
  126. {
  127. try
  128. {
  129. for (int i = 0; i <= 15; i++)
  130. {
  131. SerialPortManager.DicSerialPort[st.serialPort.PortName].bComRunNomalFlag[i] = false;
  132. }
  133. //先关闭已经打开的串口
  134. if (st.serialPort.IsOpen)
  135. {
  136. st.serialPort.Close();
  137. }
  138. st.serialPort.ReceivedBytesThreshold = 1;
  139. st.serialPort.DataReceived += new SerialDataReceivedEventHandler(MyCom_DataReceived);//DataReceived事件委托
  140. //打开串口
  141. st.serialPort.Open();
  142. //设置超时定时器属性
  143. tmrTimeOut.Elapsed += new System.Timers.ElapsedEventHandler(commTimeOut);//到达时间的时候执行事件;
  144. tmrTimeOut.AutoReset = true;//设置是执行一次(false)还是一直执行(true);
  145. tmrTimeOut.Enabled = false;//是否执行System.Timers.Timer.Elapsed事件;
  146. st.comBusying = false;
  147. SerialPortManager.DicSerialPort[st.serialPort.PortName] = st;
  148. //bCommWell = false;
  149. return true;
  150. }
  151. catch (Exception ex)
  152. {
  153. string str = "Modbus串口打开失败:";
  154. Msg.Show($"{str}\r\n{ex}", $"{str}\r\nModbus serial port opening failed:\r\n{ex}",
  155. $"{str}\r\nKhông mở được cổng nối tiếp Modbus:\r\n{ex}", "Error", msgicon: MessageBoxIcon.Error);
  156. return false;
  157. }
  158. finally
  159. {
  160. }
  161. }
  162. public void CloseMyCom(StSerialPort st)
  163. {
  164. st.serialPort.Close();
  165. }
  166. //DataReceived事件委托方法 每个协议都需重写DataReceived
  167. private void MyCom_DataReceived(object sender, SerialDataReceivedEventArgs e)
  168. {
  169. try
  170. {
  171. SerialPort sp = sender as SerialPort;
  172. int i;
  173. string mTempStr;
  174. mReceiveByteCount = 0;
  175. //循环接收数据
  176. while (SerialPortManager.DicSerialPort[sp.PortName].serialPort.BytesToRead > 0)
  177. {
  178. SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[mReceiveByteCount] = (byte)SerialPortManager.DicSerialPort[sp.PortName].serialPort.ReadByte();
  179. mReceiveByteCount = mReceiveByteCount + 1;
  180. //缓冲区溢出复位
  181. if (mReceiveByteCount >= 1024)
  182. {
  183. mReceiveByteCount = 0;
  184. SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
  185. return;
  186. }
  187. }
  188. if (SerialPortManager.DicSerialPort[sp.PortName].SeriesType==SeriesTypeEnum.ModbusRTU)//RTU接受方式
  189. {
  190. //输入寄存器 功能码0x04
  191. if (mReceiveByteCount >= (WordLength * 2 + 5) && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1 && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[1] == 0x04)
  192. {
  193. mTempStr = "";
  194. for (i = 0; i < (WordLength * 2 + 5); i++)
  195. {
  196. mTempStr = mTempStr + " " + SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[i].ToString("X2");
  197. }
  198. SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
  199. SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
  200. SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
  201. SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
  202. //bCommWell = true;//通讯GOOD
  203. }
  204. //保持寄存器 功能码0x03
  205. if (mReceiveByteCount >= (WordLength * 2 + 5) && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1 && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[1] == 0x03)
  206. {
  207. mTempStr = "";
  208. for (i = 0; i < (WordLength * 2 + 5); i++)
  209. {
  210. mTempStr = mTempStr + " " + SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[i].ToString("X2");
  211. }
  212. //赋值给全局MW变量 从起始地址开始
  213. int nDownPos;
  214. nDownPos = 0;
  215. for (i = 0; i < WordLength; i++)
  216. {
  217. SerialPortManager.DicSerialPort[sp.PortName].WordValueArray[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr, nDownPos] = (Int16)(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[3 + 2 * i] * 256 + SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[3 + 2 * i + 1]);
  218. nDownPos = nDownPos + 1;
  219. }
  220. SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
  221. SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
  222. SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
  223. SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
  224. //bCommWell = true;//通讯GOOD
  225. }
  226. //输出线圈 功能码0x01
  227. if (mReceiveByteCount >= (iBitLen + 5) && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1 && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[1] == 0x01)
  228. {
  229. mTempStr = "";
  230. for (i = 0; i < (iBitLen + 5); i++)
  231. {
  232. mTempStr = mTempStr + " " + SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[i].ToString("X2");
  233. }
  234. //赋值给全局变量
  235. for (i = 0; i < SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[2]; i++)
  236. {
  237. ByteToBoolArray(SerialPortManager.DicSerialPort[sp.PortName],SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[3 + i], SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr, i * 8);
  238. }
  239. SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
  240. SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
  241. SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
  242. SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
  243. //bCommWell = true;//通讯GOOD
  244. }
  245. //输入线圈 功能码0x02
  246. if (mReceiveByteCount >= (iBitLen + 5) && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1 && SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[1] == 0x02)
  247. {
  248. mTempStr = "";
  249. for (i = 0; i < (iBitLen + 5); i++)
  250. {
  251. mTempStr = mTempStr + " " + SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[i].ToString("X2");
  252. }
  253. for (i = 0; i < SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[2]; i++)
  254. {
  255. ByteToBoolArray(SerialPortManager.DicSerialPort[sp.PortName],SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[3 + i], SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr, i * 8);
  256. }
  257. SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
  258. SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
  259. SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
  260. SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
  261. //bCommWell = true;//通讯GOOD
  262. }
  263. }
  264. else //ASCII协议解析
  265. {
  266. //保持寄存器 功能码0x03
  267. string strTmpAddr, strTmpFun;
  268. strTmpAddr = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 1, 2);
  269. strTmpFun = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 3, 2);
  270. if (SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == ':' && mReceiveByteCount >= (WordLength * 4 + 11) && strTmpAddr == (SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1).ToString("X2") && strTmpFun == "03")
  271. {
  272. mTempStr = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 0, WordLength * 4 + 11);
  273. //赋值给全局MW变量 从起始地址开始
  274. int nDownPos;
  275. nDownPos = 0;
  276. byte bTmpHi, bTmpLo;
  277. string tmpData;
  278. for (i = 0; i < WordLength; i++)
  279. {
  280. tmpData = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 7 + i * 4, 2);
  281. bTmpHi = Convert.ToByte(tmpData, 16);
  282. tmpData = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 9 + i * 4, 2);
  283. bTmpLo = Convert.ToByte(tmpData, 16);
  284. SerialPortManager.DicSerialPort[sp.PortName].WordValueArray[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr, nDownPos] = (Int16)(bTmpHi * 256 + bTmpLo);
  285. nDownPos = nDownPos + 1;
  286. }
  287. SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
  288. SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
  289. SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
  290. SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
  291. //bCommWell = true;//通讯GOOD
  292. }
  293. //输入寄存器04
  294. if (SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == ':' && mReceiveByteCount >= (WordLength * 4 + 11) && strTmpAddr == (SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1).ToString("X2") && strTmpFun == "04")
  295. {
  296. mTempStr = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 0, WordLength * 4 + 11);
  297. //赋值给全局MW变量 从起始地址开始
  298. //int nDownPos;
  299. //nDownPos = 0;
  300. //byte bTmpHi, bTmpLo;
  301. //string tmpData;
  302. //for (i = 0; i < iMWordLen; i++)
  303. //{
  304. // tmpData = System.Text.Encoding.ASCII.GetString(bData, 7 + i * 4, 2);
  305. // bTmpHi = Convert.ToByte(tmpData, 16);
  306. // tmpData = System.Text.Encoding.ASCII.GetString(bData, 9 + i * 4, 2);
  307. // bTmpLo = Convert.ToByte(tmpData, 16);
  308. // MWordVaue[CurrentAddr, nDownPos] = (UInt16)(bTmpHi * 256 + bTmpLo);
  309. // nDownPos = nDownPos + 1;
  310. //}
  311. SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
  312. SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
  313. SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
  314. SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
  315. //bCommWell = true;//通讯GOOD
  316. }
  317. //输出线圈 功能码0x01
  318. if (SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == ':' && mReceiveByteCount >= (iBitLen * 2 + 11) && strTmpAddr == (SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1).ToString("X2") && strTmpFun == "01")
  319. {
  320. byte bDataValue;
  321. string tmpData;
  322. mTempStr = "";
  323. mTempStr = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 0, iBitLen * 2 + 11);
  324. //赋值给全局变量
  325. for (i = 0; i < iBitLen; i++)
  326. {
  327. tmpData = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 7 + i * 2, 2);
  328. bDataValue = Convert.ToByte(tmpData, 16);
  329. ByteToBoolArray(SerialPortManager.DicSerialPort[sp.PortName], bDataValue, SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr, i * 8);
  330. }
  331. SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
  332. SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
  333. SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
  334. SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
  335. //bCommWell = true;//通讯GOOD
  336. }
  337. //输入线圈 功能码0x02
  338. if (SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData[0] == ':' && mReceiveByteCount >= (iBitLen * 2 + 11) && strTmpAddr == (SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr + 1).ToString("X2") && strTmpFun == "02")
  339. {
  340. //byte bDataValue;
  341. //string tmpData;
  342. mTempStr = "";
  343. mTempStr = System.Text.Encoding.ASCII.GetString(SerialPortManager.DicSerialPort[sp.PortName].byteReceiveData, 0, iBitLen * 2 + 11);
  344. ////赋值给全局变量
  345. //for (i = 0; i < iMBitLen; i++)
  346. //{
  347. // tmpData = System.Text.Encoding.ASCII.GetString(bData, 7 + i * 2, 2);
  348. // bDataValue = Convert.ToByte(tmpData, 16);
  349. // ByteToBArray(bDataValue, CurrentAddr, i * 8);
  350. //}
  351. SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = mTempStr;
  352. SerialPortManager.DicSerialPort[sp.PortName].serialPort.DiscardInBuffer();//清输入缓冲区
  353. SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = false;//通讯正常
  354. SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//本次通讯结束
  355. //bCommWell = true;//通讯GOOD
  356. }
  357. }
  358. }
  359. catch (Exception ex)
  360. {
  361. string str = "串口接收数据错误:";
  362. Msg.Show($"{str}\r\n{ex}", $"{str}\r\nSerial port receiving data error:\r\n{ex}",
  363. $"{str}\r\nCổng nối tiếp nhận dữ liệu lỗi:\r\n{ex}", "Error", msgicon: MessageBoxIcon.Error);
  364. }
  365. }
  366. // MODBUS读保持寄存器 iAddress 开始地址(0开始),iLength 寄存器数量
  367. //主站请求:01 03 00 00 00 06 70 08
  368. //地址 1字节
  369. //功能码 1字节 0x03
  370. //起始寄存器地址 2字节 0x0000~0x0005
  371. //寄存器数量 2字节 0x01~0x06
  372. //CRC校验 2字节
  373. /// <summary>
  374. /// MODBUS读保持寄存器
  375. /// </summary>
  376. /// <param name="iStation">从站站号</param>
  377. /// <param name="iAddress">开始地址</param>
  378. /// <param name="iLength">寄存器数量</param>
  379. public void ReadKeepReg(StSerialPort st, int iStation, long iAddress, int iLength, ref string str)
  380. {
  381. try
  382. {
  383. int i;
  384. iWordStartAddr = iAddress;
  385. WordLength = iLength;
  386. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);//如果前一次接收没完成,则comBusing为true,则延时250ms
  387. byte[] SendCommand = new byte[8];
  388. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  389. SendCommand[0] = (byte)iStation;
  390. SendCommand[1] = 0x03;
  391. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  392. SendCommand[3] = (byte)(iAddress % 256);
  393. SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
  394. SendCommand[5] = (byte)(iLength % 256);
  395. Crc16(SendCommand, 6);
  396. SendCommand[6] = CRCLo;
  397. SendCommand[7] = CRCHi;
  398. //发送指令。
  399. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 8);
  400. mReceiveByteCount = 0;
  401. //strUpData = "";
  402. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
  403. for (i = 0; i < 8; i++)
  404. {
  405. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
  406. }
  407. tmrTimeOut.Enabled = true;//启动超时检测定时器
  408. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  409. //bCommWell = false;//设置本次通讯标志
  410. Thread.Sleep(200);
  411. str = SerialPortManager.DicSerialPort[st.serialPort.PortName].strReceivCommandData;
  412. }
  413. catch (Exception ex)
  414. {
  415. //strErrMsg = ex.Message.ToString();
  416. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  417. }
  418. }
  419. public void ReadKeepRegAscii(StSerialPort st, int iStation, long iAddress, int iLength)
  420. {
  421. try
  422. {
  423. int i;
  424. string strLRC;
  425. string strSendCommand;
  426. iWordStartAddr = iAddress;
  427. WordLength = iLength;
  428. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  429. byte[] SendCommand = new byte[8];
  430. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  431. SendCommand[0] = (byte)iStation;
  432. SendCommand[1] = 0x03;
  433. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  434. SendCommand[3] = (byte)(iAddress % 256);
  435. SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
  436. SendCommand[5] = (byte)(iLength % 256);
  437. strSendCommand = "";
  438. for (i = 0; i < 6; i++)
  439. {
  440. strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
  441. }
  442. strLRC = LRC(strSendCommand);
  443. strSendCommand = ":" + strSendCommand + strLRC;
  444. strSendCommand = strSendCommand + "\r" + "\n";
  445. System.Diagnostics.Trace.WriteLine(strSendCommand);
  446. //发送指令。
  447. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
  448. mReceiveByteCount = 0;
  449. //strUpData = "";
  450. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
  451. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
  452. tmrTimeOut.Enabled = true;//启动超时检测定时器
  453. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  454. //bCommWell = false;//设置本次通讯标志
  455. }
  456. catch (Exception ex)
  457. {
  458. //strErrMsg = ex.Message.ToString();
  459. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  460. }
  461. }
  462. // MODBUS读输入寄存器 iAddress 开始地址(0开始),iLength 寄存器数量
  463. //主站请求:01 04 00 00 00 06 70 08
  464. //地址 1字节
  465. //功能码 1字节 0x04
  466. //起始寄存器地址 2字节 0x0000~0x0005
  467. //寄存器数量 2字节 0x01~0x06
  468. //CRC校验 2字节
  469. /// <summary>
  470. /// MODBUS读输入寄存器(三菱PLC用不到)
  471. /// </summary>
  472. /// <param name="iStation">从站站号</param>
  473. /// <param name="iAddress">开始地址</param>
  474. /// <param name="iLength">寄存器数量</param>
  475. public void ReadInputReg(StSerialPort st, int iStation, long iAddress, int iLength)
  476. {
  477. try
  478. {
  479. int i;
  480. iWordStartAddr = iAddress;
  481. WordLength = iLength;
  482. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  483. byte[] SendCommand = new byte[8];
  484. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  485. SendCommand[0] = (byte)iStation;
  486. SendCommand[1] = 0x04;
  487. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  488. SendCommand[3] = (byte)(iAddress % 256);
  489. SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
  490. SendCommand[5] = (byte)(iLength % 256);
  491. Crc16(SendCommand, 6);
  492. SendCommand[6] = CRCLo;
  493. SendCommand[7] = CRCHi;
  494. //发送指令。
  495. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 8);
  496. mReceiveByteCount = 0;
  497. //strUpData = "";
  498. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
  499. for (i = 0; i < 8; i++)
  500. {
  501. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
  502. }
  503. tmrTimeOut.Enabled = true;//启动超时检测定时器
  504. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  505. //bCommWell = false;//设置本次通讯标志
  506. }
  507. catch (Exception ex)
  508. {
  509. //strErrMsg = ex.Message.ToString();
  510. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  511. }
  512. }
  513. public void ReadInputRegAscii(StSerialPort st, int iStation, long iAddress, int iLength)
  514. {
  515. try
  516. {
  517. int i;
  518. string strLRC;
  519. string strSendCommand;
  520. iWordStartAddr = iAddress;
  521. WordLength = iLength;
  522. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  523. byte[] SendCommand = new byte[8];
  524. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  525. SendCommand[0] = (byte)iStation;
  526. SendCommand[1] = 0x04;
  527. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  528. SendCommand[3] = (byte)(iAddress % 256);
  529. SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
  530. SendCommand[5] = (byte)(iLength % 256);
  531. strSendCommand = "";
  532. for (i = 0; i < 6; i++)
  533. {
  534. strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
  535. }
  536. strLRC = LRC(strSendCommand);
  537. strSendCommand = ":" + strSendCommand + strLRC;
  538. strSendCommand = strSendCommand + "\r" + "\n";
  539. System.Diagnostics.Trace.WriteLine(strSendCommand);
  540. //发送指令。
  541. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
  542. mReceiveByteCount = 0;
  543. //strUpData = "";
  544. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
  545. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
  546. tmrTimeOut.Enabled = true;//启动超时检测定时器
  547. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  548. //bCommWell = false;//设置本次通讯标志
  549. }
  550. catch (Exception ex)
  551. {
  552. //strErrMsg = ex.Message.ToString();
  553. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  554. }
  555. }
  556. // MODBUS读输出状态 iAddress 开始地址(0开始),iLength 输出位数量
  557. //主站请求:01 01 00 00 00 07 70 08
  558. //地址 1字节
  559. //功能码 1字节 0x01
  560. //起始寄存器地址 2字节 0x0000~0x0005
  561. //寄存器数量 2字节 0x01~0x06
  562. //CRC校验 2字节
  563. /// <summary>
  564. /// MODBUS读输出线圈状态
  565. /// </summary>
  566. /// <param name="iStation">从站站号</param>
  567. /// <param name="iAddress">开始地址</param>
  568. /// <param name="iLength">输出位数量</param>
  569. public void ReadOutputStatus(StSerialPort st, int iStation, long iAddress, int iLength, ref string str)
  570. {
  571. try
  572. {
  573. int i;
  574. //一个字节代表8个位状态
  575. //一个字节代表8个位状态
  576. if (iLength % 8 == 0)
  577. {
  578. iBitLen = iLength / 8;
  579. }
  580. else
  581. {
  582. iBitLen = iLength / 8 + 1;
  583. }
  584. iBitStartAddr = iAddress;
  585. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  586. byte[] SendCommand = new byte[8];
  587. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  588. SendCommand[0] = (byte)iStation;
  589. SendCommand[1] = 0x01;
  590. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  591. SendCommand[3] = (byte)(iAddress % 256);
  592. SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
  593. SendCommand[5] = (byte)(iLength % 256);
  594. Crc16(SendCommand, 6);
  595. SendCommand[6] = CRCLo;
  596. SendCommand[7] = CRCHi;
  597. //发送指令。
  598. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 8);
  599. mReceiveByteCount = 0;
  600. //strUpData = "";
  601. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
  602. for (i = 0; i < 8; i++)
  603. {
  604. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
  605. }
  606. tmrTimeOut.Enabled = true;//启动超时检测定时器
  607. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  608. //bCommWell = false;//设置本次通讯标志
  609. Thread.Sleep(200);
  610. str = SerialPortManager.DicSerialPort[st.serialPort.PortName].strReceivCommandData;
  611. }
  612. catch (Exception ex)
  613. {
  614. //strErrMsg = ex.Message.ToString();
  615. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  616. }
  617. }
  618. public void ReadOutputStatusAscii(StSerialPort st, int iStation, long iAddress, int iLength)
  619. {
  620. try
  621. {
  622. int i;
  623. //一个字节代表8个位状态
  624. //一个字节代表8个位状态
  625. if (iLength % 8 == 0)
  626. {
  627. iBitLen = iLength / 8;
  628. }
  629. else
  630. {
  631. iBitLen = iLength / 8 + 1;
  632. }
  633. string strLRC;
  634. string strSendCommand;
  635. iBitStartAddr = iAddress;
  636. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  637. byte[] SendCommand = new byte[8];
  638. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  639. SendCommand[0] = (byte)iStation;
  640. SendCommand[1] = 0x01;
  641. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  642. SendCommand[3] = (byte)(iAddress % 256);
  643. SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
  644. SendCommand[5] = (byte)(iLength % 256);
  645. strSendCommand = "";
  646. for (i = 0; i < 6; i++)
  647. {
  648. strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
  649. }
  650. strLRC = LRC(strSendCommand);
  651. strSendCommand = ":" + strSendCommand + strLRC;
  652. strSendCommand = strSendCommand + "\r" + "\n";
  653. System.Diagnostics.Trace.WriteLine(strSendCommand);
  654. //发送指令。
  655. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
  656. mReceiveByteCount = 0;
  657. //strUpData = "";
  658. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
  659. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
  660. tmrTimeOut.Enabled = true;//启动超时检测定时器
  661. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  662. //bCommWell = false;//设置本次通讯标志
  663. }
  664. catch (Exception ex)
  665. {
  666. //strErrMsg = ex.Message.ToString();
  667. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  668. }
  669. }
  670. // MODBUS读输入状态 iAddress 开始地址(0开始),iLength 输入位数量
  671. //主站请求:01 02 00 00 00 07 70 08
  672. //地址 1字节
  673. //功能码 1字节 0x02
  674. //起始寄存器地址 2字节 0x0000~0x0005
  675. //寄存器数量 2字节 0x01~0x06
  676. //CRC校验 2字节
  677. /// <summary>
  678. /// MODBUS读输入状态
  679. /// </summary>
  680. /// <param name="iStation">从站站号</param>
  681. /// <param name="iAddress">开始地址</param>
  682. /// <param name="iLength">输入位数量</param>
  683. public void ReadInputStatus(StSerialPort st, int iStation, long iAddress, int iLength, ref string str)
  684. {
  685. try
  686. {
  687. int i;
  688. //一个字节代表8个位状态
  689. //一个字节代表8个位状态
  690. if (iLength % 8 == 0)
  691. {
  692. iBitLen = iLength / 8;
  693. }
  694. else
  695. {
  696. iBitLen = iLength / 8 + 1;
  697. }
  698. iBitStartAddr = iAddress;
  699. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  700. byte[] SendCommand = new byte[8];
  701. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  702. SendCommand[0] = (byte)iStation;
  703. SendCommand[1] = 0x02;
  704. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  705. SendCommand[3] = (byte)(iAddress % 256);
  706. SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
  707. SendCommand[5] = (byte)(iLength % 256);
  708. Crc16(SendCommand, 6);
  709. SendCommand[6] = CRCLo;
  710. SendCommand[7] = CRCHi;
  711. //发送指令。
  712. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 8);
  713. mReceiveByteCount = 0;
  714. //strUpData = "";
  715. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
  716. for (i = 0; i < 8; i++)
  717. {
  718. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
  719. }
  720. tmrTimeOut.Enabled = true;//启动超时检测定时器
  721. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  722. //bCommWell = false;//设置本次通讯标志
  723. Thread.Sleep(200);
  724. str = SerialPortManager.DicSerialPort[st.serialPort.PortName].strReceivCommandData;
  725. }
  726. catch (Exception ex)
  727. {
  728. //strErrMsg = ex.Message.ToString();
  729. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  730. }
  731. }
  732. public void ReadInputStatusAscii(StSerialPort st, int iStation, long iAddress, int iLength)
  733. {
  734. try
  735. {
  736. int i;
  737. //一个字节代表8个位状态
  738. if (iLength % 8 == 0)
  739. {
  740. iBitLen = iLength / 8;
  741. }
  742. else
  743. {
  744. iBitLen = iLength / 8 + 1;
  745. }
  746. string strLRC;
  747. string strSendCommand;
  748. iBitStartAddr = iAddress;
  749. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  750. byte[] SendCommand = new byte[8];
  751. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  752. SendCommand[0] = (byte)iStation;
  753. SendCommand[1] = 0x02;
  754. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  755. SendCommand[3] = (byte)(iAddress % 256);
  756. SendCommand[4] = (byte)((iLength - iLength % 256) / 256);
  757. SendCommand[5] = (byte)(iLength % 256);
  758. strSendCommand = "";
  759. for (i = 0; i < 6; i++)
  760. {
  761. strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
  762. }
  763. strLRC = LRC(strSendCommand);
  764. strSendCommand = ":" + strSendCommand + strLRC;
  765. strSendCommand = strSendCommand + "\r" + "\n";
  766. System.Diagnostics.Trace.WriteLine(strSendCommand);
  767. //发送指令。
  768. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
  769. mReceiveByteCount = 0;
  770. //strUpData = "";
  771. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
  772. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
  773. tmrTimeOut.Enabled = true;//启动超时检测定时器
  774. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  775. //bCommWell = false;//设置本次通讯标志
  776. }
  777. catch (Exception ex)
  778. {
  779. //strErrMsg = ex.Message.ToString();
  780. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  781. }
  782. }
  783. // MODBUS强制单线圈 iAddress 开始地址(0开始)
  784. //主站请求:01 05 00 00 FF 00 70 08
  785. //地址 1字节
  786. //功能码 1字节 0x05
  787. //起始寄存器地址 2字节 0x0000~0x0005
  788. //寄存器数量 2字节 0x01~0x06
  789. //CRC校验 2字节
  790. /// <summary>
  791. /// MODBUS强制单线圈
  792. /// </summary>
  793. /// <param name="iStation">从站站号</param>
  794. /// <param name="iAddress">开始地址</param>
  795. public void ForceOn_Circle(StSerialPort st, int iStation, long iAddress, ref string str)
  796. {
  797. try
  798. {
  799. int i;
  800. iWordStartAddr = iAddress;
  801. //iMWordLen = 0;
  802. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  803. byte[] SendCommand = new byte[8];
  804. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  805. SendCommand[0] = (byte)iStation;
  806. SendCommand[1] = 0x05;
  807. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  808. SendCommand[3] = (byte)(iAddress % 256);
  809. SendCommand[4] = 0xff;
  810. SendCommand[5] = 0x00;
  811. Crc16(SendCommand, 6);
  812. SendCommand[6] = CRCLo;
  813. SendCommand[7] = CRCHi;
  814. //发送指令。
  815. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 8);
  816. mReceiveByteCount = 0;
  817. //strUpData = "";
  818. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
  819. for (i = 0; i < 8; i++)
  820. {
  821. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
  822. }
  823. tmrTimeOut.Enabled = true;//启动超时检测定时器
  824. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  825. //bCommWell = false;//设置本次通讯标志
  826. Thread.Sleep(200);
  827. str = SerialPortManager.DicSerialPort[st.serialPort.PortName].strReceivCommandData;
  828. }
  829. catch (Exception ex)
  830. {
  831. //strErrMsg = ex.Message.ToString();
  832. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  833. }
  834. }
  835. public void ForceOnAscii(StSerialPort st, int iStation, long iAddress)
  836. {
  837. try
  838. {
  839. int i;
  840. string strSendCommand, strLRC;
  841. iWordStartAddr = iAddress;
  842. //iMWordLen = 0;
  843. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  844. byte[] SendCommand = new byte[8];
  845. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  846. SendCommand[0] = (byte)iStation;
  847. SendCommand[1] = 0x05;
  848. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  849. SendCommand[3] = (byte)(iAddress % 256);
  850. SendCommand[4] = 0xff;
  851. SendCommand[5] = 0x00;
  852. strSendCommand = "";
  853. for (i = 0; i < 6; i++)
  854. {
  855. strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
  856. }
  857. strLRC = LRC(strSendCommand);
  858. strSendCommand = ":" + strSendCommand + strLRC;
  859. strSendCommand = strSendCommand + "\r" + "\n";
  860. //System.Diagnostics.Trace.WriteLine(strSendCommand);
  861. //发送指令。
  862. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
  863. mReceiveByteCount = 0;
  864. //strUpData = "";
  865. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
  866. tmrTimeOut.Enabled = true;//启动超时检测定时器
  867. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  868. //bCommWell = false;//设置本次通讯标志
  869. }
  870. catch (Exception ex)
  871. {
  872. //strErrMsg = ex.Message.ToString();
  873. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  874. }
  875. }
  876. // MODBUS复位单线圈 iAddress 开始地址(0开始)
  877. //主站请求:01 05 00 00 00 00 70 08
  878. //地址 1字节
  879. //功能码 1字节 0x05
  880. //起始寄存器地址 2字节 0x0000~0x0005
  881. //寄存器数量 2字节 0x01~0x06
  882. //CRC校验 2字节
  883. public void ForceOff_Circle(StSerialPort st, int iStation, long iAddress, ref string str)
  884. {
  885. try
  886. {
  887. int i;
  888. iWordStartAddr = iAddress;
  889. //iMWordLen = 0;
  890. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  891. byte[] SendCommand = new byte[8];
  892. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  893. SendCommand[0] = (byte)iStation;
  894. SendCommand[1] = 0x05;
  895. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  896. SendCommand[3] = (byte)(iAddress % 256);
  897. SendCommand[4] = 0x00;
  898. SendCommand[5] = 0x00;
  899. Crc16(SendCommand, 6);
  900. SendCommand[6] = CRCLo;
  901. SendCommand[7] = CRCHi;
  902. //发送指令。
  903. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 8);
  904. mReceiveByteCount = 0;
  905. //strUpData = "";
  906. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
  907. for (i = 0; i < 8; i++)
  908. {
  909. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
  910. }
  911. tmrTimeOut.Enabled = true;//启动超时检测定时器
  912. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  913. //bCommWell = false;//设置本次通讯标志
  914. Thread.Sleep(200);
  915. str = SerialPortManager.DicSerialPort[st.serialPort.PortName].strReceivCommandData;
  916. }
  917. catch (Exception ex)
  918. {
  919. //strErrMsg = ex.Message.ToString();
  920. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  921. }
  922. }
  923. public void ForceOffAscii(StSerialPort st, int iStation, long iAddress)
  924. {
  925. try
  926. {
  927. int i;
  928. string strSendCommand, strLRC;
  929. iWordStartAddr = iAddress;
  930. //iMWordLen = 0;
  931. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  932. byte[] SendCommand = new byte[8];
  933. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  934. SendCommand[0] = (byte)iStation;
  935. SendCommand[1] = 0x05;
  936. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  937. SendCommand[3] = (byte)(iAddress % 256);
  938. SendCommand[4] = 0x00;
  939. SendCommand[5] = 0x00;
  940. strSendCommand = "";
  941. for (i = 0; i < 6; i++)
  942. {
  943. strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
  944. }
  945. strLRC = LRC(strSendCommand);
  946. strSendCommand = ":" + strSendCommand + strLRC;
  947. strSendCommand = strSendCommand + "\r" + "\n";
  948. //System.Diagnostics.Trace.WriteLine(strSendCommand);
  949. //发送指令。
  950. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
  951. mReceiveByteCount = 0;
  952. //strUpData = "";
  953. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
  954. tmrTimeOut.Enabled = true;//启动超时检测定时器
  955. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  956. //bCommWell = false;//设置本次通讯标志
  957. }
  958. catch (Exception ex)
  959. {
  960. //strErrMsg = ex.Message.ToString();
  961. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  962. }
  963. }
  964. // MODBUS预置单字寄存器 iAddress 开始地址(0开始),iHiValue 数据
  965. //主站请求:01 06 00 00 00 06 70 08
  966. //地址 1字节
  967. //功能码 1字节 0x06
  968. //起始寄存器地址 2字节 0x0000~0x0005
  969. //寄存器数量 2字节 0x01~0x06
  970. //CRC校验 2字节
  971. /// <summary>
  972. /// MODBUS预置单字寄存器
  973. /// </summary>
  974. /// <param name="iStation">从站地址</param>
  975. /// <param name="iAddress">开始地址</param>
  976. /// <param name="SetValue">值</param>
  977. public void PreSetKeepReg(StSerialPort st, int iStation, long iAddress, UInt16 SetValue, ref string str)
  978. {
  979. try
  980. {
  981. int i;
  982. iWordStartAddr = iAddress;
  983. //iMWordLen = 0;
  984. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  985. byte[] SendCommand = new byte[8];
  986. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  987. SendCommand[0] = (byte)iStation;
  988. SendCommand[1] = 0x06;
  989. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  990. SendCommand[3] = (byte)(iAddress % 256);
  991. SendCommand[4] = (byte)((SetValue - SetValue % 256) / 256); ;
  992. SendCommand[5] = (byte)(SetValue % 256); ;
  993. Crc16(SendCommand, 6);
  994. SendCommand[6] = CRCLo;
  995. SendCommand[7] = CRCHi;
  996. //发送指令。
  997. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 8);
  998. mReceiveByteCount = 0;
  999. //strUpData = "";
  1000. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
  1001. for (i = 0; i < 8; i++)
  1002. {
  1003. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
  1004. }
  1005. tmrTimeOut.Enabled = true;//启动超时检测定时器
  1006. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  1007. //bCommWell = false;//设置本次通讯标志
  1008. Thread.Sleep(200);
  1009. str = SerialPortManager.DicSerialPort[st.serialPort.PortName].strReceivCommandData;
  1010. }
  1011. catch (Exception ex)
  1012. {
  1013. //strErrMsg = ex.Message.ToString();
  1014. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  1015. }
  1016. }
  1017. public void PreSetKeepRegAscii(StSerialPort st, int iStation, long iAddress, UInt16 SetValue)
  1018. {
  1019. try
  1020. {
  1021. int i;
  1022. string strSendCommand, strLRC;
  1023. iWordStartAddr = iAddress;
  1024. //iMWordLen = 0;
  1025. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  1026. byte[] SendCommand = new byte[8];
  1027. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  1028. SendCommand[0] = (byte)iStation;
  1029. SendCommand[1] = 0x06;
  1030. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  1031. SendCommand[3] = (byte)(iAddress % 256);
  1032. SendCommand[4] = (byte)((SetValue - SetValue % 256) / 256); ;
  1033. SendCommand[5] = (byte)(SetValue % 256); ;
  1034. strSendCommand = "";
  1035. for (i = 0; i < 6; i++)
  1036. {
  1037. strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
  1038. }
  1039. strLRC = LRC(strSendCommand);
  1040. strSendCommand = ":" + strSendCommand + strLRC;
  1041. strSendCommand = strSendCommand + "\r" + "\n";
  1042. //System.Diagnostics.Trace.WriteLine(strSendCommand);
  1043. //发送指令。
  1044. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
  1045. mReceiveByteCount = 0;
  1046. //strUpData = "";
  1047. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
  1048. tmrTimeOut.Enabled = true;//启动超时检测定时器
  1049. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  1050. //bCommWell = false;//设置本次通讯标志
  1051. }
  1052. catch (Exception ex)
  1053. {
  1054. //strErrMsg = ex.Message.ToString();
  1055. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  1056. }
  1057. }
  1058. // MODBUS预置双字寄存器 iAddress 开始地址(0开始)
  1059. //主站请求:01 06 00 00 00 10 70 08
  1060. //地址 1字节
  1061. //功能码 1字节 0x10
  1062. //起始寄存器地址 2字节 0x0000~0x0005
  1063. //寄存器数量 2字节 0x01~0x06
  1064. //CRC校验 2字节
  1065. /// <summary>
  1066. /// MODBUS预置双字寄存器
  1067. /// </summary>
  1068. /// <param name="iStation">从站站号</param>
  1069. /// <param name="iAddress">开始地址</param>
  1070. /// <param name="SetValue">值</param>
  1071. public void PreSetFloatKeepReg(StSerialPort st, int iStation, long iAddress, float SetValue, ref string str)
  1072. {
  1073. try
  1074. {
  1075. int i;
  1076. byte[] bSetValue = new byte[4];
  1077. bSetValue = BitConverter.GetBytes(SetValue);
  1078. //bSetValue = &SetValue;
  1079. iWordStartAddr = iAddress;
  1080. //iMWordLen = 0;
  1081. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  1082. byte[] SendCommand = new byte[13];
  1083. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  1084. SendCommand[0] = (byte)iStation;
  1085. SendCommand[1] = 0x10;
  1086. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  1087. SendCommand[3] = (byte)(iAddress % 256);
  1088. SendCommand[4] = 0x00;
  1089. SendCommand[5] = 0x02;
  1090. SendCommand[6] = 0x04;
  1091. SendCommand[7] = bSetValue[1];
  1092. SendCommand[8] = bSetValue[0];
  1093. SendCommand[9] = bSetValue[3];
  1094. SendCommand[10] = bSetValue[2];
  1095. Crc16(SendCommand, 11);
  1096. SendCommand[11] = CRCLo;
  1097. SendCommand[12] = CRCHi;
  1098. //发送指令。
  1099. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(SendCommand, 0, 13);
  1100. mReceiveByteCount = 0;
  1101. //strUpData = "";
  1102. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = "";
  1103. for (i = 0; i < 13; i++)
  1104. {
  1105. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData + " " + SendCommand[i].ToString("X2");
  1106. }
  1107. tmrTimeOut.Enabled = true;//启动超时检测定时器
  1108. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  1109. //bCommWell = false;//设置本次通讯标志
  1110. Thread.Sleep(200);
  1111. str = SerialPortManager.DicSerialPort[st.serialPort.PortName].strReceivCommandData;
  1112. }
  1113. catch (Exception ex)
  1114. {
  1115. //strErrMsg = ex.Message.ToString();
  1116. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  1117. }
  1118. }
  1119. public void PreSetFloatKeepRegAscii(StSerialPort st, int iStation, long iAddress, float SetValue)
  1120. {
  1121. try
  1122. {
  1123. int i;
  1124. string strSendCommand, strLRC;
  1125. byte[] bSetValue = new byte[4];
  1126. bSetValue = BitConverter.GetBytes(SetValue);
  1127. //bSetValue = &SetValue;
  1128. iWordStartAddr = iAddress;
  1129. //iMWordLen = 0;
  1130. if (SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying == true) Thread.Sleep(250);
  1131. byte[] SendCommand = new byte[13];
  1132. SerialPortManager.DicSerialPort[st.serialPort.PortName].CurrentAddr = iStation - 1;
  1133. SendCommand[0] = (byte)iStation;
  1134. SendCommand[1] = 0x10;
  1135. SendCommand[2] = (byte)((iAddress - iAddress % 256) / 256);
  1136. SendCommand[3] = (byte)(iAddress % 256);
  1137. SendCommand[4] = 0x00;
  1138. SendCommand[5] = 0x02;
  1139. SendCommand[6] = 0x04;
  1140. SendCommand[7] = bSetValue[1];
  1141. SendCommand[8] = bSetValue[0];
  1142. SendCommand[9] = bSetValue[3];
  1143. SendCommand[10] = bSetValue[2];
  1144. strSendCommand = "";
  1145. for (i = 0; i < 11; i++)
  1146. {
  1147. strSendCommand = strSendCommand + SendCommand[i].ToString("X2");
  1148. }
  1149. strLRC = LRC(strSendCommand);
  1150. strSendCommand = ":" + strSendCommand + strLRC;
  1151. strSendCommand = strSendCommand + "\r" + "\n";
  1152. //System.Diagnostics.Trace.WriteLine(strSendCommand);
  1153. //发送指令。
  1154. SerialPortManager.DicSerialPort[st.serialPort.PortName].serialPort.Write(strSendCommand);
  1155. mReceiveByteCount = 0;
  1156. //strUpData = "";
  1157. SerialPortManager.DicSerialPort[st.serialPort.PortName].strSendCommandData = strSendCommand;
  1158. tmrTimeOut.Enabled = true;//启动超时检测定时器
  1159. SerialPortManager.DicSerialPort[st.serialPort.PortName].comBusying = true;//设置串口忙标志
  1160. //bCommWell = false;//设置本次通讯标志
  1161. }
  1162. catch (Exception ex)
  1163. {
  1164. //strErrMsg = ex.Message.ToString();
  1165. MessageBox.Show($"串口发送数据错误:{ex.Message }", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
  1166. }
  1167. }
  1168. //字节变量返回8为二进制字符串
  1169. /// <summary>
  1170. /// 字节变量返回8位二进制字符串
  1171. /// </summary>
  1172. /// <param name="bValue">字节变量值</param>
  1173. /// <returns></returns>
  1174. public string ByteToBinary(byte bValue)
  1175. {
  1176. string strTemp;
  1177. int i, strLen;
  1178. strTemp = System.Convert.ToString(bValue, 2);
  1179. if (strTemp.Length < 8)
  1180. {
  1181. strLen = strTemp.Length;
  1182. for (i = 0; i < 8 - strLen; i++)
  1183. {
  1184. strTemp = "0" + strTemp;
  1185. }
  1186. }
  1187. return strTemp;
  1188. }
  1189. //字节变量赋值给bool型全局数组
  1190. /// <summary>
  1191. /// 字节变量赋值给bool型全局数组
  1192. /// </summary>
  1193. /// <param name="bValue">字节变量值</param>
  1194. /// <param name="iAddr">从站地址</param>
  1195. /// <param name="pos">赋值开始数组索引值</param>
  1196. public void ByteToBoolArray(StSerialPort st, byte bValue, int iAddr, int pos)
  1197. {
  1198. string strBinary;
  1199. strBinary = ByteToBinary(bValue);
  1200. for (int i = 0; i < 8; i++)
  1201. {
  1202. if (strBinary.Substring(7 - i, 1) == "1")
  1203. {
  1204. SerialPortManager.DicSerialPort[st.serialPort.PortName].BitVaueArray[iAddr, pos + i] = true;
  1205. }
  1206. else
  1207. {
  1208. SerialPortManager.DicSerialPort[st.serialPort.PortName].BitVaueArray[iAddr, pos + i] = false;
  1209. }
  1210. }
  1211. }
  1212. //定时器超时事件
  1213. public void commTimeOut(object source, System.Timers.ElapsedEventArgs e)
  1214. {
  1215. SerialPort sp = source as SerialPort;
  1216. //if (bCommWell == false)
  1217. {
  1218. SerialPortManager.DicSerialPort[sp.PortName].bComRunNomalFlag[SerialPortManager.DicSerialPort[sp.PortName].CurrentAddr] = true;//设置本地址通讯故障
  1219. SerialPortManager.DicSerialPort[sp.PortName].strReceivCommandData = "";
  1220. }
  1221. tmrTimeOut.Enabled = false;
  1222. SerialPortManager.DicSerialPort[sp.PortName].comBusying = false;//设置串口忙标志
  1223. }
  1224. }
  1225. }