本方法,禁用跨进程错误(做法不太好,但是对于单片机出身的人来说,好理解,能用就行)。
基本功能:
1.点串口号的下拉菜单自动当前检索设备管理器的COM
2.发送模式可选,hex和string两种
3.接收显示模式,hex和string两种
4.发送多行数据
5.发送单行,可增加自动换行(方便用于一些串口指令,很多指令都带回车,每次写回车太麻烦)
效果演示:
主代码参考:
using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.IO.Ports; using System.Linq; using System.Text; using System.Windows.Forms; namespace SerialTools { public partial class Form1 : Form { private long RxCount = 0; public Form1() { InitializeComponent(); System.Windows.Forms.Control.CheckForIllegalCrossThreadCalls = false; } #region 初始化Form private void Form1_Load(object sender, EventArgs e) { pictureBox1.Image = Properties.Resources.off; ////查询当前有用的串口号 //SerialPort.GetPortNames(); //string[] ports = SerialPort.GetPortNames(); //foreach (string port in ports) //{ // cb_com.Items.Add(port); //} serialPort1.BaudRate = 9600; serialPort1.DataBits = 8; serialPort1.StopBits = (StopBits)1; //迭代所有的波特率 string[] tab_Baud = new string[] { "110", "300", "600", "1200", "2400", "4800", "9600", "14400", "19200", "38400", "56000", "57600", "115200", "128000", "256000" }; foreach (string str in tab_Baud) { cb_Baud.Items.Add(str); } //迭代所有的数据位 string[] tab_data = new string[] { "5", "6", "7", "8" }; foreach (string str in tab_data) { cb_DataBits.Items.Add(str); } //迭代所有的停止位 string[] tab_stop = new string[] { "1", "2" }; foreach (string str in tab_stop) { cb_StopBits.Items.Add(str); } cb_Baud.Text = "9600"; cb_DataBits.Text = "8"; cb_StopBits.Text = "1"; serialPort1.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);//添加事件 } #endregion #region 接收数据 private void port_DataReceived(object sender,SerialDataReceivedEventArgs e) { if (!checkBox_receiveMode.Checked)//没有勾选hex时候,按照字符串方式读取 { string str = serialPort1.ReadExisting();//字符串方式读 textBox_receive.AppendText(str); //添加内容 RxCount += str.Length; } else { byte data; data = (byte)serialPort1.ReadByte(); string str = Convert.ToString(data, 16).ToUpper(); textBox_receive.AppendText((str.Length == 1 ? "0" + str : str)+" ");//空位补"0" RxCount += str.Length; } label_ReceiveCount.Text = RxCount.ToString(); } #endregion #region 清空接收计数器和接收显示区域 private void button4_Click(object sender, EventArgs e) { textBox_receive.Text = ""; RxCount = 0; label_ReceiveCount.Text = RxCount.ToString(); } #endregion #region 打开/关闭串口 private void button1_Click(object sender, EventArgs e) { if (!serialPort1.IsOpen) { try { serialPort1.PortName = cb_com.Text; serialPort1.BaudRate = Convert.ToInt32(cb_Baud.Text); serialPort1.DataBits = Convert.ToInt32(cb_DataBits.Text); serialPort1.StopBits = (StopBits)Convert.ToInt32(cb_StopBits.Text); serialPort1.Open(); } catch { MessageBox.Show("端口打开失败", "错误"); } } else { try { serialPort1.Close(); } catch { MessageBox.Show("端口关闭失败", "错误"); } } changeButtonTextAndPicture(); } #endregion #region 根据串口状态切换按键名称和指示灯图片 private void changeButtonTextAndPicture() { if (serialPort1.IsOpen) { pictureBox1.Image = Properties.Resources.on; button1.Text = "关闭串口"; } else { pictureBox1.Image = Properties.Resources.off; button1.Text = "打开串口"; } } #endregion #region 多行发送 private void button2_Click(object sender, EventArgs e) { byte[] Data = new byte[1]; if (serialPort1.IsOpen) { if(textBox_send1.Text != "") { if(!checkBox_sendMode.Checked)//发送模式是字符模式 { try { serialPort1.Write(textBox_send1.Text); } catch { MessageBox.Show("端口发送失败,系统将关闭当前串口", "错误"); serialPort1.Close();//关闭串口 } } else { if(textBox_send1.Text.Length%2 == 0)//偶数个数字 { for(int i = 0; i < textBox_send1.Text.Length / 2; i++) { try { Data[0] = Convert.ToByte(textBox_send1.Text.Substring(i * 2, 2), 16); } catch { MessageBox.Show("请核对输入的十六进制数据格式", "错误"); } try { serialPort1.Write(Data, 0, 1); } catch { MessageBox.Show("端口发送失败,系统将关闭当前串口", "错误"); serialPort1.Close();//关闭串口 } } } else { MessageBox.Show("请输入偶数个16进制数字", "错误"); } } } } } #endregion #region 单行发送 private void button3_Click(object sender, EventArgs e) { byte[] Data = new byte[1]; if (serialPort1.IsOpen) { if (textBox_send2.Text != "") { if (!checkBox_sendMode.Checked)//发送模式是字符模式 { try { serialPort1.Write(textBox_send2.Text); if (checkBox_newLine.Checked) serialPort1.Write(" "); } catch { MessageBox.Show("端口发送失败,系统将关闭当前串口", "错误"); serialPort1.Close();//关闭串口 } } else { if (textBox_send2.Text.Length % 2 == 0)//偶数个数字 { for (int i = 0; i < textBox_send2.Text.Length / 2; i++) { try { Data[0] = Convert.ToByte(textBox_send2.Text.Substring(i * 2, 2), 16); } catch { MessageBox.Show("请核对输入的十六进制数据格式", "错误"); } try { serialPort1.Write(Data, 0, 1); if (checkBox_newLine.Checked) serialPort1.Write(" "); } catch { MessageBox.Show("端口发送失败,系统将关闭当前串口", "错误"); serialPort1.Close();//关闭串口 } } } else { MessageBox.Show("请输入偶数个16进制数字", "错误"); } } } } } #endregion #region 切换选项时候修改串口属性 private void cb_com_SelectedIndexChanged(object sender, EventArgs e) { try { if (serialPort1.IsOpen) { serialPort1.Close(); serialPort1.PortName = cb_com.Text; serialPort1.Open(); } else { serialPort1.PortName = cb_com.Text; } } catch (System.Exception ex) { MessageBox.Show(ex.Message); } finally { changeButtonTextAndPicture(); } } private void cb_Baud_SelectedIndexChanged(object sender, EventArgs e) { serialPort1.BaudRate = int.Parse(cb_Baud.Text); } private void cb_DataBits_SelectedIndexChanged(object sender, EventArgs e) { serialPort1.DataBits = int.Parse(cb_DataBits.Text); } private void cb_StopBits_SelectedIndexChanged(object sender, EventArgs e) { serialPort1.StopBits = (StopBits)int.Parse(cb_StopBits.Text); } #endregion #region com的下拉菜单展开时候自动搜索当前设备管理器 private void cb_com_DropDown(object sender, EventArgs e) { cb_com.Items.Clear(); //清空 //查询当前有用的串口号 SerialPort.GetPortNames(); string[] ports = SerialPort.GetPortNames(); foreach (string port in ports) { cb_com.Items.Add(port); } } #endregion } }
工程源码下载(使用VS2015编译):
http://yunpan.cn/cHLTVtXLL6UYs 访问密码 bf4e