C#-Winform-上位机-串口
C#上位机-串口
一、界面搭建
二、 初始化ComboBox组件
2.1 波特率
添加初始值
public void InitBaudrate()
{
string[] bauds = new string[] {"4800", "9600", "14400", "19200"};
foreach (string s in bauds)
{
cbBaudRate.Items.Add(s);
}
cbBaudRate.SelectedIndex = 1; //默认选择下拉框的位置,“9600”
}
2.2 串口号
串口的主要通信主要需要using System.IO.Ports;
SerialPort类中提供了几乎所用串口通讯所使用的方法:
- 构造方法:
// portName:
// 要使用的端口(例如 COM1)。
// baudRate:
// 波特率。
// parity:
// System.IO.Ports.SerialPort.Parity 值之一。
// dataBits:
// 数据位值。
// stopBits:
// System.IO.Ports.SerialPort.StopBits 值之一。
public SerialPort(string portName);
public SerialPort(string portName, int baudRate);
public SerialPort(string portName, int baudRate, Parity parity);
public SerialPort(string portName, int baudRate, Parity parity, int dataBits);
public SerialPort(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits);
- 常用方法:
//获取串口号
public static string[] GetPortNames();
//关闭串口
public void Close();
//打开串口
public void Open();
//从 System.IO.Ports.SerialPort 输入缓冲区读取一些字节并将那些字节写入字节数组中指定的偏移量处。
public int Read(byte[] buffer, int offset, int count);
//使用缓冲区中的数据将指定数量的字节写入串行端口。
public void Write(byte[] buffer, int offset, int count);
- 实例:
public void InitSerialPorts()
{
string[] ports = SerialPort.GetPortNames();
foreach(string s in ports)
{
cbPortsNumber.Items.Add(s);
}
cbPortsNumber.SelectedIndex = 1;
}
三、按钮点击事件
3.1 连接按钮
private SerialPort serialPort = new SerialPort();
private void btnConnect_Click(object sender, EventArgs e)
{
serialPort = new SerialPort();
string port = cbPortsNumber.SelectedItem.ToString();
int baud = int.Parse(cbBaudRate.SelectedItem.ToString());
serialPort.PortName = port;
serialPort.BaudRate = baud;
serialPort.Open();
MessageBox.Show("连接成功");
}
private void btnDisconnect_Click(object sender, EventArgs e)
{
serialPort.Close();
MessageBox.Show("断开成功");
}
3.2 断开按钮
private void btnDisconnect_Click(object sender, EventArgs e)
{
serialPort.Close();
MessageBox.Show("断开成功");
}
四、数据收发
4.1 数据接收
- 定义一个接收数据的方法
serialPort_DataReceived
private static void serialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
pass
}
- 将
serialPort_DataReceived
加入串口数据异步接收
if (serialPort.IsOpen)
{
serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);
}
- 定义一个委托
public delegate void ReadAndRevice(string strContent);
public static ReadAndRevice readAndRevice = null;
- 实现数据的读取
public static string ReadData()
{
int bytesToRead = serialPort.BytesToRead;
byte[] reviceData = new byte[bytesToRead];
serialPort.Read(reviceData, 0, bytesToRead);
string res = Encoding.UTF8.GetString(reviceData);
return res;
}
- 页面刷新
string str = string.Empty;
private void CanRead(string strRes)
{
str = strRes;
this.Invoke(new Action(() =>{
txtRecive.Text += str;
}));
}
具体流程:
结果:
4.2 数据发送
private void btnSend_Click(object sender, EventArgs e)
{
string data = txtSend.Text.ToString();
byte[] btData = Encoding.UTF8.GetBytes(data);
byte[] sendData = new byte[btData.Length + 1];
btData.CopyTo(sendData, 0);
sendData[sendData.Length - 1] = (byte)10;
serialPort.Write(sendData, 0, sendData.Length);
}
五、扩展-实时监控串口插拔
5.1 监听设备的插拔
//事件代码
public const int WM_DEVICE_CHANGE = 0x219;
public const int DBT_DEVICEARRIVAL = 0x8000;
public const int DBT_DEVICE_REMOVE_COMPLETE = 0x8004;
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == WM_DEVICE_CHANGE) // 捕获USB设备的拔出消息WM_DEVICECHANGE
{
switch (m.WParam.ToInt32())
{
case DBT_DEVICE_REMOVE_COMPLETE: // USB拔出
{
new Thread(
new ThreadStart(
new Action(() =>
{
//更新串口
getPortDeviceName();
})
)
).Start();
}
break;
case DBT_DEVICEARRIVAL: // USB插入获取对应串口名称
{
new Thread(
new ThreadStart(
new Action(() =>
{
getPortDeviceName();
})
)
).Start();
}
break;
}
}
}
5.2 更新串口
//更新串口号
private void getPortDeviceName()
{
port = null;
string[] ports = SerialPort.GetPortNames();
this.Invoke(new Action(() =>{
cbPortsNumber.Items.Clear();
foreach (string com in ports)
{
cbPortsNumber.Items.Add(com);
}
cbPortsNumber.SelectedIndex = 0;
}));
}
结果: