串口通信
# 串口通信
介绍
这篇随笔主要介绍串口通信.
串口通信标准一般分为:RS232和RS485
效果图(原生接口实现)
原生接口实现
1、串口打开和关闭
/// <summary>
/// 串口打开与关闭
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnOpen_Click(object sender, EventArgs e)
{
if (btnOpen.Text == "打开串口")
{
try
{
if (!com.IsOpen)
{
com.PortName = cmbPort.Text;
com.BaudRate = int.Parse(cmbBaudRate.Text);
com.DataBits = int.Parse(cmbDataBits.Text);
switch (cmbStopBits.SelectedIndex) {
case 0:
com.StopBits = StopBits.One; break;
case 1:
com.StopBits = StopBits.Two; break;
case 2:
com.StopBits = StopBits.OnePointFive; break;
case 3:
com.StopBits = StopBits.None; break;
}
switch (cmbParity.SelectedIndex)
{
case 0: com.Parity = Parity.None; break;
case 1: com.Parity = Parity.Odd; break;
case 2: com.Parity = Parity.Even; break;
}
com.Open();//打开串口
}
btnOpen.Text = "关闭串口";
txtStatus.Text = "串口已打开!";
btnSend.Enabled = true;
if (rbAck.Checked)
btnReceive.Enabled = true; //应答模式,接收按钮有效
}
catch
{ txtStatus.Text = "串口打开错误或串口不存在!"; }
}
else //关闭串口
try
{
if (com.IsOpen)
com.Close(); //关闭串口
btnOpen.Text = "打开串口";
txtStatus.Text = "串口已关闭!";
btnSend.Enabled = false ;
if (rbAck.Checked)
btnReceive.Enabled = false; //应答模式,接收按钮有效
}
catch
{ txtStatus.Text = "串口关闭错误或串口不存在!"; }
}
2、应答模式下串口接收数据
/// <summary>
/// 串口接收数据,应答模式时
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnReceive_Click(object sender, EventArgs e)
{
try
{
//应答模式
int count = com.BytesToRead;
byte[] readBuffer = new byte[count];
com.Read(readBuffer, 0, count);
if (chkRecHex.Checked)
txtReceive.Text = getStringFromBytes(readBuffer); //转十六进制
else
txtReceive.Text = Encoding.Default.GetString(readBuffer); //字母、数字、汉字转换为字符串
}
catch (Exception err)
{ txtStatus.Text = err.ToString(); }
}
3、响应模式下串口接受数据事件
/// <summary>
/// 响应模式时,串口接收数据事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void com_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
try
{
int count = com.BytesToRead;
byte[] readBuffer = new byte[count];
com.Read(readBuffer, 0, count);
string strReceive="";
if(chkRecHex.Checked)
strReceive = getStringFromBytes(readBuffer); //转十六进制
else
strReceive = Encoding.Default.GetString(readBuffer); //字母、数字、汉字转换为字符串
this.Invoke(new showReceiveDelegate(doShowReceive), strReceive);
}
catch (Exception err)
{ txtStatus.Text = err.ToString(); }
}
SerialPortLib实现
1、打开Visual Studio,在Nuget中安装SerialPortLib
2、初始化端口和注册事件
SerialPortLib.SerialPortInput serialPortInput = new SerialPortInput();
try
{
serialPortInput.SetPort("COM1", 9600, StopBits.One, Parity.None,DataBits.Eight);//初始化串口:串口名,波特率,停止位,奇偶校验,数据位
serialPortInput.Connect();
serialPortInput.ConnectionStatusChanged += SerialPortInput_ConnectStatusChange;
serialPortInput.MessageReceived += SerialPortInput_MessageReceive;
}
catch
{
MessageBox.Show("串口初始化失败");
}
3、事件方法
void SerialPortInput_ConnectStatusChange(object sender, ConnectionStatusChangedEventArgs args)
{
if(serialPortInput.IsConnected)
{
MessageBox.Show("Serial Open");
}
else
{
MessageBox.Show("Serial Close");
}
}
void SerialPortInput_MessageReceive(object sender, MessageReceivedEventArgs args)
{
string a = System.Text.Encoding.UTF8.GetString(args.Data);
MessageBox.Show(a);
}
4、其他方法
byte[] a = System.Text.Encoding.UTF8.GetBytes("1234");
serialPortInput.SendMessage(a);
serialPortInput.Disconnect();
格式转化方法
/// <summary>
/// 把十六进制格式的字符串转换成字节数组。
/// </summary>
/// <param name="pString">要转换的十六进制格式的字符串</param>
/// <returns>返回字节数组。</returns>
public static byte[] getBytesFromString(string pString)
{
string[] str = pString.Split(' '); //把十六进制格式的字符串按空格转换为字符串数组。
byte[] bytes = new byte[str.Length]; //定义字节数组并初始化,长度为字符串数组的长度。
for (int i = 0; i < str.Length; i++) //遍历字符串数组,把每个字符串转换成字节类型赋值给每个字节变量。
bytes[i] = Convert.ToByte(Convert.ToInt32(str[i], 16));
return bytes; //返回字节数组。
}
/// <summary>
/// 把字节数组转换为十六进制格式的字符串。
/// </summary>
/// <param name="pByte">要转换的字节数组。</param>
/// <returns>返回十六进制格式的字符串。</returns>
public static string getStringFromBytes(byte[] pByte)
{
string str = ""; //定义字符串类型临时变量。
//遍历字节数组,把每个字节转换成十六进制字符串,不足两位前面添“0”,以空格分隔累加到字符串变量里。
for (int i = 0; i < pByte.Length; i++)
str += (pByte[i].ToString("X").PadLeft(2, '0') + " ");
str = str.TrimEnd(' '); //去掉字符串末尾的空格。
return str; //返回字符串临时变量。
}
无硬件串口测试方法
1、下载虚拟串口工具VSPD,并安装
2、创建串口后打开串口调试工具(A)和程序(B)分别连接COM1和COM2
3、此时A和B就能够互相通信了。也可在VSPD看发送和接受的字节数:Sent和Received。
源码地址
Git:https://gitee.com/PErobin/Socket.git
SVN:svn://gitee.com/PErobin/Socket