三菱
三菱的是422的只能用编程口通讯,只能用编程口协议。
波特率:9600数据位位数:7位停止位位数:1位数据校验方式: 偶校验
* D0: 1000 2000 3000 频率
* M0: 电机正转 true 、false
* M1:电机反转 true 、false
报文基本格式
FX PLC的数据注意包括`D寄存器(每个寄存器二字节长)、M(位地址)、S(位地址)、T(位地址)、C(位地址)、X(位地址)、Y(位地址)`
数据帧的基本格式如下
> 需要注意的是,除了控制码之外的其他数据帧,都需要将其转换位对应的ASCII编码值进行发送
> 如:1 => 0x31 或者 30 => 0x33 0x30 123 => 0x31 0x32 0x33
和校验
发送的报文最后两位为和校验,和校验计算反射为`命令码 + 元件地址 + 数据 + 0x03`,计算结果取后两位转换ascii码
计算: https://www.23bei.com/tool/8.html
C#代码实现
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.serialPort1.Open();
}
/// <summary>
/// 写入
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
// D123区写入258数据
// 123*2+0x1000 --> 10F6 --> 16进制ascii值 成
// 258 --> 16进制0102 --> 小端0201 --> 16进制ascii值 30h 32h 30h 31h
// 请求帧字节数组
// 31h + 31h + 30h + 46h +30h + 32h +30h + 31h + 03
// 16进制ascii值: 02 | 31h | 31h 30h 46h 36h 30h 32h 30h 32h 30h 31h | 03 |
byte[] bs = new byte[] {02,49,49,48,70,54,48,50,48,50,48,49,03,51,54 };
this.serialPort1.Write(Encoding.ASCII.GetString(bs));
}
/// <summary>
/// 读取
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button2_Click(object sender, EventArgs e)
{
byte[] bs = new byte[] {02,48,49,48,70,54,48,52,03,55,52};
this.serialPort1.Write(Encoding.ASCII.GetString(bs));
}
/// <summary>
/// 置位
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button3_Click(object sender, EventArgs e)
{
// 置位
byte[] bs = new byte[] {02,55,48,49,48,56,03,48,51};
this.serialPort1.Write(Encoding.ASCII.GetString(bs));
}
/// <summary>
/// 复位
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button4_Click(object sender, EventArgs e)
{
// 复位
byte[] bs = new byte[] { 02, 56, 48, 49, 48, 56, 03, 56, 52 };
this.serialPort1.Write(Encoding.ASCII.GetString(bs));
}
/// <summary>
/// 接收接口消息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
// 读取响应
byte[] data = new byte[this.serialPort1.BytesToRead];
this.serialPort1.Read(data, 0, data.Length);
Console.WriteLine(BitConverter.ToString(data)); // 06
if (data.Length == 1 )
{
if (data[0] == 6)
{
MessageBox.Show("写入成功");
}
else
{
MessageBox.Show("写入失败");
}
}
else // 读取操作
{
MessageBox.Show(GetResult(data)+"");
}
}
private uint GetResult(byte[] data)
{
byte[] array = new byte[(data.Length - 4)/2]; // 响应帧里面数据的长度
for (int i = 0;i< array.Length; i++) // 0 1 2 3
{
byte[] bs = new byte[2]
{
data[i*2+1],
data[i*2+2],
};
array[i] = Convert.ToByte(Encoding.ASCII.GetString(bs), 16);
}
var value = BitConverter.ToUInt16(array, 0);
return value;
}
}