일반적으로 C#에서 직렬 포트 통신을 구현하는 방법에는 네 가지가 있습니다.
첫째: MSCOMM 제어를 통한 가장 간단하고 편리한 방법입니다. 그러나 기능을 자유롭게 제어하는 것은 어렵습니다. 동시에 이 제어는 시스템 자체에 포함되어 있지 않으므로 등록이 필요하므로 이 기사의 범위를 벗어납니다. 한 외국 네티즌이 작성한 튜토리얼인 http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=320을 방문해 보세요. 저자는 매우 열성적으로 이메일을 보냈고 그는 신속하게 응답했습니다.
두 번째: Microsoft는 .NET의 P/Invoke 호출 방법을 기반으로 구현된 새로운 직렬 포트 제어를 .NET에서 출시했습니다. 자세한 내용은 Microsoft 웹사이트(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+CGMIr")) //휴대폰 브랜드 가져오기
직렬 포트 읽기:
함수 프로토타입: public byte[] Read(int NumBytes)
NumBytes 캐시 번호 읽기 , 읽기는 바이트 배열이므로 실제 응용 프로그램에서는 문자 변환이 필요합니다
예:
문자열 응답 = Encoding.ASCII. GetString(ss_port .Read(128)); //128바이트 버퍼 읽기
직렬 포트 닫기:
함수 프로토타입: ss_port. Close( )
예:
ss_port.Close()
길이로 인해 직렬 포트 통신은 광범위한 주제를 다루고 있으며 여기서는 이에 대해서만 다루겠습니다.
이미 SMS 단말기에 필요한 다양한 원시 기술을 이해했으며 이제 우리의 기술을 시험해 볼 시간입니다.
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; } } }