C#實(shí)現(xiàn)監(jiān)聽串口數(shù)據(jù)的方法詳解
在C#中,接收COM端口(串口)報(bào)文通常涉及到使用System.IO.Ports.SerialPort
類,并對接收到的字節(jié)數(shù)據(jù)進(jìn)行處理和格式轉(zhuǎn)換。下面是一個(gè)基本的流程,描述了如何在C#中接收和轉(zhuǎn)換COM端口報(bào)文:
步驟 1: 引用命名空間
首先,確保你的項(xiàng)目引用了處理串口通信所需的命名空間:
using System.IO.Ports;
步驟 2: 設(shè)置 SerialPort 對象
創(chuàng)建SerialPort
對象并設(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è)置讀寫時(shí)間超時(shí) mySerialPort.ReadTimeout = 500; mySerialPort.WriteTimeout = 500;
步驟 3: 打開串口
mySerialPort.Open();
步驟 4: 接收數(shù)據(jù)
你可以使用DataReceived
事件來處理接收到的數(shù)據(jù)。當(dāng)串口接收到數(shù)據(jù)時(shí),這個(gè)事件會被觸發(fā):
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
實(shí)現(xiàn)事件處理函數(shù)DataReceivedHandler
來讀取數(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
來實(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)限來訪問COM端口。
- 上面的代碼片段是一個(gè)簡化的例子。實(shí)際應(yīng)用中,你可能需要根據(jù)具體的通信協(xié)議來處理和驗(yàn)證數(shù)據(jù)(如計(jì)算校驗(yàn)和、處理數(shù)據(jù)幀等)。
- 如果通信過程中可能出現(xiàn)讀寫沖突或其他線程安全問題,考慮使用鎖(如
lock
語句)來同步訪問串口資源。
配置完成后,程序就可以監(jiān)聽指定的COM端口,并在接收到數(shù)據(jù)時(shí)進(jìn)行處理和轉(zhuǎn)換了。記得在實(shí)際部署前,充分測試你的代碼以確保它能夠可靠地處理實(shí)際的通信場景。
知識補(bǔ)充
除了上文的內(nèi)容,小編還為大家整理了C#實(shí)現(xiàn)串口數(shù)據(jù)偵聽的相關(guān)方法,希望對大家有所幫助
當(dāng)需要編程操縱硬件時(shí)會遇到過這樣的問題,就是通過串口來接收硬件發(fā)來的數(shù)據(jù),或是通過串口向硬件發(fā)送某種格式的命令。在C#平臺上,可以通過 System.IO.Ports 命名空間下的SerialPort 類來實(shí)現(xiàn)。
下面是一個(gè)簡單的示例,首先獲取本機(jī)關(guān)聯(lián)的串行端口列表,然后獲取配置文件中配置的COM端口,檢查是否在本機(jī)串行端口列表中,若在列表中則進(jìn)一步實(shí)例化串口對象,并為串口對象指定數(shù)據(jù)接收事件來實(shí)現(xiàn)監(jiān)聽,示例代碼如下:
using System.IO.Ports; namespace SerialTest { public class SerialTest { #region 串口監(jiān)聽 private SerialPort serialPort = null; /// <summary> /// 開啟串口監(jiān)聽 /// </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ù)位長度 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é)閥值, //串口對象在收到這樣長度的數(shù)據(jù)之后會觸發(fā)事件處理函數(shù) //一般都設(shè)為1 serialPort.ReceivedBytesThreshold = 1; serialPort.DataReceived += new SerialDataReceivedEventHandler(CommDataReceived); //設(shè)置數(shù)據(jù)接收事件(監(jiān)聽) try { serialPort.Open(); //打開串口 } catch (Exception ex) { DialogForm.Show("提示信息", "串行端口打開失??!具體原因:" + 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é)長度 int len = serialPort.BytesToRead; Byte[] readBuffer = new Byte[len]; serialPort.Read(readBuffer, 0, len); //將數(shù)據(jù)讀入緩存 //處理readBuffer中的數(shù)據(jù),自定義處理過程 string msg = encoding.GetString(readBuffer, 0, len); //獲取出入庫產(chǎn)品編號 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()) //自動獲取串行口名稱 list.Add(com); } } catch { DialogForm.Show("提示信息", "串行端口檢查異常!"); System.Environment.Exit(0); //徹底退出應(yīng)用程序 } return list; } #endregion 串口監(jiān)聽 } }
到此這篇關(guān)于C#實(shí)現(xiàn)監(jiān)聽串口數(shù)據(jù)的方法詳解的文章就介紹到這了,更多相關(guān)C#監(jiān)聽串口數(shù)據(jù)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#客戶端程序Visual Studio遠(yuǎn)程調(diào)試的方法詳解
這篇文章主要給大家介紹了關(guān)于C#客戶端程序Visual Studio遠(yuǎn)程調(diào)試的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09c#數(shù)據(jù)綁定之?dāng)?shù)據(jù)轉(zhuǎn)化為信息的示例
這篇文章主要介紹了c#數(shù)據(jù)綁定中的數(shù)據(jù)轉(zhuǎn)化為信息的示例,需要的朋友可以參考下2014-04-04Unity3D實(shí)現(xiàn)分頁系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了Unity3D實(shí)現(xiàn)分頁系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-04-04c#實(shí)現(xiàn)無標(biāo)題欄窗口的拖動
本篇文章是對c#中實(shí)現(xiàn)無標(biāo)題欄窗口拖動的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06詳解C# 泛型中的數(shù)據(jù)類型判定與轉(zhuǎn)換
這篇文章主要介紹了C# 泛型中的數(shù)據(jù)類型判定與轉(zhuǎn)換,文中講解非常細(xì)致,代碼幫助大家更好的理解和學(xué)習(xí),感興趣的朋友可以了解下2020-07-07c#和avascript加解密之間的互轉(zhuǎn)代碼分享
這篇文章主要介紹了c#和Javascript間互轉(zhuǎn)的Xxtea加解密代碼,需要的朋友可以參考下2014-02-02extern外部方法使用C#的實(shí)現(xiàn)方法
這篇文章主要介紹了extern外部方法使用C#的實(shí)現(xiàn)方法,較為詳細(xì)的分析了外部方法使用C#的具體步驟與實(shí)現(xiàn)技巧,具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2014-12-12DataTables List互相轉(zhuǎn)換的實(shí)現(xiàn)類示例
這篇文章主要介紹了將DataTable轉(zhuǎn)換為List,將List轉(zhuǎn)換為DataTable的實(shí)現(xiàn)類實(shí)例方法,大家參考使用吧2013-11-11