1、安裝依賴(lài)包
System.IO.Ports
2、讀協(xié)議
/// <summary>
/// Modbus-RTU協(xié)議讀實(shí)例
/// </summary>
private static void Read()
{
//組裝一個(gè)請(qǐng)求報(bào)文
// 01 03 00 00 00 0A C5 CD
byte slave = 0x01;
//byte function = 0x03; //讀單個(gè)寄存器
byte function = 0x01; //讀單個(gè)線(xiàn)圈狀態(tài)
int startAddress = 0;
int length = 10;
List<byte> bytes = new List<byte>();
bytes.Add(slave);
bytes.Add(function);
bytes.Add(BitConverter.GetBytes(startAddress)[1]);
bytes.Add(BitConverter.GetBytes(startAddress)[0]);
bytes.Add(BitConverter.GetBytes(length)[1]);
bytes.Add(BitConverter.GetBytes(length)[0]);
//CRC校驗(yàn)
bytes = CRC16(bytes);
//組裝好了進(jìn)行串口通信
SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
serialPort.Open();
//向從站發(fā)送請(qǐng)求
serialPort.Write(bytes.ToArray(), 0, bytes.Count);
Task.Run(async () =>
{
await Task.Delay(100);
byte[] buffer = new byte[serialPort.BytesToRead];
serialPort.DiscardInBuffer();
List<byte> bufferList = new List<byte>(buffer);
bufferList.RemoveAt(0);
bufferList.RemoveAt(0);
bufferList.RemoveAt(0);
bufferList.RemoveAt(bufferList.Count - 1);
bufferList.RemoveAt(bufferList.Count - 1);
//讀寄存器
//for(int i = 0; i < bufferList.Count; i++)
//{
// List<byte> valueList = new List<byte>();
// valueList.Add(bufferList[i]);
// valueList.Add(bufferList[++i]);
// valueList.Reverse();
// ushort value=BitConverter.ToUInt16(valueList.ToArray(), 0);
// Console.WriteLine(value);
//}
//讀線(xiàn)圈 09 00
bufferList.Reverse();
var values = string.Join("", bufferList.Select(x => Convert.ToString(x, 2).PadLeft(8, '0')).ToList()).ToList();
values.Reverse();
for (int i = 0; i < values.Count; i++)
{
Console.WriteLine(Convert.ToBoolean(int.Parse(values[i].ToString())));
}
});
}
3、寫(xiě)協(xié)議文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-615777.html
/// <summary>
/// Modbus-RTU協(xié)議寫(xiě)實(shí)例
/// </summary>
private static void Write()
{
//組裝報(bào)文
byte slave = 0x01;
//byte function = 0x05; //寫(xiě)單個(gè)線(xiàn)圈狀態(tài)
byte function = 0x06; //寫(xiě)單個(gè)寄存器
int startAddress = 0;
bool value = false;
int iv = 123;
List<byte> bytes = new List<byte>();
bytes.Add(slave);
bytes.Add(function);
bytes.Add(BitConverter.GetBytes(startAddress)[1]);
bytes.Add(BitConverter.GetBytes(startAddress)[0]);
//單線(xiàn)圈的寫(xiě)入
//bytes.Add(value ? (byte)0xFF : (byte)0x00);
//bytes.Add(0x00);
//單寄存器寫(xiě)入
bytes.Add(BitConverter.GetBytes(iv)[1]);
bytes.Add(BitConverter.GetBytes(iv)[0]);
//CRC校驗(yàn)
bytes = CRC16(bytes);
SerialPort serialPort = new SerialPort("COM1", 9600, Parity.None, 8, StopBits.One);
serialPort.Open();
//向從站發(fā)送請(qǐng)求
serialPort.Write(bytes.ToArray(), 0, bytes.Count);
//接收后如果報(bào)文一致,說(shuō)明發(fā)送請(qǐng)求成功
}
4、CRC16校驗(yàn)文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-615777.html
/// <summary>
/// CRC-16校驗(yàn)
/// </summary>
/// <param name="value"></param>
/// <param name="poly"></param>
/// <param name="crcInit"></param>
/// <returns></returns>
/// <exception cref="ArgumentException"></exception>
private static List<byte> CRC16(List<byte> value,ushort poly=0xA001,ushort crcInit=0xFFFF)
{
if (value == null || !value.Any())
throw new ArgumentException("");
//運(yùn)算
ushort crc = crcInit;
for(int i=0; i<value.Count; i++)
{
crc = (ushort)(crc ^ value[i]);
for(int j=0; j<8; j++)
{
crc=(crc&1)!=0?(ushort)((crc>>1)^poly):(ushort)(crc>>1);
}
}
byte hi = (byte)((crc & 0xFF00) >> 8);
byte lo=(byte)(crc & 0xFF);
List<byte> buffer = new List<byte>();
buffer.AddRange(value);
buffer.Add(lo);
buffer.Add(hi);
return buffer;
}
到了這里,關(guān)于Modbus-RTU協(xié)議C#實(shí)現(xiàn)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!