C#實(shí)現(xiàn)串口通信詳解
前言
我們知道對(duì)于 標(biāo)準(zhǔn)DLL,可以采用DllImport進(jìn)行調(diào)用。
例如:
[DllImport("KMY350X.dll")] private static extern int OpenPort(int PortNum, int BaudRate);
如果一些廠家比較懶的話,沒有提供相應(yīng)的dll,我們只能對(duì)它進(jìn)行串口通信編程了。
以前從沒接觸過串口編程,最近在一個(gè)項(xiàng)目中有幾個(gè)地方都需要采用串口通信,跟公司一個(gè)老手請(qǐng)教后,感覺學(xué)到了很多東西,特在此做個(gè)總結(jié)。
正文
一、首先我們來認(rèn)識(shí)下什么是串口
右鍵 我的電腦-管理-設(shè)備管理器-端口,選擇一個(gè)端口,點(diǎn)擊屬性。
我們可以看到該串口的屬性,在C#中我們使用SerialPort類來表示串口
ConfigClass config = new ConfigClass(); comm.serialPort.PortName = config.ReadConfig("SendHealCard"); //波特率 comm.serialPort.BaudRate = 9600; //數(shù)據(jù)位 comm.serialPort.DataBits = 8; //兩個(gè)停止位 comm.serialPort.StopBits = System.IO.Ports.StopBits.One; //無奇偶校驗(yàn)位 comm.serialPort.Parity = System.IO.Ports.Parity.None; comm.serialPort.ReadTimeout = 100; comm.serialPort.WriteTimeout = -1;
二、串口調(diào)試工具
在對(duì)串口進(jìn)行編程時(shí)候,我們要向串口發(fā)送指令,然后我們解析串口返回的指令。
在這里向大家推薦一款工具。
將要發(fā)送的指令用空格隔開,選擇HEX顯示為放回的字符串。
三、正式編程
編寫Comm類
public class Comm { public delegate void EventHandle(byte[] readBuffer); public event EventHandle DataReceived; public SerialPort serialPort; Thread thread; volatile bool _keepReading; public Comm() { serialPort = new SerialPort(); thread = null; _keepReading = false; } public bool IsOpen { get { return serialPort.IsOpen; } } private void StartReading() { if (!_keepReading) { _keepReading = true; thread = new Thread(new ThreadStart(ReadPort)); thread.Start(); } } private void StopReading() { if (_keepReading) { _keepReading = false; thread.Join(); thread = null; } } private void ReadPort() { while (_keepReading) { if (serialPort.IsOpen) { int count = serialPort.BytesToRead; if (count > 0) { byte[] readBuffer = new byte[count]; try { Application.DoEvents(); serialPort.Read(readBuffer, 0, count); if(DataReceived != null) DataReceived(readBuffer); Thread.Sleep(100); } catch (TimeoutException) { } } } } } public void Open() { Close(); serialPort.Open(); if (serialPort.IsOpen) { StartReading(); } else { MessageBox.Show("串口打開失敗!"); } } public void Close() { StopReading(); serialPort.Close(); } public void WritePort(byte[] send, int offSet, int count) { if (IsOpen) { serialPort.Write(send, offSet, count); } } }
注冊(cè)串口
Comm comm = new Comm(); ConfigClass config = new ConfigClass(); comm.serialPort.PortName = config.ReadConfig("SendHealCard"); //波特率 comm.serialPort.BaudRate = 9600; //數(shù)據(jù)位 comm.serialPort.DataBits = 8; //兩個(gè)停止位 comm.serialPort.StopBits = System.IO.Ports.StopBits.One; //無奇偶校驗(yàn)位 comm.serialPort.Parity = System.IO.Ports.Parity.None; comm.serialPort.ReadTimeout = 100; ialPort.WriteTimeout = -1; pen(); if (comm.IsOpen) { comm.DataReceived += new Comm.EventHandle(comm_DataReceived); }
發(fā)送指令
/// <summary> /// 發(fā)卡到機(jī)口 /// </summary> private void SendCardToOut() { is_read_card = false; sendCardToOut = true; byte[] send = { 0x02, 0x46, 0x43, 0x34, 0x03, 0x30 }; if (comm.IsOpen) { comm.WritePort(send, 0, send.Length); } }
收到指令,并解析
void comm_DataReceived(byte[] readBuffer1) { //log.Info(HexCon.ByteToString(readBuffer)); if (readBuffer1.Length == 1) { receive = HealCardClass.ByteToString(readBuffer1); string str = "06"; if (string.Equals(receive.Trim(), str, StringComparison.CurrentCultureIgnoreCase)) { try { if (is_read_card) { byte[] send = new byte[1]; send[0] = 0x05; comm.WritePort(send, 0, send.Length); Thread.Sleep(500); comm.DataReceived -= new Comm.EventHandle(comm_DataReceived); InitReadComm(); } if (sendCardToOut) { byte[] send = new byte[1]; send[0] = 0x05; comm.WritePort(send, 0, send.Length); readComm.DataReceived -= new Comm.EventHandle(readComm_DataReceived); readComm.Close(); log.Info("發(fā)卡完成!"); lblMsg.Text = "發(fā)卡成功!"; lblSendCardMsg.Text = "發(fā)卡完成,請(qǐng)收好卡!"; timer1.Tick -= new EventHandler(timer1_Tick); PlaySound(); this.btnOK.Enabled = true; } } catch (Exception ex) { log.Info(ex.ToString()); } } } }
至此,串口通信編程告一段落
最后
到此這篇關(guān)于C#實(shí)現(xiàn)串口通信詳解的文章就介紹到這了,更多相關(guān)C#串口通信內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
使用revit api畫垂直于風(fēng)管的風(fēng)管示例
這篇文章主要介紹了使用revit api畫垂直于風(fēng)管的風(fēng)管示例,需要的朋友可以參考下2014-03-03C#實(shí)現(xiàn)支付寶沙箱支付的項(xiàng)目實(shí)踐
本文主要介紹了C#實(shí)現(xiàn)支付寶沙箱支付的項(xiàng)目實(shí)踐,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-05-05淺析C#數(shù)據(jù)類型轉(zhuǎn)換的幾種形式
本篇文章是對(duì)C#中數(shù)據(jù)類型轉(zhuǎn)換的幾種形式進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-07-07C#使用CefSharp和網(wǎng)頁進(jìn)行自動(dòng)化交互的示例代碼
CefSharp 是一個(gè)用 C# 編寫的開源庫,它封裝了 Google Chrome 瀏覽器的 Chromium 內(nèi)核,CefSharp 允許開發(fā)者在其應(yīng)用程序中嵌入瀏覽器功能,從而能夠展示網(wǎng)頁內(nèi)容、執(zhí)行JavaScript代碼,本文給大家介紹了C#使用CefSharp和網(wǎng)頁進(jìn)行自動(dòng)化交互,需要的朋友可以參考下2024-07-07在WinForm應(yīng)用程序中快速實(shí)現(xiàn)多語言的處理的方法
在國(guó)際化環(huán)境下,越來越多的程序需要做多語言版本,這篇文章主要介紹了在WinForm應(yīng)用程序中快速實(shí)現(xiàn)多語言的處理的方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。2018-07-07C#實(shí)現(xiàn)調(diào)用本機(jī)攝像頭實(shí)例
這篇文章主要介紹了C#實(shí)現(xiàn)調(diào)用本機(jī)攝像頭的方法,可以實(shí)現(xiàn)調(diào)用本機(jī)攝像頭進(jìn)行拍照,具有不錯(cuò)的實(shí)用價(jià)值,需要的朋友可以參考下2014-08-08