一、SerialPort
参考:https://www.cnblogs.com/qyhe/articles/8590968.html
1.通过System.IO.Ports.SerialPort.GetPortNames() 将获得系统所有的串口名称,C#代码如下,
string[] sPorts = SerialPort.GetPortNames(); //刷新端口选择,获取端口名称
Array.Sort(sPorts);
if (sPorts.Count() != 0)
{
foreach (string str in sPorts)
{
hoose_ports.Items.Add(str);//列出所有的串口
}
}//此时,端口没有打开
///serialPort.Open();//是端口打开的语句
2.打开和关闭串口
SerialPort port = new SerialPort(ports[choose_ports.SelectedIndex], 9600, Parity.None, 8); //设置串口串口号、波特率、校验位、数据位
//或者设置成
//SerialPort port = new SerialPort();
//port.BaudRate = 9600;//波特率 //9600的波特率的信道,理论上每秒可以传输9600个二进制位,也就是9600/8个英文字母的数据量,也就是1200个字节
//port.PortName = "COM1";
//port.Parity = Parity.None;//校验法:无
//port.DataBits = 8;//数据位:8
//port.StopBits = StopBits.One;//停止位:1
try
{
port.ReceivedBytesThreshold = 1;//串口输入缓冲区获得新数据后,将检查缓冲区内已有的字节数,大于等于ReceivedBytesThreshold就会触发DataReceived事件
port.DataReceived += port_DataReceived; //注册串口监听事件
port.Open();//打开串口
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
if (port.IsOpen)//表示串口被占用
{
port.Close();//关闭串口
}
3.DataReceived事件
private List<byte> buffer = new List<byte>(); //缓存串口数组
void port_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
int nRead = port.BytesToRead;
if (nRead > 0)
{
byte[] data = new byte[nRead];
port.Read(data, 0, nRead);
buffer.AddRange(data);
}
}
回调函数port_DataReceived用于响应DataReceived事件,通常在这个函数里读取串口数据。回调函数是被一个多线程调用的,它不在主线程内。所以,不要在这个回调函数里直接访问界面控件。可以使用Invoke或BeginInvoke。
4.流控制
串行通讯的双方,如果有一方反应较慢,另一方不停的发送数据,就可能造成数据的丢失。为了防止这种情况,需要使用流控制(也叫握手)
5.写数据
void Write(byte[] buffer,int offset,int count);//写二进制数据
void Write(char[] buffer,int offset,int count);//写二进制数据
void Write(string text);//写文本数据
void WriteLine(string text);//写一行数据
Modbus,TCP/IP,RS232,RS485,ModbusRTU和ModbusTCP的区别
Modbus是一种协议,必须要有硬件为实现平台,而不同的硬件平台具有不同的电气特性和连接方式,,它既可以使用RS232、RS484作为物理层,他们需要用URAT作为链路层对物理层进行指挥,也可以用Ethernet定义的物理层、链路层,使用Ethernet时则配合TCP、IP分别作为传输层和网络层。
ModbusRTU和ModbusTCP两个协议的本质都是MODBUS协议,但所用的硬件接口不一样,Modbus RTU一般采用串口RS232C或RS485/422,而Modbus TCP一般采用以太网口。