首先呢,這個代碼我工作中也在用,而且一般公司代碼不能外發,隻不過呢,這個是在我入職之前就寫着玩的,應該無所謂咯。
1、首先呢,運作起來是這樣的,一直在收取單片機的資料
2、對應單片機呢,是這樣發的(大學的時候買的STM32F1的卡,很久沒接觸單片機了),裡面的printf函數輸出,通過USB線傳回給電腦。
3、對應C#裡面的幾個關鍵點
(1)使用Serialport對象,結合微軟官方執行個體程式使用:SerialPort serialPort = new SerialPort();
(2)讀取目前有哪些接線的端口号(還有設定通訊速度,校驗位什麼的):
// 查詢更新已有端口
IList<string> list = new List<string>();
// 讀取目前有哪些COM口
foreach (string s in SerialPort.GetPortNames())
{
list.Add(s);
}
port_m.DataSource = list;
(3)接收到資料後的事件觸發
serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
(4)事件觸發中,中英文都傳送,需要如下格式轉換:
通訊時,string轉換成byte,用于發送(包含中文)
Byte[] data = System.Text.Encoding.Default.GetBytes(textBox1.Text);
serialPort.Write(data, 0, data.Length);
通訊時,byte轉換成string,用于接收(包含中文)
int dataLength = serialPort.BytesToRead;
byte[] buffer = new byte[1024];
sp.Read(buffer, 0, dataLength);
string indata = System.Text.Encoding.Default.GetString(buffer, 0, dataLength);
(5)事件觸發呢是這樣的
void DataReceivedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
if (waitTimes == 0)
{
SerialPort sp = (SerialPort)sender;
Thread.Sleep(10); // 計算需要多長時間延時後再發送
int dataLength = serialPort.BytesToRead;
byte[] buffer = new byte[1024];
sp.Read(buffer, 0, dataLength);
string indata = System.Text.Encoding.Default.GetString(buffer, 0, dataLength);
//indata += sp.ReadExisting(); // 讀取緩沖區全部内容
// String to store the response ASCII representation.
//ASCIIEncoding ASCll = new ASCIIEncoding();
//indata += ASCll.GetString(bt) + "\r\n";
//indata += Convert.ToString(sp.BytesToRead) + "\r\n";
haveRead = true;
// 需要觸發更新界面
this.BeginInvoke(new ReadDelegate(Read), new object[] { indata });
}
}
private delegate void ReadDelegate(string str);
private void Read(string str)
{
this.textBox2.Text += str;
this.textBox2.SelectionStart = this.textBox2.Text.Length;
this.textBox2.ScrollToCaret(); // 滾動到目前選中位置
}
4、好啦,差不多了,于是看下我整體代碼有些什麼
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.Timers; // 用于系統定時重新整理
using System.IO.Ports;
using System.Threading;
using System.Runtime.CompilerServices;
namespace Com
{
public partial class Form1 : Form
{
//系統定時器
System.Timers.Timer timer;
public static int waitTimes = 0; // 端口發送後等待回收時間
static bool haveRead = false; // 已經讀取到資料
static bool timerOut = false; // 讀取等待逾時
static SerialPort serialPort = new SerialPort();
StringComparer stringComparer = StringComparer.OrdinalIgnoreCase;
//Thread readThread = new Thread(Read);
public Form1()
{
InitializeComponent();
InitParameter();
serialPort.ReadTimeout = 500;
serialPort.WriteTimeout = 500;
}
private void send_Click(object sender, EventArgs e)
{
Byte[] data = System.Text.Encoding.Default.GetBytes(textBox1.Text);
if (receive_mode.Text == "發送後延時") {
if (serialPort.IsOpen)
serialPort.Write(data, 0, data.Length);
Thread.Sleep(waitTimes);
string indata;
int dataLength = serialPort.BytesToRead;
if (dataLength > 0)
{
byte[] buffer = new byte[1024];
serialPort.Read(buffer, 0, dataLength);
indata = System.Text.Encoding.Default.GetString(buffer, 0, dataLength);
}
else
indata = "逾時未收到\r\n";
// 需要觸發更新界面
this.BeginInvoke(new ReadDelegate(Read), new object[] { indata });
}
else
{
if (serialPort.IsOpen)
serialPort.Write(data, 0, data.Length);
TimerInit(250);
while (!timerOut && !haveRead) ;
if (timerOut == true) // 需要觸發更新界面
this.BeginInvoke(new ReadDelegate(Read), new object[] { "逾時未收到\r\n" });
timerOut = false;
haveRead = false;
timer.Stop();
}
}
void DataReceivedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
if (waitTimes == 0)
{
SerialPort sp = (SerialPort)sender;
Thread.Sleep(10); // 計算需要多長時間延時後再發送
int dataLength = serialPort.BytesToRead;
byte[] buffer = new byte[1024];
sp.Read(buffer, 0, dataLength);
string indata = System.Text.Encoding.Default.GetString(buffer, 0, dataLength);
//indata += sp.ReadExisting(); // 讀取緩沖區全部内容
// String to store the response ASCII representation.
//ASCIIEncoding ASCll = new ASCIIEncoding();
//indata += ASCll.GetString(bt) + "\r\n";
//indata += Convert.ToString(sp.BytesToRead) + "\r\n";
haveRead = true;
// 需要觸發更新界面
this.BeginInvoke(new ReadDelegate(Read), new object[] { indata });
}
}
private delegate void ReadDelegate(string str);
private void Read(string str)
{
this.textBox2.Text += str;
this.textBox2.SelectionStart = this.textBox2.Text.Length;
this.textBox2.ScrollToCaret(); // 滾動到目前選中位置
}
private void port_m_SelectedIndexChanged(object sender, EventArgs e)
{
}
private void receive_Click(object sender, EventArgs e)
{
if(!serialPort.IsOpen)
{
connect.Text = "關閉";
try
{
object myPort;
myPort = port_m.SelectedItem;
serialPort.PortName = Convert.ToString(myPort);
object mySpeed;
mySpeed = speed.SelectedItem;
serialPort.BaudRate = Convert.ToInt32(mySpeed);
object myParity;
myParity = odd_even.SelectedItem;
serialPort.Parity = (Parity)Enum.Parse(typeof(Parity), Convert.ToString(myParity), true);
serialPort.DataBits = 8;
object myStop;
myStop = receive_mode.SelectedItem;
serialPort.StopBits = (StopBits)Enum.Parse(typeof(StopBits), Convert.ToString(myStop), true);
}
catch (Exception ex) { }
serialPort.Open();
// 連接配接後開始執行讀取線程
Task.Run(() => {
while (false)
{
if (haveRead)
{
TimerInit(100);
while (haveRead) ;
}
}
});
}
else
{
connect.Text = "連接配接";
serialPort.Close();
}
}
void TimerInit(int time)
{
//高重新整理定時器初始化
timer = new System.Timers.Timer();
timer.Interval = time; // 機關:毫秒
timer.Elapsed += OnTimedEvent;
timer.AutoReset = true;
timer.Enabled = true;
timer.Start();
//timer.Stop();
}
/* 定時器Timer觸發事件
*/
public void OnTimedEvent(object source, ElapsedEventArgs e)
{
timerOut = true;
}
private void InitParameter()
{
serialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
//comboBox1.Items.Add(textBox1.Text);
// 查詢更新已有端口
IList<string> list = new List<string>();
// 讀取目前有哪些COM口
foreach (string s in SerialPort.GetPortNames())
{
list.Add(s);
}
port_m.DataSource = list;
// 傳輸速度
int[] speed_data = new int[] { 9600, 19200, 38400, 115200 };
speed.DataSource = speed_data;
// 奇偶校驗
IList<string> list1 = new List<string>();
list1.Clear();
list1.Add("None");
list1.Add("奇校驗");
list1.Add("偶校驗");
odd_even.DataSource = list1;
// 停止位
string[] stop = { "1", "2" };
stop_num.DataSource = stop;
//list.Clear();
string[] str = { "事件", "發送後延時" };
receive_mode.DataSource = str; // StopBits
// 觸發事件
this.port_m.SelectedValueChanged += new System.EventHandler(this.port_m_SelectedIndexChanged);
}
// 接收方式發生改變時
void receive_mode_changed(object ob, EventArgs e)
{
if(receive_mode.Text == "發送後延時")
{
DelayTime delayTime = new DelayTime();
delayTime.Show();
}
else
{
waitTimes = 0;
}
}
}
}