在C#中實現串口通信的方法
通常,在C#中實現串口通信,我們有四種方法:
第一:通過MSCOMM控件這是最簡單的,最方便的方法。可功能上很難做到控制自如,同時這個控件并不是系統本身所帶,所以還得注冊,不在本文討論范圍。可以訪問http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=320 ,一個國外網友的寫的教程,作者很熱心,我曾有發郵件給他,很快就回復了。第二:微軟在.NET新推出了一個串口控件,基于.NET的P/Invoke調用方法實現,詳細的大家可以訪問微軟網站http://msdn.microsoft.com/msdnmag/issues/02/10/NETSerialComm/default.aspx,方便得到更多資料。 第三:就是用第三方控件啦,可一般都要付費的,不太合實際,不作考慮 第四:自己用API寫串口通信,這樣難度高點,但對于我們來說,可以方便實現自己想要的各種功能 在本文,我們采用第四種方法來實現串口通信,不過不是自己寫,用一個國外網友現成的已經封裝好的類庫,不過功能簡單點,相對我們來說已經夠用了。 在整個終端短信的操作過程中,與串口的通信,只用到了四個功能,打開、寫、讀、關閉串口。下面是類庫對這四個功能的定義: 打開串口: 函數原型:public void Open() 說明:打開事先設置好的端口 示例: using JustinIO; static JustinIO.CommPort ss_port = new JustinIO.CommPort(); ss_port.PortNum = COM1; //端口號 ss_port.BaudRate = 19200; //串口通信波特率 ss_port.ByteSize = 8; //數據位 ss_port.Parity = 0; //奇偶校驗 ss_port.StopBits = 1;//停止位 ss_port.ReadTimeout = 1000; //讀超時 try { if (ss_port.Opened) { ss_port.Close(); ss_port.Open(); //打開串口 } else { ss_port.Open();//打開串口 } return true; } catch(Exception e) { MessageBox.Show("錯誤:" + e.Message); return false; } 寫串口: 函數原型:public void Write(byte[] WriteBytes) WriteBytes 就是你的寫入的字節,注意,字符串要轉換成字節數組才能進行通信 示例: ss_port.Write(Encoding.ASCII.GetBytes("AT+CGMI\r")); //獲取手機品牌 讀串口: 函數原型:public byte[] Read(int NumBytes) NumBytes 讀入緩存數,注意讀取來的是字節數組,要實際應用中要進行字符轉換 示例: string response = Encoding.ASCII.GetString(ss_port.Read(128)); //讀取128個字節緩存 關閉串口: 函數原型:ss_port.Close() 示例: ss_port.Close(); 由于篇幅,以及串口通信涉及內容廣泛,我在這里只講這些。 在上面我們已經把終端短信所需的各種原始技術有所了解,是可以小試牛刀的時候了。 </pre>
using System;
using System.Runtime.InteropServices;namespace BusApp { /// <summary> /// /// </summary> public class mycom { public mycom() { // // TODO: 在此處添加構造函數邏輯 // } public int PortNum; //1,2,3,4 public int BaudRate; //1200,2400,4800,9600 public byte ByteSize; //8 bits public byte Parity; // 0-4=no,odd,even,mark,space public byte StopBits; // 0,1,2 = 1, 1.5, 2 public int ReadTimeout; //10 //comm port win32 file handle private int hComm = -1; public bool Opened = false; //win32 api constants private const uint GENERIC_READ = 0x80000000; private const uint GENERIC_WRITE = 0x40000000; private const int OPEN_EXISTING = 3; private const int INVALID_HANDLE_VALUE = -1; [StructLayout(LayoutKind.Sequential)] private struct DCB { //taken from c struct in platform sdk public int DCBlength; // sizeof(DCB) public int BaudRate; // current baud rate public int fBinary; // binary mode, no EOF check public int fParity; // enable parity checking public int fOutxCtsFlow; // CTS output flow control public int fOutxDsrFlow; // DSR output flow control public int fDtrControl; // DTR flow control type public int fDsrSensitivity; // DSR sensitivity public int fTXContinueOnXoff; // XOFF continues Tx public int fOutX; // XON/XOFF out flow control public int fInX; // XON/XOFF in flow control public int fErrorChar; // enable error replacement public int fNull; // enable null stripping public int fRtsControl; // RTS flow control public int fAbortOnError; // abort on error public int fDummy2; // reserved public ushort wReserved; // not currently used public ushort XonLim; // transmit XON threshold public ushort XoffLim; // transmit XOFF threshold public byte ByteSize; // number of bits/byte, 4-8 public byte Parity; // 0-4=no,odd,even,mark,space public byte StopBits; // 0,1,2 = 1, 1.5, 2 public char XonChar; // Tx and Rx XON character public char XoffChar; // Tx and Rx XOFF character public char ErrorChar; // error replacement character public char EofChar; // end of input character public char EvtChar; // received event character public ushort wReserved1; // reserved; do not use } [StructLayout(LayoutKind.Sequential)] private struct COMMTIMEOUTS { public int ReadIntervalTimeout; public int ReadTotalTimeoutMultiplier; public int ReadTotalTimeoutConstant; public int WriteTotalTimeoutMultiplier; public int WriteTotalTimeoutConstant; } [StructLayout(LayoutKind.Sequential)] private struct OVERLAPPED { public int Internal; public int InternalHigh; public int Offset; public int OffsetHigh; public int hEvent; } [DllImport("kernel32.dll")] private static extern int CreateFile( string lpFileName, // file name uint dwDesiredAccess, // access mode int dwShareMode, // share mode int lpSecurityAttributes, // SD int dwCreationDisposition, // how to create int dwFlagsAndAttributes, // file attributes int hTemplateFile // handle to template file ); [DllImport("kernel32.dll")] private static extern bool GetCommState( int hFile, // handle to communications device ref DCB lpDCB // device-control block ); [DllImport("kernel32.dll")] private static extern bool BuildCommDCB( string lpDef, // device-control string ref DCB lpDCB // device-control block ); [DllImport("kernel32.dll")] private static extern bool SetCommState( int hFile, // handle to communications device ref DCB lpDCB // device-control block ); [DllImport("kernel32.dll")] private static extern bool GetCommTimeouts( int hFile, // handle to comm device ref COMMTIMEOUTS lpCommTimeouts // time-out values ); [DllImport("kernel32.dll")] private static extern bool SetCommTimeouts( int hFile, // handle to comm device ref COMMTIMEOUTS lpCommTimeouts // time-out values ); [DllImport("kernel32.dll")] private static extern bool ReadFile( int hFile, // handle to file byte[] lpBuffer, // data buffer int nNumberOfBytesToRead, // number of bytes to read ref int lpNumberOfBytesRead, // number of bytes read ref OVERLAPPED lpOverlapped // overlapped buffer ); [DllImport("kernel32.dll")] private static extern bool WriteFile( int hFile, // handle to file byte[] lpBuffer, // data buffer int nNumberOfBytesToWrite, // number of bytes to write ref int lpNumberOfBytesWritten, // number of bytes written ref OVERLAPPED lpOverlapped // overlapped buffer ); [DllImport("kernel32.dll")] private static extern bool CloseHandle( int hObject // handle to object ); public void Open() { DCB dcbCommPort = new DCB(); COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS(); // OPEN THE COMM PORT. hComm = CreateFile("COM" + PortNum ,GENERIC_READ | GENERIC_WRITE,0, 0,OPEN_EXISTING,0,0); // IF THE PORT CANNOT BE OPENED, BAIL OUT. if(hComm == INVALID_HANDLE_VALUE) { throw(new ApplicationException("Comm Port Can Not Be Opened")); } // SET THE COMM TIMEOUTS. GetCommTimeouts(hComm,ref ctoCommPort); ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout; ctoCommPort.ReadTotalTimeoutMultiplier = 0; ctoCommPort.WriteTotalTimeoutMultiplier = 0; ctoCommPort.WriteTotalTimeoutConstant = 0; SetCommTimeouts(hComm,ref ctoCommPort); // SET BAUD RATE, PARITY, WORD SIZE, AND STOP BITS. // THERE ARE OTHER WAYS OF DOING SETTING THESE BUT THIS IS THE EASIEST. // IF YOU WANT TO LATER ADD CODE FOR OTHER BAUD RATES, REMEMBER // THAT THE ARGUMENT FOR BuildCommDCB MUST BE A POINTER TO A STRING. // ALSO NOTE THAT BuildCommDCB() DEFAULTS TO NO HANDSHAKING. dcbCommPort.DCBlength = Marshal.SizeOf(dcbCommPort); GetCommState(hComm, ref dcbCommPort); dcbCommPort.BaudRate=BaudRate; dcbCommPort.Parity=Parity; dcbCommPort.ByteSize=ByteSize; dcbCommPort.StopBits=StopBits; SetCommState(hComm, ref dcbCommPort); Opened = true; } public void Close() { if (hComm!=INVALID_HANDLE_VALUE) { CloseHandle(hComm); Opened=false; } } public byte[] Read(int NumBytes) { byte[] BufBytes; byte[] OutBytes; BufBytes = new byte[NumBytes]; if (hComm!=INVALID_HANDLE_VALUE) { OVERLAPPED ovlCommPort = new OVERLAPPED(); int BytesRead=0; ReadFile(hComm,BufBytes,NumBytes,ref BytesRead,ref ovlCommPort); OutBytes = new byte[BytesRead]; Array.Copy(BufBytes,OutBytes,BytesRead); } else { throw(new ApplicationException("Comm Port Not Open")); } return OutBytes; } public int Write(byte[] WriteBytes) { int BytesWritten = 0; if (hComm!=INVALID_HANDLE_VALUE) { OVERLAPPED ovlCommPort = new OVERLAPPED(); WriteFile(hComm,WriteBytes,WriteBytes.Length,ref BytesWritten,ref ovlCommPort); } else { throw(new ApplicationException("Comm Port Not Open")); } return BytesWritten; } } } </pre>
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!