c#的串列埠通訊簡單例項
---本人是一名小白,最近在做學校有關通訊的專案。在寫這份程式碼之前,查看了許多參考程式碼。如果我有說的不對的地方,還請大家指出來。
工具:串列埠助手、串列埠除錯助手、編譯器(我用的vs2017)//完整程式碼和除錯助手 在文末有連結
一、效果圖
首先給大家放一張效果圖。
二、步驟
(1)首先,肯定就是先將各個部件拖入form裡,然後佈局了。
在這裡請注意:
- 對於剛剛接觸c#的小白來說,記得傳送的文字框和單選按鈕與接受的文字框和單選按鈕。是兩個不一樣的panel。
- 波特率:因為常用的波特率是以下幾個,所以我直接設定了下拉框。
- 校驗位:設定的是 無、奇校驗、偶校驗。
- 停止位設定的是:1、1.5、2
- 資料位是:7、8
- 串列埠號:串列埠號就任意了,主要看你需要多少。我就設定了com1~4
在選擇完引數之後,點選檢查串列埠,如沒問題,則會顯示,串列埠檢查成功
這時,點選開啟串列埠,會提示開啟串列埠成功。
讓我們再看看串列埠助手
開啟串列埠除錯助手,將引數調成一致之後。在form裡傳送一段16進位制。除錯助手將接受到
最後用除錯助手,傳送一段16進位制數。form將接受到資訊。
(2)程式碼及其主要函式。
CheckPort():檢查串列埠是否可用。裡面的主要方法是GetPortNames(獲取當前計算機的串列埠名稱陣列)
private void CheckPort()//檢查串列埠是否可用 { ckCheckBox.Items.Clear();//清除控制元件中的當前值 bool havePort = false; string[] a = SerialPort.GetPortNames(); if (a != null) { for (int i = 0; i < a.Length; i++) { bool use = false; try { SerialPort t = new SerialPort(a[i]); sp.Open(); sp.Close(); use = true; } catch { } if (use) { ckCheckBox.Items.Add(a[i]); havePort = true; } } } if (havePort) { ckCheckBox.SelectedIndex = 0;//?? } else { MessageBox.Show("無可用串列埠...", "錯誤"); } }
setPort()://設定串列埠
通過下拉框獲取此串列埠的PortName(串列埠號)、BaudRate(波特率)、Parity(校驗位)、StopBits(停止位)
DataReceived()//接受資料
通過非同步委託一個執行緒,讀出緩衝區串列埠通訊的位元組,然後將其寫入此前定義的SerialPort中。最後寫入text中
ASCIIToHex()//字元轉16進位制
HexToASCII()//十六進位制轉字元;
-----------------------------------------------------------------------
話不多說,直接上原始碼
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.IO.Ports;
using System.Threading;//執行緒申明
namespace ck3
{
public partial class Form1 : Form
{
private void CheckPort()//檢查串列埠是否可用
{
ckCheckBox.Items.Clear();//清除控制元件中的當前值
bool havePort = false;
string[] a = SerialPort.GetPortNames();
if (a != null)
{
for (int i = 0; i < a.Length; i++)
{
bool use = false;
try
{
SerialPort t = new SerialPort(a[i]);
sp.Open();
sp.Close();
use = true;
}
catch
{
}
if (use)
{
ckCheckBox.Items.Add(a[i]);
havePort = true;
}
}
}
if (havePort)
{
ckCheckBox.SelectedIndex = 0;//??
}
else
{
MessageBox.Show("無可用串列埠...", "錯誤");
}
}
private void SetPort()//設定串列埠
{
try
{
sp.PortName = ckCheckBox.Text.Trim();//串列埠名給了串列埠類
sp.BaudRate = Convert.ToInt32(SendBox.Text.Trim());//Trim除去前後空格,講文字轉換為32位字元給予串列埠類
if (JywCheckBox.Text.Trim() == "奇校驗")
{
sp.Parity = Parity.Odd;//將奇校驗位給了sp的協議
}
else if (JywCheckBox.Text.Trim() == "偶校驗")
{
sp.Parity = Parity.Even;
}
else
{
sp.Parity = Parity.None;
}
if (StopCheckBox.Text.Trim() == "1.5")
{
sp.StopBits = StopBits.OnePointFive;//設定停止位有幾位
}
else if (StopCheckBox.Text.Trim() == "2")
{
sp.StopBits = StopBits.Two;
}
else
{
sp.StopBits = StopBits.One;
}
sp.DataBits = Convert.ToInt16(DataBox.Text.ToString().Trim());//資料位
sp.Encoding = Encoding.UTF8;//串列埠通訊的編碼格式
sp.Open();
}
catch { }
}
private string HexToASCII(string str)
{
try
{
string[] mystr1 = str.Trim().Split(' ');
byte[] t = new byte[mystr1.Length];
for (int i = 0; i < t.Length; i++)
{
t[i] = Convert.ToByte(mystr1[i], 16);
}
return Encoding.UTF8.GetString(t);
}
catch (Exception ex)
{
rbtReceicedAscii.Select();
MessageBox.Show("轉換失敗!" + ex.Message, "錯誤提示");
return str;
}
}
private string ASCIIToHex(string my2)
{
try
{
byte[] a = Encoding.UTF8.GetBytes(my2.Trim());
string mystr1 = "";
for (int i = 0; i < a.Length; i++)
{
mystr1 += a[i].ToString("X2") + " ";
}
return mystr1;
}
catch (Exception ex)
{
rbtReceicedAscii.Select();
MessageBox.Show("轉換失敗!" + ex.Message, "錯誤提示");
return my2;
}
}
private void Form1_Load(object sender, EventArgs e)
{
statusText.Text = "";//狀態條初始化
//設定視窗大小
this.MaximizeBox = false;//隱藏最大化按鈕
this.MaximumSize = this.Size;//固定視窗尺寸最大為當前尺寸
this.MinimumSize = this.Size;//固定視窗尺寸最小為當前尺寸
BtlCheckBox.SelectedIndex = 5;
// JywCheckBox.Items.Clear();
JywCheckBox.SelectedIndex = 1;
StopCheckBox.SelectedIndex = 1;
// DataBox.Items.Clear();
DataBox.SelectedIndex = 1;
statusText.Text = "";
rbtSendAscii.Select();//預設選擇ASCII字元顯示
rbtReceicedAscii.Select();//預設選擇ASCII字元顯示
}
private void btnChecked_Click(object sender, EventArgs e)
{
statusText.Text = "檢測串列埠開始!";
CheckPort();
statusText.Text = "串列埠檢測完成!";
}
private void sp_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(100);//等待
this.Invoke((EventHandler)(delegate //非同步委託一個執行緒
{
try
{
byte[] a = new byte[sp.BytesToRead];//讀出緩衝區串列埠通訊的位元組
sp.Read(a, 0, a.Length);//寫入sp
string my2 = Encoding.UTF8.GetString(a);
string b = "";
if (rbtSendAscii.Checked)
{
b = ASCIIToHex(my2);
}
else
{
b = my2;
}
RecevieBox.Text += b + "\r\n";
statusText.Text = "接收成功!";
}
catch
{
statusText.Text = "接收失敗!";
}
}));
}
public Form1()
{
InitializeComponent();
}
//傳送按鈕
private void button1_Click_1(object sender, EventArgs e)
{
try
{
string mystr1 = SendBox.Text;
if (SixtyRe.Checked)
{
mystr1 = HexToASCII(SendBox.Text);
}
byte[] a = Encoding.UTF8.GetBytes(mystr1);
string mystr2 = Encoding.UTF8.GetString(a);
sp.Write(mystr2);//將資料寫入串列埠輸出緩衝區
// tbxReceivedData.Text += tbxSendData.Text + "\r\n";
statusText.Text = "傳送成功!";
}
catch
{
statusText.Text = "傳送失敗";
}
}
private void button1_Click_2(object sender, EventArgs e)
{
RecevieBox.Text = " ";
SendBox.Text = " ";
}
private void BtnOpen_Click(object sender, EventArgs e)
{
if (BtnOpen.Text == "開啟串列埠")
{
SetPort();
if (sp.IsOpen)
{
statusText.Text = "串列埠" + ckCheckBox.Text + "已開啟!";
}
else
{
try
{
sp.Open();
btnChecked.Enabled = false;
ckCheckBox.Enabled = false;
BtlCheckBox.Enabled = false;
JywCheckBox.Enabled = false;
StopCheckBox.Enabled = false;
DataBox.Enabled = false;
BtnOpen.Text = "關閉串列埠";
statusText.Text = "串列埠" + ckCheckBox.Text + "開啟成功!";
}
catch (Exception ex)
{
MessageBox.Show("串列埠" + ckCheckBox.Text + "開啟失敗,失敗原因:" + ex.Message, "錯誤提示");
statusText.Text = "串列埠" + ckCheckBox.Text + "開啟失敗,失敗原因:" + ex.Message;
}
}
}
else //關閉串列埠
{
if (sp.IsOpen) //判斷串列埠是否開啟
{
try
{
sp.Close(); //關閉串列埠
//啟用設定控制元件
btnChecked.Enabled = true;
ckCheckBox.Enabled = true;
BtlCheckBox.Enabled = true;
JywCheckBox.Enabled = true;
StopCheckBox.Enabled = true;
DataBox.Enabled = true;
BtnOpen.Text = "開啟串列埠";
statusText.Text = "串列埠" + ckCheckBox.Text + "關閉成功!";
}
catch (Exception ex)
{
MessageBox.Show("串列埠" + ckCheckBox.Text + "關閉失敗,錯誤提示:" + ex.Message, "錯誤提示");
statusText.Text = "串列埠" + ckCheckBox.Text + "關閉失敗,錯誤提示:" + ex.Message;
}
}
else
{
btnChecked.Enabled = true;
ckCheckBox.Enabled = true;
BtlCheckBox.Enabled = true;
JywCheckBox.Enabled = true;
StopCheckBox.Enabled = true;
DataBox.Enabled = true;
BtnOpen.Text = "開啟串列埠";
statusText.Text = "串列埠未開啟,無法關閉!";
MessageBox.Show("串列埠未開啟,無法關閉!", "錯誤提示");
}
}
}
private void SixtySend_CheckedChanged(object sender, EventArgs e)
{
if (SixtyRe.Checked)
{
SendBox.Text = ASCIIToHex(SendBox.Text.ToString());
}
}
}
}
最後附上 我的程式碼資源。如果連結打不開請大家去我的主頁檢視
完整程式碼:https://download.csdn.net/download/qq_41406816/10776168
串列埠除錯助手:https://download.csdn.net/download/qq_41406816/10776285