引用kernel32.dll中的API来进行串口通讯

2021-02-05 08:15

阅读:629

标签:number   character   attribute   串口通信   dsr   异步   关闭   template   成员   

串口通讯可以引出kernel32.dll中的API来操作,相关源码如下:
using System;
using System.Runtime.InteropServices;

namespace Telehome.GSM
{
///


/// ************************************************************************************
/// 
/// Function: 连接,断开串口;发送,接收串口数据,使用kernel32.dll中相关串口操作
/// 函数对COM口进行操作
/// 
/// Author: Telehome.Hzyong 
/// 
/// DateTime: 2005-11-20
/// 
/// ************************************************************************************
///

public class CommPort 
{
///
/// 端口名称(COM1,COM2...COM4...)
///

public string PortNum;

///


/// 波特率9600
///

public int BaudRate;

///


/// 数据位4-8
///

public byte ByteSize;

///


/// 奇偶校验0-4=no,odd,even,mark,space 
///

public byte Parity;

///


/// 停止位
///

public byte StopBits; // 0,1,2 = 1, 1.5, 2

///


/// 超时长
///

public int ReadTimeout;

///


/// COM口句柄
///

private int hComm = -1;

///


/// 串口是否已经打开
///

public bool Opened = false;

///


/// WINAPI常量,写标志
///

private const uint GENERIC_READ = 0x80000000;

///


/// WINAPI常量,读标志
///

private const uint GENERIC_WRITE = 0x40000000;

///


/// WINAPI常量,打开已存在
///

private const int OPEN_EXISTING = 3;

///


/// WINAPI常量,无效句柄
///

private const int INVALID_HANDLE_VALUE = -1;

///


/// 设备控制块结构体类型
///

[StructLayout(LayoutKind.Sequential)]
public struct DCB
{
///
/// DCB长度
///

public int DCBlength;
///
/// 指定当前波特率
///

public int BaudRate; 
///
/// 指定是否允许二进制模式
///

public int fBinary;
///
/// 指定是否允许奇偶校验
///

public int fParity;
///
/// 指定CTS是否用于检测发送控制,当为TRUE是CTS为OFF,发送将被挂起。
///

public int fOutxCtsFlow;
///
/// 指定CTS是否用于检测发送控制
///

public int fOutxDsrFlow; 
///
/// DTR_CONTROL_DISABLE值将DTR置为OFF, DTR_CONTROL_ENABLE值将DTR置为ON, DTR_CONTROL_HANDSHAKE允许DTR"握手"
///

public int fDtrControl;
///
/// 当该值为TRUE时DSR为OFF时接收的字节被忽略
///

public int fDsrSensitivity;
///
/// 指定当接收缓冲区已满,并且驱动程序已经发送出XoffChar字符时发送是否停止。
/// TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动程序已经发送出
/// XoffChar字符中止接收字节之后,发送继续进行。 FALSE时,在接收缓冲区接
/// 收到代表缓冲区已空的字节XonChar且驱动程序已经发送出恢复发送的XonChar之
/// 后,发送继续进行。XOFF continues Tx
///

public int fTXContinueOnXoff; 
///
/// TRUE时,接收到XoffChar之后便停止发送接收到XonChar之后将重新开始 XON/XOFF
/// out flow control 
///

public int fOutX;
///
/// TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去接收
/// 缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去 XON/XOFF in flow control 
///

public int fInX;
///
/// 该值为TRUE且fParity为TRUE时,用ErrorChar 成员指定的字符代替奇偶校验错误
/// 的接收字符 enable error replacement 
///

public int fErrorChar;
///
/// eTRUE时,接收时去掉空(0值)字节 enable null stripping 
///

public int fNull; 
///
/// RTS flow control RTS_CONTROL_DISABLE时,RTS置为OFF RTS_CONTROL_ENABLE时, RTS置为ON
/// RTS_CONTROL_HANDSHAKE时,当接收缓冲区小于半满时RTS为ON当接收缓冲区超过四分之
/// 三满时RTS为OFF RTS_CONTROL_TOGGLE时,当接收缓冲区仍有剩余字节时RTS为ON ,否则
/// 缺省为OFF
///

public int fRtsControl;
///
/// TRUE时,有错误发生时中止读和写操作 abort on error
///

public int fAbortOnError;
///
/// 未使用
///

public int fDummy2;
///
/// 标志位
///

public uint flags;
///
/// 未使用,必须为0
///

public ushort wReserved;
///
/// 指定在XON字符发送这前接收缓冲区中可允许的最小字节数
///

public ushort XonLim;
///
/// 指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数
///

public 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 Rx XON character 
///

public char XonChar;
///
/// 指定用于发送和接收字符XOFF值 Tx and Rx XOFF character 
///

public char XoffChar;
///
/// 本字符用来代替接收到的奇偶校验发生错误时的值
///

public char ErrorChar; 
///
/// 当没有使用二进制模式时,本字符可用来指示数据的结束
///

public char EofChar;
///
/// 当接收到此字符时,会产生一个事件
///

public char EvtChar;
///
/// 未使用
///

public ushort wReserved1; 
}

///


/// 串口超时时间结构体类型
///

[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; 
}

///


/// 打开串口
///

/// 要打开的串口名称
/// 指定串口的访问方式,一般设置为可读可写方式
/// 指定串口的共享模式,串口不能共享,所以设置为0
/// 设置串口的安全属性,WIN9X下不支持,应设为NULL
/// 对于串口通信,创建方式只能为OPEN_EXISTING
/// 指定串口属性与标志,设置为FILE_FLAG_OVERLAPPED(重叠I/O操作),指定串口以异步方式通信
/// 对于串口通信必须设置为NULL
[DllImport("kernel32.dll")]
private static extern int CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode,
int lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile);

///


/// 得到串口状态
///

/// 通信设备句柄
/// 设备控制块DCB
[DllImport("kernel32.dll")]
private static extern bool GetCommState(int hFile, ref DCB lpDCB);

///


/// 建立串口设备控制块
///

/// 设备控制字符串
/// 设备控制块
[DllImport("kernel32.dll")]
private static extern bool BuildCommDCB(string lpDef, ref DCB lpDCB);

///


/// 设置串口状态
///

/// 通信设备句柄
/// 设备控制块
[DllImport("kernel32.dll")]
private static extern bool SetCommState(int hFile, ref DCB lpDCB);

///


/// 读取串口超时时间
///

/// 通信设备句柄
/// 超时时间
[DllImport("kernel32.dll")]
private static extern bool GetCommTimeouts(int hFile, ref COMMTIMEOUTS lpCommTimeouts);

///


/// 设置串口超时时间
///

/// 通信设备句柄
/// 超时时间
[DllImport("kernel32.dll")] 
private static extern bool SetCommTimeouts(int hFile, ref COMMTIMEOUTS lpCommTimeouts);

///


/// 读取串口数据
///

/// 通信设备句柄
/// 数据缓冲区
/// 多少字节等待读取
/// 读取多少字节
/// 溢出缓冲区
[DllImport("kernel32.dll")]
private static extern bool ReadFile(int hFile, byte[] lpBuffer, int nNumberOfBytesToRead,
ref int lpNumberOfBytesRead, ref OVERLAPPED lpOverlapped);

///


/// 写串口数据
///

/// 通信设备句柄
/// 数据缓冲区
/// 多少字节等待写入
/// 已经写入多少字节
/// 溢出缓冲区
[DllImport("kernel32.dll")] 
private static extern bool WriteFile(int hFile, byte[] lpBuffer, int nNumberOfBytesToWrite,
ref int lpNumberOfBytesWritten, ref OVERLAPPED lpOverlapped);

[DllImport("kernel32.dll", SetLastError=true)]
private static extern bool FlushFileBuffers(int hFile);

[DllImport("kernel32.dll", SetLastError=true)]
private static extern bool PurgeComm(int hFile, uint dwFlags);

///


/// 关闭串口
///

/// 通信设备句柄
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(int hObject);

///


/// 得到串口最后一次返回的错误
///

[DllImport("kernel32.dll")]
private static extern uint GetLastError();

///


/// 建立与串口的连接
///

public void Open()
{

DCB dcbCommPort = new DCB();
COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS();

// 打开串口 
hComm = CreateFile(PortNum ,GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);

if(hComm == INVALID_HANDLE_VALUE) 
{
return;
}

// 设置通信超时时间
GetCommTimeouts(hComm, ref ctoCommPort);
ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout;
ctoCommPort.ReadTotalTimeoutMultiplier = 0;
ctoCommPort.WriteTotalTimeoutMultiplier = 0;
ctoCommPort.WriteTotalTimeoutConstant = 0; 
SetCommTimeouts(hComm, ref ctoCommPort);

// 设置串口
GetCommState(hComm, ref dcbCommPort);
dcbCommPort.fOutxCtsFlow = 524800;
dcbCommPort.BaudRate = BaudRate;
dcbCommPort.flags = 0;
dcbCommPort.flags |= 1;
if (Parity > 0)
{
dcbCommPort.flags |= 2;
}
dcbCommPort.Parity = Parity;
dcbCommPort.ByteSize = ByteSize;
dcbCommPort.StopBits = StopBits;
dcbCommPort.fOutxCtsFlow = 524800; 
if (!SetCommState(hComm, ref dcbCommPort))
{
return;
}
Opened = true;
}

///


/// 关闭串口,结束通讯
///

public void Close() 
{
if (hComm != INVALID_HANDLE_VALUE) 
{
CloseHandle(hComm);
}
}

///


/// 读取串口返回的数据
///

/// 数据长度
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);
return OutBytes;

else
{
return new byte [0];
}
}

///


/// 清空COM口缓冲区数据
///

///
public bool ClearPortData()
{
bool result = false;
if (hComm != INVALID_HANDLE_VALUE)
{
result = PurgeComm(hComm, 0);
}
return result;
}

///


/// 向串口写数据
///

/// 数据数组
public bool Write(byte[] WriteBytes) 
{
bool result;
if (hComm != INVALID_HANDLE_VALUE) 
{
OVERLAPPED ovlCommPort = new OVERLAPPED();
int BytesWritten = 0;
WriteFile(hComm, WriteBytes, WriteBytes.Length, ref BytesWritten, ref ovlCommPort);
result = true;
}
else
{
result = false;
}
return result;
}
}
}

转自

https://www.xuebuyuan.com/841503.html

引用kernel32.dll中的API来进行串口通讯

标签:number   character   attribute   串口通信   dsr   异步   关闭   template   成员   

原文地址:https://www.cnblogs.com/leo-navy/p/11445923.html

上一篇:WPF简介

下一篇:delphi实现圆角窗体[转]


评论


亲,登录后才可以留言!