工作上需要用到上位機進行數據交互,所以就用C#編制了一個簡單的串口信息收發程序。界面如下:
開發過程中遇到的一個問題是串口的接收。串口接收大體來說有兩個方式,一個是同步讀取,也即利用循環不斷的讀串口緩存,另外一個就是利用事件觸發的方式。第一種方法效率低,不推薦,第二種則需要利用到跨線程的內容。本人就是卡在這裡一天,其實也就10來句代碼的事,無奈自己玩這個沒得請教,只有求助萬能的百度。經過一天多斷續的摸索,終於解決了這個問題。
在貼上代碼前,先解釋一下代碼中會用到的一些控件的名稱。
1、 cmbportname:設置串口號的下拉列表
2、 cmbbaudrate:設置波特率的下來列表
3、 bttopenport:打開/關閉串口的動作按鈕
4、 txSend:要發送的數據顯示文本框
5、 bttSend:發送那妞
6、 txrecieve:接收到的數據顯示文本框
7、 bttClear:清空接收數據的按鈕
塗黃的代碼關係到異步接收數據,只要照著那幾個塗黃的代碼改一下,應該就可以實現了功能了。需要完整代碼的也可以發郵件給我,。
代碼中的SP是從工具箱拖進來的一個serialport控件。
代碼:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public delegate void getstring(string dataRe);//定義委託
getstring getmystring;//定義委託變量
private void DoUpdate(string data)
{
tbRecieve.Text = tbRecieve.Text + data;//數據處理,將當前數據與文本框文本合併
if (label5.BackColor == Color.AliceBlue)//改變lable的顏色,提示收到數據
{
label5.BackColor = Color.Black;
}
else label5.BackColor = Color.AliceBlue;
}
void SP_DataReceived(object sender, SerialDataReceivedEventArgs e)//接收事件觸發方法
{
try
{
string mystring = SP.ReadExisting();
getmystring = new getstring(DoUpdate);
Invoke(getmystring, mystring);
}
catch (Exception EX)
{
MessageBox.Show(EX.Message, "出錯", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
private void bttOpenPort_Click(object sender, EventArgs e)//打開串口按鈕單擊事件函數
{
try
{
if (SP.IsOpen == true)//如果當前串口是處於打開狀態,則單擊按鈕為關閉串口動作
{
cmbPortName.Enabled = true;//使能串口號獲取控件
cmbBaudRate.Enabled = true;//使能波特率設置控件
bttSend.Enabled = false;//關閉發送數據按鈕
SP.Close();//關閉串口
bttOpenPort.Text = "打開串口";//將打開按鈕文字改為打開串口
}
else if (SP.IsOpen == false)//如果當前串口是處於關閉狀態,則單擊按鈕為打開串口動作
{
cmbPortName.Enabled = false;//關閉串口號獲取控件
cmbBaudRate.Enabled = false;//關閉波特率設置控件
bttOpenPort.Text = "關閉串口";//將打開按鈕文字改為關閉串口
SP.BaudRate = Convert.ToInt16(cmbBaudRate.SelectedItem);//設置波特率為對應combox的選擇項,強制轉換成int型
SP.PortName = cmbPortName.SelectedItem.ToString();//串口號設置成串口號獲取控件當前選擇項,強制轉換成string
SP.StopBits = StopBits.One;//停止位1位
SP.Parity = 0;//校驗,無
SP.DataBits = 8;//數據位,8位
SP.ReceivedBytesThreshold = 10;//接收數據事件觸發門限,設為10,可根據需要設置
SP.Open();//打開串口
bttSend.Enabled = true;//使能發送數據按鈕
SP.DataReceived += new SerialDataReceivedEventHandler(SP_DataReceived);//添加數據接收事件
}
}
catch (Exception EX)
{
MessageBox.Show(EX.Message, "出錯", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
private void bttSend_Click(object sender, EventArgs e)
{
try
{
SP.Write(tbSend.Text);
}
catch (Exception EX)
{
MessageBox.Show(EX.Message, "出錯", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
}
//串口號選擇combox鼠標點擊事件,為了獲取電腦當前有的串口號,並將其添加到combox列表中
//
private void bttGetPort_Click(object sender, EventArgs e)
{
string[] Ports = SerialPort.GetPortNames();
Array.Sort(Ports);
cmbPortName.Items.AddRange(Ports);
cmbPortName.SelectedIndex = cmbPortName.Items.Count > 0 ? 0 : -1;
cmbBaudRate.SelectedIndex = cmbBaudRate.Items.IndexOf("9600");
tbSend.Text = Ports[1];
}
private void bttClear_Click(object sender, EventArgs e)//清空數據按鈕點擊事件
{
tbRecieve.Text = string.Empty;//清空文本框文本內容
}
}
}
閱讀更多 能源工控微課堂 的文章