Write的逻辑与上文Read设置相同,如有不清楚的请看上文C#与三菱FX2NPLC的RS232接口通讯(Read),本文用于说明Write的功能
- Write数据命令格式
02H 31H 起始地址 写入长度N 数据1.....数据N 03H 校验1 校验2
02H 代表命令开始
31H 代表写入命令
03H代表命令结束
起始地址计算方法:
ex: 读D123,D124两个点的数据
D123对应地址计算方法为:
123*2=246
246对应十六进制为F6H
Address=F6H+1000H=10F6H
故实际地址未 31H 30H 46H 36H
加入需要读取D123,D124两个地址,因为D的长度为2,所以读取长度应该为2*2=4
故长度为 30H 34H
校验计算方法为:
02H后到03H为止(包含03H)相加,然后取最后两位得到校验数据
如02H 31H 31H 30H 46H 36H 30H 34H 数据1 数据2 03H 校验1 校验2
命令每个数据由4个字节组成,格式为L1L2H1H2
假设数据1为124(D)数据2为35(D)
数据1 124(D)=7C(H)=007C(C)
命令为 37H 43H 30H 30H
数据2 35(D)=23(H)=0023(H)
命令为32H 33H 30H 30H
故实际命令如下
02H 31H 31H 30H 46H 36H 30H 34H 37H 43H 30H 30H 32H 33H 30H 30H 03H 校验1 校验2
校验位=
31H+31H+30H+46H+36H+30H+34H+37H+43H+30H+30H+32H+33H+30H+30H+03H=314H
校验1=31H 校验2=34H
最终命令
02H 31H 31H 30H 46H 36H 30H 34H 30H 30H 37H 43H 30H 30H 32H 33H 03H 31H 34H
写入成功后收到如下回复
查看实际数据
正确写入
C#代码为(配置等信息,请看上文Read部分,本文只展示写入数据部分源代码)
string[] datas = txtWriteData.Text.Split(',');
int length = Convert.ToInt32(txtLength.Text);
if (datas.Length < length)
{
MessageBox.Show("写入数据长度与操作长度不匹配,请重新操作");
return;
}
int[] wdatas = datas.Select(t => Convert.ToInt32(t)).ToArray();
byte[] buffers = new byte[length * 4 + 11];
buffers[0] = 0x02;
buffers[1] = 0x31;//30读,31写
if (txtStartAddress.Text.StartsWith("D"))
{
int addSou = Convert.ToInt32(txtStartAddress.Text.Substring(1));
if (addSou > 9999 || addSou < 0)
{
MessageBox.Show("地址范围为0-9999");
return;
}
addSou *= 2;
int addBase = 4096;//1000H对应10进制为4096
int startAdd = addBase + addSou;
string strAdd = startAdd.ToString("x8").TrimStart('0').ToUpper().PadLeft(4, '0');
buffers[2] = Convert.ToByte(strAdd[0]);
buffers[3] = Convert.ToByte(strAdd[1]);
buffers[4] = Convert.ToByte(strAdd[2]);
buffers[5] = Convert.ToByte(strAdd[3]);
}
string strLen = (length * 2).ToString("x8").TrimStart('0').ToUpper().PadLeft(2, '0');
buffers[6] = Convert.ToByte(strLen[0]);
buffers[7] = Convert.ToByte(strLen[1]);
for (int i = 0; i < length; i++)
{
string temp = wdatas[i].ToString("x8").TrimStart('0').ToUpper().PadLeft(4, '0');
//写入数据的顺序是34,12
buffers[i * 4 + 8] = Convert.ToByte(temp[2]);
buffers[i * 4 + 9] = Convert.ToByte(temp[3]);
buffers[i * 4 + 10] = Convert.ToByte(temp[0]);
buffers[i * 4 + 11] = Convert.ToByte(temp[1]);
}
buffers[buffers.Length - 3] = 0x03;
int total = 0;
for (int i = 1; i < buffers.Length - 2; i++)
{
total += Convert.ToInt32(buffers[i].ToString());
}
string cal = total.ToString("x8").TrimStart('0').ToUpper();
cal = cal.Substring(cal.Length - 2).PadLeft(2, '0');
buffers[buffers.Length - 2] = Convert.ToByte(cal[0]);
buffers[buffers.Length - 1] = Convert.ToByte(cal[1]);
sp.Write(buffers, 0, buffers.Length);
MessageBox.Show("写入成功!");
以上为使用RS232协议C#读写三菱FX2NPLC的全部设置,如有不清楚的地方,可以添加QQ1319666784交流学习