C#實現(xiàn)監(jiān)聽串口數(shù)據(jù)的方法詳解
在C#中,接收COM端口(串口)報文通常涉及到使用System.IO.Ports.SerialPort
類,并對接收到的字節(jié)數(shù)據(jù)進行處理和格式轉換。下面是一個基本的流程,描述了如何在C#中接收和轉換COM端口報文:
步驟 1: 引用命名空間
首先,確保你的項目引用了處理串口通信所需的命名空間:
using System.IO.Ports;
步驟 2: 設置 SerialPort 對象
創(chuàng)建SerialPort
對象并設置串口的配置參數(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; // 設置讀寫時間超時 mySerialPort.ReadTimeout = 500; mySerialPort.WriteTimeout = 500;
步驟 3: 打開串口
mySerialPort.Open();
步驟 4: 接收數(shù)據(jù)
你可以使用DataReceived
事件來處理接收到的數(shù)據(jù)。當串口接收到數(shù)據(jù)時,這個事件會被觸發(fā):
mySerialPort.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
實現(xiàn)事件處理函數(shù)DataReceivedHandler
來讀取數(shù)據(jù)并進行處理:
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ù)處理和格式轉換邏輯 string formattedData = ConvertToDesiredFormat(buffer); // 處理轉換后的數(shù)據(jù) ProcessData(formattedData); }
步驟 5: 轉換格式
創(chuàng)建函數(shù)ConvertToDesiredFormat
來實現(xiàn)將接收到的字節(jié)數(shù)據(jù)轉換為你需要的格式。這里的實現(xiàn)取決于你的具體需求:
private static string ConvertToDesiredFormat(byte[] data) { // 舉例:將字節(jié)數(shù)據(jù)轉換為ASCII字符串 return Encoding.ASCII.GetString(data); // 注意:如果數(shù)據(jù)是特定協(xié)議格式,你需要根據(jù)協(xié)議解析并轉換數(shù)據(jù) }
步驟 6: 關閉串口
當數(shù)據(jù)處理完成后,記得關閉串口以釋放資源:
mySerialPort.Close();
注意事項
- 確保你有適當?shù)臋嘞迊碓L問COM端口。
- 上面的代碼片段是一個簡化的例子。實際應用中,你可能需要根據(jù)具體的通信協(xié)議來處理和驗證數(shù)據(jù)(如計算校驗和、處理數(shù)據(jù)幀等)。
- 如果通信過程中可能出現(xiàn)讀寫沖突或其他線程安全問題,考慮使用鎖(如
lock
語句)來同步訪問串口資源。
配置完成后,程序就可以監(jiān)聽指定的COM端口,并在接收到數(shù)據(jù)時進行處理和轉換了。記得在實際部署前,充分測試你的代碼以確保它能夠可靠地處理實際的通信場景。
知識補充
除了上文的內容,小編還為大家整理了C#實現(xiàn)串口數(shù)據(jù)偵聽的相關方法,希望對大家有所幫助
當需要編程操縱硬件時會遇到過這樣的問題,就是通過串口來接收硬件發(fā)來的數(shù)據(jù),或是通過串口向硬件發(fā)送某種格式的命令。在C#平臺上,可以通過 System.IO.Ports 命名空間下的SerialPort 類來實現(xiàn)。
下面是一個簡單的示例,首先獲取本機關聯(lián)的串行端口列表,然后獲取配置文件中配置的COM端口,檢查是否在本機串行端口列表中,若在列表中則進一步實例化串口對象,并為串口對象指定數(shù)據(jù)接收事件來實現(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); //首先獲取本機關聯(lián)的串行端口列表 if (comList.Count == 0) { DialogForm.Show("提示信息", "當前設備不存在串行端口!"); System.Environment.Exit(0); //徹底退出應用程序 } else { string targetCOMPort = ConfigurationManager.AppSettings["COMPort"].ToString(); //判斷串口列表中是否存在目標串行端口 if (!comList.Contains(targetCOMPort)) { DialogForm.Show("提示信息", "當前設備不存在配置的串行端口!"); System.Environment.Exit(0); //徹底退出應用程序 } serialPort = new SerialPort(); //設置參數(shù) serialPort.PortName = ConfigurationManager.AppSettings["COMPort"].ToString(); //通信端口 serialPort.BaudRate = Int32.Parse(ConfigurationManager.AppSettings["BaudRate"].ToString()); //串行波特率 serialPort.DataBits = 8; //每個字節(jié)的標準數(shù)據(jù)位長度 serialPort.StopBits = StopBits.One; //設置每個字節(jié)的標準停止位數(shù) serialPort.Parity = Parity.None; //設置奇偶校驗檢查協(xié)議 serialPort.ReadTimeout = 3000; //單位毫秒 serialPort.WriteTimeout = 3000; //單位毫秒 //串口控件成員變量,字面意思為接收字節(jié)閥值, //串口對象在收到這樣長度的數(shù)據(jù)之后會觸發(fā)事件處理函數(shù) //一般都設為1 serialPort.ReceivedBytesThreshold = 1; serialPort.DataReceived += new SerialDataReceivedEventHandler(CommDataReceived); //設置數(shù)據(jù)接收事件(監(jiān)聽) try { serialPort.Open(); //打開串口 } catch (Exception ex) { DialogForm.Show("提示信息", "串行端口打開失?。【唧w原因:" + ex.Message); System.Environment.Exit(0); //徹底退出應用程序 } } } /// <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); //獲取出入庫產品編號 DialogForm.Show("接收到的信息", msg); } catch(Exception ex) { DialogForm.Show("提示信息", "接收返回消息異常!具體原因:" + ex.Message); } } /// <summary> /// 關閉串口 /// </summary> private void Stop() { serialPort.Close(); } /// <summary> /// 獲取本機串口列表 /// </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); //徹底退出應用程序 } return list; } #endregion 串口監(jiān)聽 } }
到此這篇關于C#實現(xiàn)監(jiān)聽串口數(shù)據(jù)的方法詳解的文章就介紹到這了,更多相關C#監(jiān)聽串口數(shù)據(jù)內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
c#數(shù)據(jù)綁定之數(shù)據(jù)轉化為信息的示例
這篇文章主要介紹了c#數(shù)據(jù)綁定中的數(shù)據(jù)轉化為信息的示例,需要的朋友可以參考下2014-04-04DataTables List互相轉換的實現(xiàn)類示例
這篇文章主要介紹了將DataTable轉換為List,將List轉換為DataTable的實現(xiàn)類實例方法,大家參考使用吧2013-11-11