C#實(shí)現(xiàn)監(jiān)聽(tīng)串口數(shù)據(jù)的方法詳解
在C#中,接收COM端口(串口)報(bào)文通常涉及到使用System.IO.Ports.SerialPort類(lèi),并對(duì)接收到的字節(jié)數(shù)據(jù)進(jìn)行處理和格式轉(zhuǎn)換。下面是一個(gè)基本的流程,描述了如何在C#中接收和轉(zhuǎn)換COM端口報(bào)文:
步驟 1: 引用命名空間
首先,確保你的項(xiàng)目引用了處理串口通信所需的命名空間:
using System.IO.Ports;
步驟 2: 設(shè)置 SerialPort 對(duì)象
創(chuàng)建SerialPort對(duì)象并設(shè)置串口的配置參數(shù)(如波特率、數(shù)據(jù)位、停止位等):
SerialPort mySerialPort = new SerialPort("COM1");
mySerialPort.BaudRate = 9600;
mySerialPort.Parity = Parity.None;
mySerialPort.StopBits = StopBits.One;
mySerialPort.DataBits = 8;
mySerialPort.Handshake = Handshake.None;
// 設(shè)置讀寫(xiě)時(shí)間超時(shí)
mySerialPort.ReadTimeout = 500;
mySerialPort.WriteTimeout = 500;
步驟 3: 打開(kāi)串口
mySerialPort.Open();
步驟 4: 接收數(shù)據(jù)
你可以使用DataReceived事件來(lái)處理接收到的數(shù)據(jù)。當(dāng)串口接收到數(shù)據(jù)時(shí),這個(gè)事件會(huì)被觸發(fā):
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
實(shí)現(xiàn)事件處理函數(shù)DataReceivedHandler來(lái)讀取數(shù)據(jù)并進(jìn)行處理:
private static void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
byte[] buffer = new byte[sp.BytesToRead];
sp.Read(buffer, 0, buffer.Length);
// TODO: 這里添加你的數(shù)據(jù)處理和格式轉(zhuǎn)換邏輯
string formattedData = ConvertToDesiredFormat(buffer);
// 處理轉(zhuǎn)換后的數(shù)據(jù)
ProcessData(formattedData);
}
步驟 5: 轉(zhuǎn)換格式
創(chuàng)建函數(shù)ConvertToDesiredFormat來(lái)實(shí)現(xiàn)將接收到的字節(jié)數(shù)據(jù)轉(zhuǎn)換為你需要的格式。這里的實(shí)現(xiàn)取決于你的具體需求:
private static string ConvertToDesiredFormat(byte[] data)
{
// 舉例:將字節(jié)數(shù)據(jù)轉(zhuǎn)換為ASCII字符串
return Encoding.ASCII.GetString(data);
// 注意:如果數(shù)據(jù)是特定協(xié)議格式,你需要根據(jù)協(xié)議解析并轉(zhuǎn)換數(shù)據(jù)
}
步驟 6: 關(guān)閉串口
當(dāng)數(shù)據(jù)處理完成后,記得關(guān)閉串口以釋放資源:
mySerialPort.Close();
注意事項(xiàng)
- 確保你有適當(dāng)?shù)臋?quán)限來(lái)訪問(wèn)COM端口。
- 上面的代碼片段是一個(gè)簡(jiǎn)化的例子。實(shí)際應(yīng)用中,你可能需要根據(jù)具體的通信協(xié)議來(lái)處理和驗(yàn)證數(shù)據(jù)(如計(jì)算校驗(yàn)和、處理數(shù)據(jù)幀等)。
- 如果通信過(guò)程中可能出現(xiàn)讀寫(xiě)沖突或其他線程安全問(wèn)題,考慮使用鎖(如
lock語(yǔ)句)來(lái)同步訪問(wèn)串口資源。
配置完成后,程序就可以監(jiān)聽(tīng)指定的COM端口,并在接收到數(shù)據(jù)時(shí)進(jìn)行處理和轉(zhuǎn)換了。記得在實(shí)際部署前,充分測(cè)試你的代碼以確保它能夠可靠地處理實(shí)際的通信場(chǎng)景。
知識(shí)補(bǔ)充
除了上文的內(nèi)容,小編還為大家整理了C#實(shí)現(xiàn)串口數(shù)據(jù)偵聽(tīng)的相關(guān)方法,希望對(duì)大家有所幫助
當(dāng)需要編程操縱硬件時(shí)會(huì)遇到過(guò)這樣的問(wèn)題,就是通過(guò)串口來(lái)接收硬件發(fā)來(lái)的數(shù)據(jù),或是通過(guò)串口向硬件發(fā)送某種格式的命令。在C#平臺(tái)上,可以通過(guò) System.IO.Ports 命名空間下的SerialPort 類(lèi)來(lái)實(shí)現(xiàn)。
下面是一個(gè)簡(jiǎn)單的示例,首先獲取本機(jī)關(guān)聯(lián)的串行端口列表,然后獲取配置文件中配置的COM端口,檢查是否在本機(jī)串行端口列表中,若在列表中則進(jìn)一步實(shí)例化串口對(duì)象,并為串口對(duì)象指定數(shù)據(jù)接收事件來(lái)實(shí)現(xiàn)監(jiān)聽(tīng),示例代碼如下:
using System.IO.Ports;
namespace SerialTest
{
public class SerialTest
{
#region 串口監(jiān)聽(tīng)
private SerialPort serialPort = null;
/// <summary>
/// 開(kāi)啟串口監(jiān)聽(tīng)
/// </summary>
private void StartSerialPortMonitor()
{
List<string> comList = GetComlist(false); //首先獲取本機(jī)關(guān)聯(lián)的串行端口列表
if (comList.Count == 0)
{
DialogForm.Show("提示信息", "當(dāng)前設(shè)備不存在串行端口!");
System.Environment.Exit(0); //徹底退出應(yīng)用程序
}
else
{
string targetCOMPort = ConfigurationManager.AppSettings["COMPort"].ToString();
//判斷串口列表中是否存在目標(biāo)串行端口
if (!comList.Contains(targetCOMPort))
{
DialogForm.Show("提示信息", "當(dāng)前設(shè)備不存在配置的串行端口!");
System.Environment.Exit(0); //徹底退出應(yīng)用程序
}
serialPort = new SerialPort();
//設(shè)置參數(shù)
serialPort.PortName = ConfigurationManager.AppSettings["COMPort"].ToString(); //通信端口
serialPort.BaudRate = Int32.Parse(ConfigurationManager.AppSettings["BaudRate"].ToString()); //串行波特率
serialPort.DataBits = 8; //每個(gè)字節(jié)的標(biāo)準(zhǔn)數(shù)據(jù)位長(zhǎng)度
serialPort.StopBits = StopBits.One; //設(shè)置每個(gè)字節(jié)的標(biāo)準(zhǔn)停止位數(shù)
serialPort.Parity = Parity.None; //設(shè)置奇偶校驗(yàn)檢查協(xié)議
serialPort.ReadTimeout = 3000; //單位毫秒
serialPort.WriteTimeout = 3000; //單位毫秒
//串口控件成員變量,字面意思為接收字節(jié)閥值,
//串口對(duì)象在收到這樣長(zhǎng)度的數(shù)據(jù)之后會(huì)觸發(fā)事件處理函數(shù)
//一般都設(shè)為1
serialPort.ReceivedBytesThreshold = 1;
serialPort.DataReceived += new SerialDataReceivedEventHandler(CommDataReceived); //設(shè)置數(shù)據(jù)接收事件(監(jiān)聽(tīng))
try
{
serialPort.Open(); //打開(kāi)串口
}
catch (Exception ex)
{
DialogForm.Show("提示信息", "串行端口打開(kāi)失?。【唧w原因:" + ex.Message);
System.Environment.Exit(0); //徹底退出應(yīng)用程序
}
}
}
/// <summary>
/// 串口數(shù)據(jù)處理函數(shù)
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void CommDataReceived(Object sender, SerialDataReceivedEventArgs e)
{
try
{
//Comm.BytesToRead中為要讀入的字節(jié)長(zhǎng)度
int len = serialPort.BytesToRead;
Byte[] readBuffer = new Byte[len];
serialPort.Read(readBuffer, 0, len); //將數(shù)據(jù)讀入緩存
//處理readBuffer中的數(shù)據(jù),自定義處理過(guò)程
string msg = encoding.GetString(readBuffer, 0, len); //獲取出入庫(kù)產(chǎn)品編號(hào)
DialogForm.Show("接收到的信息", msg);
}
catch(Exception ex)
{
DialogForm.Show("提示信息", "接收返回消息異常!具體原因:" + ex.Message);
}
}
/// <summary>
/// 關(guān)閉串口
/// </summary>
private void Stop()
{
serialPort.Close();
}
/// <summary>
/// 獲取本機(jī)串口列表
/// </summary>
/// <param name="isUseReg"></param>
/// <returns></returns>
private List<string> GetComlist(bool isUseReg)
{
List<string> list = new List<string>();
try
{
if (isUseReg)
{
RegistryKey RootKey = Registry.LocalMachine;
RegistryKey Comkey = RootKey.OpenSubKey(@"HARDWARE\DEVICEMAP\SERIALCOMM");
String[] ComNames = Comkey.GetValueNames();
foreach (String ComNamekey in ComNames)
{
string TemS = Comkey.GetValue(ComNamekey).ToString();
list.Add(TemS);
}
}
else
{
foreach (string com in SerialPort.GetPortNames()) //自動(dòng)獲取串行口名稱
list.Add(com);
}
}
catch
{
DialogForm.Show("提示信息", "串行端口檢查異常!");
System.Environment.Exit(0); //徹底退出應(yīng)用程序
}
return list;
}
#endregion 串口監(jiān)聽(tīng)
}
}到此這篇關(guān)于C#實(shí)現(xiàn)監(jiān)聽(tīng)串口數(shù)據(jù)的方法詳解的文章就介紹到這了,更多相關(guān)C#監(jiān)聽(tīng)串口數(shù)據(jù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#客戶端程序Visual Studio遠(yuǎn)程調(diào)試的方法詳解
這篇文章主要給大家介紹了關(guān)于C#客戶端程序Visual Studio遠(yuǎn)程調(diào)試的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
c#數(shù)據(jù)綁定之?dāng)?shù)據(jù)轉(zhuǎn)化為信息的示例
這篇文章主要介紹了c#數(shù)據(jù)綁定中的數(shù)據(jù)轉(zhuǎn)化為信息的示例,需要的朋友可以參考下2014-04-04
Unity3D實(shí)現(xiàn)分頁(yè)系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Unity3D實(shí)現(xiàn)分頁(yè)系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04
c#實(shí)現(xiàn)無(wú)標(biāo)題欄窗口的拖動(dòng)
本篇文章是對(duì)c#中實(shí)現(xiàn)無(wú)標(biāo)題欄窗口拖動(dòng)的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06
詳解C# 泛型中的數(shù)據(jù)類(lèi)型判定與轉(zhuǎn)換
這篇文章主要介紹了C# 泛型中的數(shù)據(jù)類(lèi)型判定與轉(zhuǎn)換,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07
c#和avascript加解密之間的互轉(zhuǎn)代碼分享
這篇文章主要介紹了c#和Javascript間互轉(zhuǎn)的Xxtea加解密代碼,需要的朋友可以參考下2014-02-02
C#爬取動(dòng)態(tài)網(wǎng)頁(yè)上信息得流程步驟
動(dòng)態(tài)內(nèi)容網(wǎng)站使用 JavaScript 腳本動(dòng)態(tài)檢索和渲染數(shù)據(jù),爬取信息時(shí)需要模擬瀏覽器行為,否則獲取到的源碼基本是空的,這篇文章主要給大家詳細(xì)介紹了C#爬取動(dòng)態(tài)網(wǎng)頁(yè)上信息得流程步驟,需要的朋友可以參考下2024-10-10
extern外部方法使用C#的實(shí)現(xiàn)方法
這篇文章主要介紹了extern外部方法使用C#的實(shí)現(xiàn)方法,較為詳細(xì)的分析了外部方法使用C#的具體步驟與實(shí)現(xiàn)技巧,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-12-12
C#判斷訪問(wèn)來(lái)源是否為搜索引擎鏈接的方法
這篇文章主要介紹了C#判斷訪問(wèn)來(lái)源是否為搜索引擎鏈接的方法,實(shí)例分析了C#解析URL來(lái)源的技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-03-03
DataTables List互相轉(zhuǎn)換的實(shí)現(xiàn)類(lèi)示例
這篇文章主要介紹了將DataTable轉(zhuǎn)換為L(zhǎng)ist,將List轉(zhuǎn)換為DataTable的實(shí)現(xiàn)類(lèi)實(shí)例方法,大家參考使用吧2013-11-11

