• C# SerialPort 读写三菱FX系列PLC


    1:串口初始化

    com = new SerialPort("COM3", 9600, Parity.Even, 7, StopBits.One);

    2:打开关闭串口

     1 if (com.IsOpen)
     2 {
     3     com.Close();//关闭
     4 }
     5 
     6 com.Open();//打开

    3:C# ASCII转字符及字符转ASCII

     1 public static string Chr(int asciiCode)
     2 {
     3   if (asciiCode >= 0 && asciiCode <= 255)
     4   {
     5     System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
     6     byte[] byteArray = new byte[] { (byte)asciiCode };
     7     string strCharacter = asciiEncoding.GetString(byteArray);
     8     return (strCharacter);
     9   }
    10   else
    11   {
    12     throw new Exception("ASCII Code is not valid.");
    13   }
    14 }
    15 
    16  
    17 
    18 public static int Asc(string character)
    19 {
    20   if (character.Length == 1)
    21   {
    22     System.Text.ASCIIEncoding asciiEncoding = new System.Text.ASCIIEncoding();
    23     int intAsciiCode = (int)asciiEncoding.GetBytes(character)[0];
    24     return (intAsciiCode);
    25   }
    26   else
    27   {
    28     throw new Exception("Character is not valid.");
    29   }
    30 }

    4:写入串口的命令字符串的和校验

     1      /// <summary>
     2         /// 写入串口的命令字符串的和校验
     3         /// </summary>
     4         /// <param name="data"></param>
     5         /// <returns></returns>
     6         public string SumCheck(string data)
     7         {
     8             int sum = 0;
     9             for (int i = 0; i < data.Length; i++)
    10             {
    11                 sum += Asc(data.Substring(i, 1));
    12             }
    13 
    14             string res = sum.ToString("X");
    15             res = res.Substring(res.Length - 2, 2);
    16 
    17             return res;
    18         }

    5:写入PLC

     1      private void btnWrite_Click(object sender, EventArgs e)
     2         { 
     3             string[] write = new string[] { "2","2"}; //将准备写入PLC的值
     4             //将要写入的值转换成16进制数,补齐两个字节,注意高低字节需要交换
     5             string sWriteData = "";
     6             for (int i = 0; i < write.Length; i++)
     7             {
     8                 int val = Convert.ToInt32(write[i].Length>0?write[i]:"0");
     9                 string s = val.ToString("X");
    10                 while (s.Length<4)
    11                 {
    12                     s = "0" + s;
    13                 }
    14                 sWriteData += s.Substring(2,2)+s.Substring(0,2);
    15             }
    16 
    17             MessageBox.Show(sWriteData);
    18             //写入命令,1表示写入,1194表示D202这个地址的16进制,04表示D202,D203为4个BYTE,1194=(202*2)+4096的16进制数,至于用它表示D202的起始位置,三菱故意要这么麻烦了.
    19             sWriteData = "1119404" + sWriteData + Chr(3);
    20             //chr(2)和chr(3)是构成命令的标志字符,然后加上校验和,命令组织完成
    21             sWriteData = Chr(2) + sWriteData + SumCheck(sWriteData);
    22 
    23             MessageBox.Show(sWriteData);
    24             //写入串口
    25             com.Write(sWriteData);
    26             //byte[] data = Encoding.ASCII.GetBytes(sWriteData); 
    27             //com.Write(data,0,data.Length);
    28         }

    6:读PLC

     1       private void btnRead_Click(object sender, EventArgs e)
     2         {
     3             
     4             this.txtRead0.Clear();
     5             string sReadData = "";
     6             //在读PLC中的数据之前,需要先发个指令给它,让它将数据发送到串口,下面的字符串中,chr(2),chr(3)为PLC命令的格式标志,0119404中,0表示读,1194表示D202的起始地址,04表示读D202,D203两个字,共4个字节,66为0119404和chr(3)的校验和,向串口写入"读"命令,其实和向plc地址中写入数据是一样的,只是没有数据,用0表示读
     7             string sReadCmd = Chr(2) + "0119404" + Chr(3) + "66";
     8             com.Write(sReadCmd);
     9             //等待1秒钟
    10             System.Threading.Thread.Sleep(1000);
    11             // 从串口读数据
    12             byte[] data = new byte[1024];
    13             com.Read(data, 0, 1024);
    14 
    15            //如果首位为2,则表示数据有效.这里有个问题,在第二次读,第2位才为'2',第三次又是首位为2,需要再测试
    16             if (data[0]==2)
    17             {
    18                 string sReceiveData = System.Text.Encoding.ASCII.GetString(data);
    19                 //MessageBox.Show(sReceiveData);
    20                //解析命令,将读到的字符解析成数字,注意高低位的转换
    21                 for (int i = 1; i < 8; i += 4)
    22                 {
    23                     string sLow = sReceiveData.Substring(i,2);
    24                     string sHigh = sReceiveData.Substring(i + 2, 2);
    25                     //int res = Convert.ToInt32(sHigh)+ Convert.ToInt32(sLow);
    26                     int res = Convert.ToInt32(sHigh,16) + Convert.ToInt32(sLow,16);
    27 
    28                     this.txtRead0.Text += res.ToString() + ",";
    29                 }               
    30                 
    31             }
  • 相关阅读:
    Mac安装WineHQ
    Ubuntu 16.04下使用Wine安装文件比对工具Beyond Compare 4
    Ubuntu 16.04下安装WineHQ
    Ubuntu 16.04下使用Wine安装PowerDesigner15
    Ubuntu 16.04下使用Wine安装Windows版的微信(不太完美)
    Ubuntu 16.04下使用Wine安装Xshell 4和Xftp 4
    MySQL中数据类型(char(n)、varchar(n)、nchar(n)、nvarchar(n)的区别)(转)
    Ubuntu 16.04安装MongoDB的GUI工具RoboMongo
    Linux下Shell的快捷键(转)
    Jackson反序列化错误:com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field的解决方法
  • 原文地址:https://www.cnblogs.com/ybqjymy/p/12170688.html
Copyright © 2020-2023  润新知