三菱
三菱的是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)); // 06if (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;}}