0.png (3.36 KB, 下載次數: 156)
下載附件
2019-7-25 18:15 上傳
單片機源程序如下:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.IO.Ports;
- using System.Windows;
- using System.Threading;
- namespace FX3GModbusAPI
- {
- public class FX3GModbusAPI
- {
- public struct Type
- {
- //FX3G
- public static string Y = "3300"; //Y元件的定義
- public static string X = "3400"; //X元件的定義
- public static string S = "2000"; //S元件的定義
- public static string M = "0000"; //M元件的定義
- public static string TS = "3000"; //TS位元件的定義
- public static string MR = "1E00"; //M8000~M8511字元件的定義
- public static string CS = "3200"; //CS位元件的定義
- public static string D = "0000"; //D0~D7999
- public static string WD = "1F40"; //D8000~D8511
- }
- public enum SoftElemType
- {
- //FX3G
- Y,
- X,
- S,
- M,
- TS,
- MR,
- CS,
- D,
- WD,
- }
-
- public struct FunctionName
- {
- public static string Read_線圈 = "01";//可多點
- public static string Read_輸入 = "02";//可多點
- public static string Read_保持寄存器 = "03";//可多點
- public static string Read_輸入寄存器 = "04";//可多點
- public static string Write_線圈寫入 = "05";//僅一點
- public static string Write_寄存器寫入 = "06";//僅一點
- public static string Write_批量線圈寫入 = "0F";//多點線圈寫入
- public static string Write_批量寄存器寫入 = "10";//多點保持寄存器寫入
- }
- public SerialPort port;
- // private StringBuilder myCompleteMessage = new StringBuilder();//避免在事件處理方法中反復的創建,定義到外面。
-
- public string STATE;
- public string myCompleteMessage;
-
- public int FX3G_Write_Soft_Elem(SoftElemType eType, int nStartAddr, int nCount, byte[] pValue, int nNetId = 0)
- {
-
- try
- {
- Addr = "";
- senddata = "";
- value = "";
-
- //num = 0;
- switch (eType)
- {
- case (SoftElemType.Y):
- for (int i = 0; i < pValue.Length; i++)
- value += string.Format("{0:x2}", pValue[i]);
- Addr = Convert.ToString(nStartAddr + Convert.ToInt16(Type.Y.ToString(), 16), 16);
- if (nCount == 1)
- senddata = string.Format("{0:x2}{1}{2}", FunctionName.Write_線圈寫入, Addr.PadLeft(4, '0'), value.PadLeft(4, '0'));
- else senddata = string.Format("{0:x2}{1}{2}{3}{4}", FunctionName.Write_批量線圈寫入, Addr.PadLeft(4, '0'), Convert.ToString(nCount, 16).PadLeft(4, '0'), Convert.ToString((nCount - 1) / 8 + 1, 16).PadLeft(4, '0'), value);
- Write_port(senddata);
- myCompleteMessage = myCompleteMessage.Replace(" ", "");
- if (Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x05 && Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x0F) return -1;
- break;
- case (SoftElemType.M):
- for (int i = 0; i < pValue.Length; i++)
- value += string.Format("{0:x2}", pValue[i]);
- Addr = Convert.ToString(nStartAddr + Convert.ToInt16(Type.M.ToString(), 16), 16);
- int len = nCount / 8;
- if (nCount % 8 != 0)
- {
- len += 1;
- }
- if (nCount == 1) senddata = string.Format("{0:x2}{1}{2}", FunctionName.Write_線圈寫入, Addr.PadLeft(4, '0'), value.PadLeft(4, '0'));
- else senddata = string.Format("{0:x2}{1}{2}{3}{4}", FunctionName.Write_批量線圈寫入, Addr.PadLeft(4, '0'), Convert.ToString(nCount, 16).PadLeft(4, '0'), Convert.ToString(len, 16).PadLeft(2, '0'), value);
-
- Write_port(senddata);
-
-
- myCompleteMessage = myCompleteMessage.Replace(" ", "");
- if (Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x05 && Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x0F) return -1;
-
- break;
- case (SoftElemType.D):
- for (int i = 0; i < pValue.Length; i++)
- value += string.Format("{0:x2}", pValue[i]);
- Addr = Convert.ToString(nStartAddr + Convert.ToInt16(Type.M.ToString(), 16), 16);
- if (nCount == 1) senddata = string.Format("{0:x2}{1}{2}", FunctionName.Write_寄存器寫入, Addr.PadLeft(4, '0'), value.PadLeft(4, '0'));
- else senddata = string.Format("{0:x2}{1}{2}{3}{4}", FunctionName.Write_批量寄存器寫入, Addr.PadLeft(4, '0'), Convert.ToString(nCount, 16).PadLeft(4, '0'), Convert.ToString(2 * nCount, 16).PadLeft(2, '0'), value);
- Write_port(senddata);
- myCompleteMessage = myCompleteMessage.Replace(" ", "");
- if (Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x06 && Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x10) return -1;
- break;
- case (SoftElemType.WD):
- for (int i = 0; i < pValue.Length; i++)
- value += string.Format("{0:x2}", pValue[i]);
- Addr = Convert.ToString(nStartAddr + Convert.ToInt16(Type.M.ToString(), 16), 16);
- senddata = string.Format("{0:x2}{1}{2}{3}{4}", FunctionName.Write_批量寄存器寫入, Addr.PadLeft(4, '0'), Convert.ToString(nCount, 16).PadLeft(4, '0'), Convert.ToString(2 * nCount, 16).PadLeft(2, '0'), value);
- Write_port(senddata);
- myCompleteMessage = myCompleteMessage.Replace(" ", "");
- if (Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x06 && Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x10) return -1;
- break;
- default:
- return -1;
- }
- }
- catch
- {
- return -1;
- }
- return 1;
-
- }
- string Addr = "";
- string senddata = "";
- string value = "";
- // int num = 0;
- object locker1 = new object();
- public int FX3G_Read_Soft_Elem(SoftElemType eType, int nStartAddr, int nCount, byte[] pValue, int nNetId = 0)
- {
- Addr = "";
- senddata = "";
- value = "";
-
-
- // num = 0;
- try
- {
- switch (eType)
- {
- case (SoftElemType.Y):
- Addr = Convert.ToString(nStartAddr + Convert.ToInt16(Type.Y.ToString(), 16), 16).PadLeft(4, '0');
- senddata = string.Format("{0:x2}{1}{2}", FunctionName.Read_線圈, Addr, Convert.ToString(nCount, 16).PadLeft(4, '0'));
- Write_port(senddata);
- myCompleteMessage = myCompleteMessage.Replace(" ", "");
- int leny = nCount / 8;
- if (nCount % 8 != 0)
- {
- leny += 1;
- }
- StringBuilder resulty = new StringBuilder(leny * 8);
- byte[] bvaluey = new byte[leny];
- if (Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x01) return -1;
- for (int i = 0; i < leny; i++)
- {
- bvaluey[i] = Convert.ToByte((myCompleteMessage.Substring(6 + 2 * i, 2)), 16);
- }
- foreach (byte b in bvaluey)
- {
- resulty.Append(Convert.ToString(b, 2).PadLeft(8, '0'));
- }
- for (int i = 0; i < leny * 8; i++)
- {
- int len1 = (i + 1) / 8;
- if ((i + 1) % 8 != 0)
- {
- len1 += 1;
- }
- pValue[i] = Convert.ToByte(resulty[8 * (2 * len1 - 1) - 1 - i].ToString(), 2);
- }
- break;
- case (SoftElemType.X):
- Addr = Convert.ToString(nStartAddr + Convert.ToInt16(Type.X.ToString(), 16), 16).PadLeft(4, '0'); ;
- senddata = string.Format("{0:x2}{1}{2}", FunctionName.Read_輸入, Addr, Convert.ToString(nCount, 16).PadLeft(4, '0'));
- Write_port(senddata);
-
- myCompleteMessage = myCompleteMessage.Replace(" ", "");
- int lenx = nCount / 8;
- if (nCount % 8 != 0)
- {
- lenx += 1;
- }
- StringBuilder resultx = new StringBuilder(lenx * 8);
- byte[] bvaluex = new byte[lenx];
- if (Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x02) return -1;
- for (int i = 0; i < lenx; i++)
- {
- bvaluex[i] = Convert.ToByte((myCompleteMessage.Substring(6 + 2 * i, 2)), 16);
- }
- foreach (byte b in bvaluex)
- {
- resultx.Append(Convert.ToString(b, 2).PadLeft(8, '0'));
- }
- for (int i = 0; i < lenx * 8; i++)
- {
- int len1 = (i + 1) / 8;
- if ((i + 1) % 8 != 0)
- {
- len1 += 1;
- }
- pValue[i] = Convert.ToByte(resultx[8 * (2 * len1 - 1) - 1 - i].ToString(), 2);
- }
- break;
-
-
- case (SoftElemType.M):
- Addr = Convert.ToString(nStartAddr + Convert.ToInt16(Type.M.ToString(), 16), 16).PadLeft(4, '0'); ;
- senddata = string.Format("{0:x2}{1}{2}", FunctionName.Read_線圈, Addr, Convert.ToString(nCount, 16).PadLeft(4, '0'));
- Write_port(senddata);
- //if (myCompleteMessage.Length < 8) return -1;
- myCompleteMessage = myCompleteMessage.Replace(" ", "");
- int len = nCount / 8;
- if (nCount % 8 != 0)
- {
- len += 1;
- }
- StringBuilder result = new StringBuilder(len * 8);
- byte[] bvalue = new byte[len];
- if (Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x01) return -1;
- for (int i = 0; i < len; i++)
- {
- bvalue[i] = Convert.ToByte((myCompleteMessage.Substring(6 + 2 * i, 2)), 16);
- }
- foreach (byte b in bvalue)
- {
- result.Append(Convert.ToString(b, 2).PadLeft(8, '0'));
- }
- for (int i = 0; i < len * 8; i++)
- {
- int len1 = (i + 1) / 8;
- if ((i + 1) % 8 != 0)
- {
- len1 += 1;
- }
- pValue[i] = Convert.ToByte(result[8 * (2 * len1 - 1) - 1 - i].ToString(), 2);
- }
- break;
- case (SoftElemType.D):
- Addr = Convert.ToString(nStartAddr + Convert.ToInt16(Type.D.ToString(), 16), 16).PadLeft(4, '0');
- senddata = string.Format("{0:x2}{1}{2}", FunctionName.Read_輸入寄存器, Addr, Convert.ToString(nCount, 16).PadLeft(4, '0'));
- Write_port(senddata);
- myCompleteMessage = myCompleteMessage.Replace(" ", "");
- if (Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x04) return -1;
- for (int i = 0; i < 2 * nCount; i = i + 2)
- {
- pValue[i] = Convert.ToByte(myCompleteMessage.ToString().Substring(6 + 2 * i, 2), 16);//高8位
- pValue[i + 1] = Convert.ToByte(myCompleteMessage.ToString().Substring(8 + 2 * i, 2), 16);//低8位
- }
- break;
- case (SoftElemType.WD):
- Addr = Convert.ToString(nStartAddr + Convert.ToInt16(Type.D.ToString(), 16), 16).PadLeft(4, '0');
- senddata = string.Format("{0:x2}{1}{2}", FunctionName.Read_輸入寄存器, Addr, Convert.ToString(nCount, 16).PadLeft(4, '0'));
- Write_port(senddata);
- myCompleteMessage = myCompleteMessage.Replace(" ", "");
- if (Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x04) return -1;
- for (int i = 0; i < 2 * nCount; i = i + 4)
- {
- pValue[i] = Convert.ToByte(myCompleteMessage.ToString().Substring(6 + 2 * i + 2, 2), 16);//低8位
- pValue[i + 1] = Convert.ToByte(myCompleteMessage.ToString().Substring(6 + 2 * i, 2), 16);//高8位
- pValue[i + 2] = Convert.ToByte(myCompleteMessage.ToString().Substring(6 + 2 * i + 6, 2), 16);//低8位
- pValue[i + 3] = Convert.ToByte(myCompleteMessage.ToString().Substring(6 + 2 * i + 4, 2), 16);//高8位
- }
- break;
- default:
- return -1;
- }
- return 1;
- }
- catch
- {
- return -1;
- }
-
- }
- object locker = new object();
- public void Write_port(string Date)
- {
-
- Date = Date.Insert(0, STATE);
- List<string> sendData16 = new List<string>();
- byte[] sendBuffer = null;
- for (int i = 0; i < Date.Length; i += 2)
- {
- sendData16.Add(Date.Substring(i, 2));
- }
- sendBuffer = new byte[sendData16.Count];
- for (int i = 0; i < sendData16.Count; i++)
- {
- sendBuffer[i] = (byte)(Convert.ToInt32(sendData16[i], 16));
- }
- byte[] star = bcrc16(sendBuffer);
- StringBuilder recBuffer16 = new StringBuilder();
- List<byte> tmp = new List<byte>(sendBuffer.Length + star.Length);
- tmp.AddRange(sendBuffer);
- tmp.AddRange(star);
- byte[] merged = tmp.ToArray();
- port.Write(merged, 0, merged.Length);
- //DateTime TF_timeh, TS_timeh;
- //TF_timeh = DateTime.Now;
- //bool cc = true;
- //while (cc)
- //{
- // TS_timeh = DateTime.Now;
- // double TDelta_t = (TS_timeh - TF_timeh).TotalMilliseconds;
- // if (TDelta_t > 1000) cc = false;
- //}
- System.Threading.Thread.Sleep(200);
-
- }
- public static byte[] bcrc16(byte[] data)
- {
- if (data.Length == 0)
- throw new Exception("調用CRC16校驗算法,(低字節在前,高字節在后)時發生異常,異常信息:被校驗的數組長度為0。");
- byte[] temdata = new byte[data.Length + 2];
- int xda, xdapoly;
- byte i, j, xdabit;
- xda = 0xFFFF;
- xdapoly = 0xA001;
- for (i = 0; i < data.Length; i++)
- {
- xda ^= data[i];
- for (j = 0; j < 8; j++)
- {
- xdabit = (byte)(xda & 0x01);
- xda >>= 1;
- if (xdabit == 1)
- xda ^= xdapoly;
- }
- }
- temdata = new byte[2] { (byte)(xda & 0xFF), (byte)(xda >> 8) };
- return temdata;
- }//crc校驗
- public void serialport_DataReceived(object sender, SerialDataReceivedEventArgs e)
- {
- lock(locker)
- {
- try
- {
- System.Threading.Thread.Sleep(50);
- int n = port.BytesToRead;//先記錄下來,避免某種原因,人為的原因,操作幾次之間時間長,緩存不一致
- if (n < 2)
- return;
- // myCompleteMessage = ""; //清除字符串構造器的內容
- ////因為要訪問ui資源,所以需要使用invoke方式同步ui。
- byte[] myReadBuffer = new byte[n];
- int numberOfBytesRead = 0;
- // Incoming message may be larger than the buffer size.
- numberOfBytesRead = port.Read(myReadBuffer, 0, myReadBuffer.Length);//讀取緩沖數據
- string[] recData = new string[myReadBuffer.Length];
- StringBuilder recBuffer16 = new StringBuilder();
- for (int i = 0; i < myReadBuffer.Length; i++)
- {
- recBuffer16.AppendFormat("{0:X2}" + " ", myReadBuffer[i]);
- recData[i] = myReadBuffer[i].ToString("X2");
- }
- myCompleteMessage = recBuffer16.ToString();
- // myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));
-
- }
- catch
- {
- return ;
- }
- }
- }
-
- public int FX3G_Read_Soft_Elem_Float(SoftElemType eType, int nStartAddr, int nCount, byte[] pValue, int nNetId = 0)
- {
-
- try
- {
- if (eType != SoftElemType.WD)
- return -1;
- Addr = Convert.ToString(nStartAddr + Convert.ToInt16(Type.D.ToString(), 16), 16).PadLeft(4, '0');
- senddata = string.Format("{0:x2}{1}{2}", FunctionName.Read_輸入寄存器, Addr, Convert.ToString(nCount, 16).PadLeft(4, '0'));
- Write_port(senddata);
- lock (locker)
- {
- myCompleteMessage = myCompleteMessage.Replace(" ", "");
-
- if (Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x04)
- return -1;
- for (int i = 0; i < 2 * nCount; i = i + 4)
- {
- pValue[i] = Convert.ToByte(myCompleteMessage.ToString().Substring(6 + 2 * i + 2, 2), 16);//低8位
- pValue[i + 1] = Convert.ToByte(myCompleteMessage.ToString().Substring(6 + 2 * i, 2), 16);//高8位
- pValue[i + 2] = Convert.ToByte(myCompleteMessage.ToString().Substring(6 + 2 * i + 6, 2), 16);//低8位
- pValue[i + 3] = Convert.ToByte(myCompleteMessage.ToString().Substring(6 + 2 * i + 4, 2), 16);//高8位
- }
- return 1;
- }
- }
- catch
- {
- return -1;
- }
-
- }
- public int FX3G_Write_Soft_Elem_Float(SoftElemType eType, int nStartAddr, int nCount, byte[] pValue, int nNetId = 0)
- {
-
- try
- {
- if (eType != SoftElemType.WD)
- return -1;
- for (int i = 0; i < pValue.Length; i++)
- value += string.Format("{0:x2}", pValue[i]);
- Addr = Convert.ToString(nStartAddr + Convert.ToInt16(Type.M.ToString(), 16), 16);
- senddata = string.Format("{0:x2}{1}{2}{3}{4}", FunctionName.Write_批量寄存器寫入, Addr.PadLeft(4, '0'), Convert.ToString(nCount, 16).PadLeft(4, '0'), Convert.ToString(2 * nCount, 16).PadLeft(2, '0'), value);
- Write_port(senddata);
- myCompleteMessage = myCompleteMessage.Replace(" ", "");
- if (Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x06 && Convert.ToByte((myCompleteMessage.Substring(2, 2)), 16) != 0x10) return -1;
- return 1;
- }
- catch
- {
- return -1;
- }
- }
-
- }
- }
復制代碼
所有資料51hei提供下載:
FX3GModbusAPI.rar
(27.5 KB, 下載次數: 237)
2019-7-25 15:33 上傳
點擊文件名下載附件
下載積分: 黑幣 -5
|