1. 程式人生 > >串口編程之端口

串口編程之端口

兩種方法 交換 device ons utili sys div sleep ace

軟件程序與硬件通過串口交換數據,首先要知道COM口,但是COM口是由計算機動態隨機分配的。也就是說COM口的編號是變化的。因此我們在編程時不能將COM的編號寫死。針對此問題我們想到的可能是將所有COM口讀出來綁定到下拉框,軟件啟動後從下拉框選擇需要的端口。或者寫到配置文件,軟件啟動前在配置文件配置。不用說這兩種方法都不是很理想。後來通過查詢資料原來COM口的變化會在註冊表中記錄。如圖。

技術分享圖片

這樣我們就有一個想法,能不能通過監控註冊表來監測COM口。於是有了下面代碼。

  1 using Microsoft.Win32;
  2 using System;
  3 using System.Threading;
4 using System.Threading.Tasks; 5 6 namespace AutoTester.Utilities 7 { 8 public class COMListenService 9 { 10 /// <summary> 11 /// COM監聽服務類 12 /// </summary> 13 /// <param name="serialPort">需要監聽的端口</param> 14 //public COMListenService(string serialPort)
15 //{ 16 // _SerialPort = serialPort; 17 //} 18 19 /// <summary> 20 /// 監聽連接狀態事件 21 /// </summary> 22 public event Action<string, bool> ConnectionStatusChanged; 23 24 /// <summary> 25 /// 連接狀態 26 ///
</summary> 27 private bool _connectionStatus; 28 29 /// <summary> 30 /// 連接狀態 31 /// </summary> 32 private bool ConnectionStatus 33 { 34 get { return _connectionStatus; } 35 set 36 { 37 if (_connectionStatus != value) 38 { 39 _connectionStatus = value; 40 ConnectionStatusChanged(_SerialPort, value); 41 } 42 } 43 } 44 45 46 /// <summary> 47 /// 開始監聽 48 /// </summary> 49 public void StartListen() 50 { 51 _TokenSource = new CancellationTokenSource(); 52 53 Task.Factory.StartNew(() => 54 { 55 Listenning(); 56 }); 57 } 58 59 /// <summary> 60 /// 停止監聽 61 /// </summary> 62 public void StopListen() 63 { 64 _TokenSource.Cancel(); 65 } 66 67 /// <summary> 68 /// 監聽端口 69 /// </summary> 70 public void Listenning() 71 { 72 while (true) 73 { 74 Thread.Sleep(ListenFrequency); 75 76 if (_TokenSource.IsCancellationRequested) 77 { 78 break; 79 } 80 81 lock (_Locker) 82 { 83 bool isExist = false; 84 RegistryKey keyCom = Registry.LocalMachine.OpenSubKey(@"Hardware\DeviceMap\SerialComm"); 85 if (keyCom != null) 86 { 87 string[] sSubKeys = keyCom.GetValueNames(); 88 89 foreach (string sName in sSubKeys) 90 { 91 string sValue = string.Empty; 92 93 //if (sValue == _SerialPort) 94 //{ 95 // isExist = true; 96 // break; 97 //} 98 99 if (sName.Contains("ProlificSerial") || sName.ToUpper().Contains("VCP")) 100 { 101 _SerialPort = (string)keyCom.GetValue(sName); 102 isExist = true; 103 break; 104 } 105 } 106 } 107 108 ConnectionStatus = isExist; 109 } 110 } 111 } 112 113 114 private string _SerialPort; 115 private CancellationTokenSource _TokenSource; 116 private const int ListenFrequency = 1000; //監聽頻率(毫秒) 117 private static readonly object _Locker = new object(); 118 } 119 }

(註:ProlificSerial和VCP和你的硬件設備有關,插上你的硬件後觀察註冊表變化)

調用非常簡單,直接上代碼。

1  COMListenService cls = new COMListenService();
2  cls.ConnectionStatusChanged += Cls_ConnectionStatusChanged;
3  cls.StartListen();
 1         /// <summary>
 2         /// 
 3         /// </summary>
 4         /// <param name="comPort"></param>
 5         /// <param name="status"></param>
 6         private static void Cls_ConnectionStatusChanged(string comPort, bool status)
 7         {
 8             if (status)
 9             {
10                 //comPort已插入
11             }
12             else
13             {
14                 //comPort已拔出
15             }
16         }

測試後,完美一切正常。

串口編程之端口