C#调用API串口通信.doc

上传人:飞****2 文档编号:52735245 上传时间:2022-10-23 格式:DOC 页数:13 大小:71.50KB
返回 下载 相关 举报
C#调用API串口通信.doc_第1页
第1页 / 共13页
C#调用API串口通信.doc_第2页
第2页 / 共13页
点击查看更多>>
资源描述

《C#调用API串口通信.doc》由会员分享,可在线阅读,更多相关《C#调用API串口通信.doc(13页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。

1、c#调api串口通信 分类: C# 在调试ICU通信设备的时候,由于串口通信老出现故障,所以就怀疑CF实现的SerialPort类是否有问题,所以最后决定用纯API函数实现串口读写。先从网上搜索相关代码(关键字:C# API 串口),发现网上相关的资料大约来源于一个版本,那就是所谓的msdn提供的样例代码(msdn的具体出处,我没有考证),其它的代码大都是它的变种。其实这个示例代码是有问题的,也就是说DCB结构体声明的有问题,虽然该代码可以正常通信,不过如果你设置了奇偶校验的话,你会发现奇偶校验无效。VC中的DCB结构声明如下:typedef struct _DCB DWORD DCBleng

2、th; /* sizeof(DCB) */ DWORD BaudRate; /* Baudrate at which running */ DWORD fBinary: 1; /* Binary Mode (skip EOF check) */ DWORD fParity: 1; /* Enable parity checking */ DWORD fOutxCtsFlow:1; /* CTS handshaking on output */ DWORD fOutxDsrFlow:1; /* DSR handshaking on output */ DWORD fDtrControl:2;/*

3、 DTR Flow control */ DWORD fDsrSensitivity:1; /* DSR Sensitivity */ DWORD fTXContinueOnXoff: 1; /* Continue TX when Xoff sent */ DWORD fOutX: 1; /* Enable output X-ON/X-OFF */ DWORD fInX: 1; /* Enable input X-ON/X-OFF */ DWORD fErrorChar: 1;/* Enable Err Replacement */ DWORD fNull: 1; /* Enable Null

4、 stripping */ DWORD fRtsControl:2;/* Rts Flow control */ DWORD fAbortOnError:1; /* Abort all reads and writes on Error */ DWORD fDummy2:17; /* Reserved */ WORD wReserved; /* Not currently used */ WORD XonLim; /* Transmit X-ON threshold */ WORD XoffLim; /* Transmit X-OFF threshold */ BYTE ByteSize; /

5、* Number of bits/byte, 4-8 */ BYTE Parity; /* 0-4=None,Odd,Even,Mark,Space */ BYTE StopBits; /* 0,1,2 = 1, 1.5, 2 */ char XonChar; /* Tx and Rx X-ON character */ char XoffChar; /* Tx and Rx X-OFF character */ char ErrorChar; /* Error replacement char */ char EofChar; /* End of Input character */ cha

6、r EvtChar; /* Received Event character */ WORD wReserved1; /* Fill for now. */ DCB, *LPDCB;有问题的代码DCB结构声明如下:StructLayout(LayoutKind.Sequential) public struct DCB public int DCBlength; public int BaudRate; public int fBinary; public int fParity; public int fOutxCtsFlow; public int fOutxDsrFlow; public

7、 int fDtrControl; public int fDsrSensitivity; public int fTXContinueOnXoff; public int fOutX; public int fInX; public int fErrorChar; public int fNull; public int fRtsControl; public int fAbortOnError; public int fDummy2; public uint flags; public ushort wReserved; public ushort XonLim; public ushor

8、t XoffLim; public byte ByteSize; public byte Parity; public byte StopBits; public byte XonChar; public byte XoffChar; public byte ErrorChar; public byte EofChar; public byte EvtChar; public ushort wReserved1; 对C+比较熟悉网友应该知道,结构体中这种格式的声明,如DWORD fBinary: 1;是以位为单位进行变量设置的,DCB中相关位一共占4个字节,也就是相当于C#中的一个int变量所

9、占的空间。很明显上面的DCB结构会有问题,实际上后面你设置的串口参数,如奇偶校验由于偏移有问题,虽然你设置了,其实都没有设置成功。其实也不是我说人家的DCB声明错了就错了,在SerialPort类中你就可以找到微软官方自己的DCB声明(需要反编译SerialPort类),声明如下:StructLayout(LayoutKind.Sequential) public struct DCB public int DCBlength; public int BaudRate; public uint Flags; public ushort wReserved; public ushort XonL

10、im; public ushort XoffLim; public byte ByteSize; public byte Parity; public byte StopBits; public byte XonChar; public byte XoffChar; public byte ErrorChar; public byte EofChar; public byte EvtChar; public ushort wReserved1; 并且专门有一个设置位标志的函数,如下:internal void SetDcbFlag(int whichFlag, int setting) uin

11、t num; setting = setting whichFlag; if (whichFlag = 4) | (whichFlag = 12) num = 3; else if (whichFlag = 15) num = 0x1ffff; else num = 1; dcb.flags &= (num whichFlag); dcb.flags |= (uint)setting; 经过修改能正确运行的API代码如下(注意,由于我是在WinCE平台上运行,所以DLL的路径为/windows/coredll.dll,你修改为kernel32后即可在PC机使用):/ / API串口类 / pu

12、blic class CommPort / /端口名称(COM1,COM2.COM4.) / public string Port = COM1:; / /波特率9600 / public int BaudRate = 9600; / /数据位4-8 / public byte ByteSize = 8; /4-8 / /奇偶校验0-4=no,odd,even,mark,space / public byte Parity = 0; /0-4=no,odd,even,mark,space / /停止位 / public byte StopBits = 0; /0,1,2 = 1, 1.5, 2

13、 / /超时长 / public int ReadTimeout = 200; / /串口是否已经打开 / public bool Opened = false; / / COM口句柄 / private int hComm = -1; #region API相关定义 private const string DLLPATH = /windows/coredll.dll; / PC机请使用kernel32.dll; / / WINAPI常量,写标志 / private const uint GENERIC_READ = 0x; / / WINAPI常量,读标志 / private const

14、uint GENERIC_WRITE = 0x; / / WINAPI常量,打开已存在 / private const int OPEN_EXISTING = 3; / / WINAPI常量,无效句柄 / private const int INVALID_HANDLE_VALUE = -1; private const int PURGE_RXABORT = 0x2; private const int PURGE_RXCLEAR = 0x8; private const int PURGE_TXABORT = 0x1; private const int PURGE_TXCLEAR = 0

15、x4; / /设备控制块结构体类型 / StructLayout(LayoutKind.Sequential) public struct DCB / / DCB长度 / public int DCBlength; / /指定当前波特率 / public int BaudRate; / /标志位 / public uint flags; / /未使用,必须为0 / public ushort wReserved; / /指定在XON字符发送这前接收缓冲区中可允许的最小字节数 / public ushort XonLim; / /指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数 / pu

16、blic ushort XoffLim; / /指定端口当前使用的数据位 / public byte ByteSize; / /指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY 0-4=no,odd,even,mark,space / public byte Parity; / /指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS 0,1,2 = 1, 1.5, 2 / public byte StopBits; / /指定用于发送和接收字符XON的值 Tx and

17、Rx XON character / public byte XonChar; / /指定用于发送和接收字符XOFF值 Tx and Rx XOFF character / public byte XoffChar; / /本字符用来代替接收到的奇偶校验发生错误时的值 / public byte ErrorChar; / /当没有使用二进制模式时,本字符可用来指示数据的结束 / public byte EofChar; / /当接收到此字符时,会产生一个事件 / public byte EvtChar; / /未使用 / public ushort wReserved1; / /串口超时时间结

18、构体类型 / StructLayout(LayoutKind.Sequential) private struct COMMTIMEOUTS public int ReadIntervalTimeout; public int ReadTotalTimeoutMultiplier; public int ReadTotalTimeoutConstant; public int WriteTotalTimeoutMultiplier; public int WriteTotalTimeoutConstant; / /溢出缓冲区结构体类型 / StructLayout(LayoutKind.Seq

19、uential) private struct OVERLAPPED public int Internal; public int InternalHigh; public int Offset; public int OffsetHigh; public int hEvent; / /打开串口 / /要打开的串口名称 /指定串口的访问方式,一般设置为可读可写方式 /指定串口的共享模式,串口不能共享,所以设置为0 /设置串口的安全属性,WIN9X下不支持,应设为NULL /对于串口通信,创建方式只能为OPEN_EXISTING /指定串口属性与标志,设置为FILE_FLAG_OVERLAPP

20、ED(重叠I/O操作),指定串口以异步方式通信 /对于串口通信必须设置为NULL DllImport(DLLPATH) private static extern int CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode, int lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile); / /得到串口状态 / /通信设备句柄 /设备控制块DCB DllImport(DLLPAT

21、H) private static extern bool GetCommState(int hFile, ref DCB lpDCB); / /建立串口设备控制块(嵌入版没有) / /设备控制字符串 /设备控制块 /DllImport(DLLPATH) /private static extern bool BuildCommDCB(string lpDef, ref DCB lpDCB); / /设置串口状态 / /通信设备句柄 /设备控制块 DllImport(DLLPATH) private static extern bool SetCommState(int hFile, ref

22、DCB lpDCB); / /读取串口超时时间 / /通信设备句柄 /超时时间 DllImport(DLLPATH) private static extern bool GetCommTimeouts(int hFile, ref COMMTIMEOUTS lpCommTimeouts); / /设置串口超时时间 / /通信设备句柄 /超时时间 DllImport(DLLPATH) private static extern bool SetCommTimeouts(int hFile, ref COMMTIMEOUTS lpCommTimeouts); / /读取串口数据 / /通信设备句

23、柄 /数据缓冲区 /多少字节等待读取 /读取多少字节 /溢出缓冲区 DllImport(DLLPATH) private static extern bool ReadFile(int hFile, byte lpBuffer, int nNumberOfBytesToRead, ref int lpNumberOfBytesRead, ref OVERLAPPED lpOverlapped); / /写串口数据 / /通信设备句柄 /数据缓冲区 /多少字节等待写入 /已经写入多少字节 /溢出缓冲区 DllImport(DLLPATH) private static extern bool W

24、riteFile(int hFile, byte lpBuffer, int nNumberOfBytesToWrite, ref int lpNumberOfBytesWritten, ref OVERLAPPED lpOverlapped); DllImport(DLLPATH, SetLastError = true) private static extern bool FlushFileBuffers(int hFile); DllImport(DLLPATH, SetLastError = true) private static extern bool PurgeComm(int

25、 hFile, uint dwFlags); / /关闭串口 / /通信设备句柄 DllImport(DLLPATH) private static extern bool CloseHandle(int hObject); / /得到串口最后一次返回的错误 / DllImport(DLLPATH) private static extern uint GetLastError(); #endregion / /设置DCB标志位 / / / / internal void SetDcbFlag(int whichFlag, int setting, DCB dcb) uint num; set

26、ting = setting whichFlag; if (whichFlag = 4) | (whichFlag = 12) num = 3; else if (whichFlag = 15) num = 0x1ffff; else num = 1; dcb.flags &= (num whichFlag); dcb.flags |= (uint)setting; / /建立与串口的连接 / public int Open() DCB dcb = new DCB(); COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS(); / 打开串口 hComm =

27、CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0); if (hComm = INVALID_HANDLE_VALUE) return -1; / 设置通信超时时间 GetCommTimeouts(hComm, ref ctoCommPort); ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout; ctoCommPort.ReadTotalTimeoutMultiplier = 0; ctoCommPort.WriteTotalTimeoutMultiplier = 0; ctoCommPort.WriteTotalTimeoutConstant = 0; SetCommTimeouts(hComm, ref ctoCommPort);

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 教案示例

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知淘文阁网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号© 2020-2023 www.taowenge.com 淘文阁