本方法,禁用跨進程錯誤(做法不太好,但是對於單片機出身的人來說,好理解,能用就行)。
基本功能:
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("\r\n"); } 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("\r\n"); } 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