串口全稱(chēng)為串行接口,一般指COM接口,是采用串行通信方式的擴(kuò)展接口。其特點(diǎn)是數(shù)據(jù)位的傳送按位順序進(jìn)行,最少只需一根傳輸線即可完成,成本低但傳送速度慢。由于串口(COM)不支持熱插拔及傳輸速率較低,目前部分新主板和大部分便攜電腦已取消該接口?,F(xiàn)在串口多用于工業(yè)控制和測(cè)量設(shè)備以及部分通信設(shè)備中。
根據(jù)美國(guó)電子工業(yè)協(xié)會(huì)(EIA: Electronic Industry Association)制定的標(biāo)準(zhǔn),串口可以分為RS-232、RS-422以及RS-485等種類(lèi),其中以RS-232類(lèi)型的接口最為典型和常見(jiàn),如圖 1所示,是RS-232類(lèi)型9針串口的實(shí)物示意圖。RS-232類(lèi)型9針串口每一個(gè)引腳的作用說(shuō)明如圖 2所示。
當(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)。
下面是我做過(guò)的一個(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)失??!具體原因:” + 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(@“HARDWAREDEVICEMAPSERIALCOMM”);
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)獲取串行口名稱(chēng)
list.Add(com);
}
}
catch
{
DialogForm.Show(“提示信息”, “串行端口檢查異常!”);
System.Environment.Exit(0); //徹底退出應(yīng)用程序
}
return list;
}
#endregion 串口監(jiān)聽(tīng)
}
}
評(píng)論