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

namespace Telehome.GSM
{
/// <summary>
/// ************************************************************************************
/// 
/// Function: 连接,断开串口;发送,接收串口数据,使用kernel32.dll中相关串口操作
/// 函数对COM口进行操作
/// 
/// Author: Telehome.Hzyong 
/// 
/// DateTime: 2005-11-20
/// 
/// ************************************************************************************
/// </summary>
public class CommPort 
{
/// <summary>
/// 端口名称(COM1,COM2...COM4...)
/// </summary>
public string PortNum;

/// <summary>
/// 波特率9600
/// </summary>
public int BaudRate;

/// <summary>
/// 数据位4-8
/// </summary>
public byte ByteSize;

/// <summary>
/// 奇偶校验0-4=no,odd,even,mark,space 
/// </summary>
public byte Parity;

/// <summary>
/// 停止位
/// </summary>
public byte StopBits; // 0,1,2 = 1, 1.5, 2

/// <summary>
/// 超时长
/// </summary>
public int ReadTimeout;

/// <summary>
/// COM口句柄
/// </summary>
private int hComm = -1;

/// <summary>
/// 串口是否已经打开
/// </summary>
public bool Opened = false;

/// <summary>
/// WINAPI常量,写标志
/// </summary>
private const uint GENERIC_READ = 0x80000000;

/// <summary>
/// WINAPI常量,读标志
/// </summary>
private const uint GENERIC_WRITE = 0x40000000;

/// <summary>
/// WINAPI常量,打开已存在
/// </summary>
private const int OPEN_EXISTING = 3;

/// <summary>
/// WINAPI常量,无效句柄
/// </summary>
private const int INVALID_HANDLE_VALUE = -1;

/// <summary>
/// 设备控制块结构体类型
/// </summary>
[StructLayout(LayoutKind.Sequential)]
public struct DCB
{
/// <summary>
/// DCB长度
/// </summary>
public int DCBlength;
/// <summary>
/// 指定当前波特率
/// </summary>
public int BaudRate; 
/// <summary>
/// 指定是否允许二进制模式
/// </summary>
public int fBinary;
/// <summary>
/// 指定是否允许奇偶校验
/// </summary>
public int fParity;
/// <summary>
/// 指定CTS是否用于检测发送控制,当为TRUE是CTS为OFF,发送将被挂起。
/// </summary>
public int fOutxCtsFlow;
/// <summary>
/// 指定CTS是否用于检测发送控制
/// </summary>
public int fOutxDsrFlow; 
/// <summary>
/// DTR_CONTROL_DISABLE值将DTR置为OFF, DTR_CONTROL_ENABLE值将DTR置为ON, DTR_CONTROL_HANDSHAKE允许DTR"握手"
/// </summary>
public int fDtrControl;
/// <summary>
/// 当该值为TRUE时DSR为OFF时接收的字节被忽略
/// </summary>
public int fDsrSensitivity;
/// <summary>
/// 指定当接收缓冲区已满,并且驱动程序已经发送出XoffChar字符时发送是否停止。
/// TRUE时,在接收缓冲区接收到缓冲区已满的字节XoffLim且驱动程序已经发送出
/// XoffChar字符中止接收字节之后,发送继续进行。 FALSE时,在接收缓冲区接
/// 收到代表缓冲区已空的字节XonChar且驱动程序已经发送出恢复发送的XonChar之
/// 后,发送继续进行。XOFF continues Tx
/// </summary>
public int fTXContinueOnXoff; 
/// <summary>
/// TRUE时,接收到XoffChar之后便停止发送接收到XonChar之后将重新开始 XON/XOFF
/// out flow control 
/// </summary>
public int fOutX;
/// <summary>
/// TRUE时,接收缓冲区接收到代表缓冲区满的XoffLim之后,XoffChar发送出去接收
/// 缓冲区接收到代表缓冲区空的XonLim之后,XonChar发送出去 XON/XOFF in flow control 
/// </summary>
public int fInX;
/// <summary>
/// 该值为TRUE且fParity为TRUE时,用ErrorChar 成员指定的字符代替奇偶校验错误
/// 的接收字符 enable error replacement 
/// </summary>
public int fErrorChar;
/// <summary>
/// eTRUE时,接收时去掉空(0值)字节 enable null stripping 
/// </summary>
public int fNull; 
/// <summary>
/// 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
/// </summary>
public int fRtsControl;
/// <summary>
/// TRUE时,有错误发生时中止读和写操作 abort on error
/// </summary>
public int fAbortOnError;
/// <summary>
/// 未使用
/// </summary>
public int fDummy2;
/// <summary>
/// 标志位
/// </summary>
public uint flags;
/// <summary>
/// 未使用,必须为0
/// </summary>
public ushort wReserved;
/// <summary>
/// 指定在XON字符发送这前接收缓冲区中可允许的最小字节数
/// </summary>
public ushort XonLim;
/// <summary>
/// 指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数
/// </summary>
public ushort XoffLim;
/// <summary>
/// 指定端口当前使用的数据位
/// </summary>
public byte ByteSize;
/// <summary>
/// 指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY 0-4=no,odd,even,mark,space 
/// </summary>
public byte Parity;
/// <summary>
/// 指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS 0,1,2 = 1, 1.5, 2 
/// </summary>
public byte StopBits;
/// <summary>
/// 指定用于发送和接收字符XON的值 Tx and Rx XON character 
/// </summary>
public char XonChar;
/// <summary>
/// 指定用于发送和接收字符XOFF值 Tx and Rx XOFF character 
/// </summary>
public char XoffChar;
/// <summary>
/// 本字符用来代替接收到的奇偶校验发生错误时的值
/// </summary>
public char ErrorChar; 
/// <summary>
/// 当没有使用二进制模式时,本字符可用来指示数据的结束
/// </summary>
public char EofChar;
/// <summary>
/// 当接收到此字符时,会产生一个事件
/// </summary>
public char EvtChar;
/// <summary>
/// 未使用
/// </summary>
public ushort wReserved1; 
}

/// <summary>
/// 串口超时时间结构体类型
/// </summary>
[StructLayout(LayoutKind.Sequential)]
private struct COMMTIMEOUTS 

public int ReadIntervalTimeout; 
public int ReadTotalTimeoutMultiplier; 
public int ReadTotalTimeoutConstant; 
public int WriteTotalTimeoutMultiplier; 
public int WriteTotalTimeoutConstant; 
}

/// <summary>
/// 湓出缓冲区结构体类型
/// </summary>
[StructLayout(LayoutKind.Sequential)] 
private struct OVERLAPPED 

public int Internal; 
public int InternalHigh; 
public int Offset; 
public int OffsetHigh; 
public int hEvent; 
}

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

/// <summary>
/// 得到串口状态
/// </summary>
/// <param name="hFile">通信设备句柄</param>
/// <param name="lpDCB">设备控制块DCB</param>
[DllImport("kernel32.dll")]
private static extern bool GetCommState(int hFile, ref DCB lpDCB);

/// <summary>
/// 建立串口设备控制块
/// </summary>
/// <param name="lpDef">设备控制字符串</param>
/// <param name="lpDCB">设备控制块</param>
[DllImport("kernel32.dll")]
private static extern bool BuildCommDCB(string lpDef, ref DCB lpDCB);

/// <summary>
/// 设置串口状态
/// </summary>
/// <param name="hFile">通信设备句柄</param>
/// <param name="lpDCB">设备控制块</param>
[DllImport("kernel32.dll")]
private static extern bool SetCommState(int hFile, ref DCB lpDCB);

/// <summary>
/// 读取串口超时时间
/// </summary>
/// <param name="hFile">通信设备句柄</param>
/// <param name="lpCommTimeouts">超时时间</param>
[DllImport("kernel32.dll")]
private static extern bool GetCommTimeouts(int hFile, ref COMMTIMEOUTS lpCommTimeouts);

/// <summary>
/// 设置串口超时时间
/// </summary>
/// <param name="hFile">通信设备句柄</param>
/// <param name="lpCommTimeouts">超时时间</param>
[DllImport("kernel32.dll")] 
private static extern bool SetCommTimeouts(int hFile, ref COMMTIMEOUTS lpCommTimeouts);

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

/// <summary>
/// 写串口数据
/// </summary>
/// <param name="hFile">通信设备句柄</param>
/// <param name="lpBuffer">数据缓冲区</param>
/// <param name="nNumberOfBytesToWrite">多少字节等待写入</param>
/// <param name="lpNumberOfBytesWritten">已经写入多少字节</param>
/// <param name="lpOverlapped">溢出缓冲区</param>
[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);

/// <summary>
/// 关闭串口
/// </summary>
/// <param name="hObject">通信设备句柄</param>
[DllImport("kernel32.dll")]
private static extern bool CloseHandle(int hObject);

/// <summary>
/// 得到串口最后一次返回的错误
/// </summary>
[DllImport("kernel32.dll")]
private static extern uint GetLastError();

/// <summary>
/// 建立与串口的连接
/// </summary>
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;
}

/// <summary>
/// 关闭串口,结束通讯
/// </summary>
public void Close() 
{
if (hComm != INVALID_HANDLE_VALUE) 
{
CloseHandle(hComm);
}
}

/// <summary>
/// 读取串口返回的数据
/// </summary>
/// <param name="NumBytes">数据长度</param>
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];
}
}

/// <summary>
/// 清空COM口缓冲区数据
/// </summary>
/// <returns></returns>
public bool ClearPortData()
{
bool result = false;
if (hComm != INVALID_HANDLE_VALUE)
{
result = PurgeComm(hComm, 0);
}
return result;
}

/// <summary>
/// 向串口写数据
/// </summary>
/// <param name="WriteBytes">数据数组</param>
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来进行串口通讯的更多相关文章

  1. advapi32.dll kernel32.dll 中的两套注册表API

    日前遇到一件事:WebBrowser中的网页会用到一个“大众”ActiveX控件,为了保证兼容性以及和其它程序互不干扰,我们采用这样一种方案: 1. 我们的软件会自带该控件: 2. 如果系统中已注册有 ...

  2. C#中的WinFrom技术实现串口通讯助手(附源码)

    C#中的WinFrom技术实现串口通讯助手(附源码)   实现的功能: 1.实现自动加载可用串口. 2.打开串口,并且使用C#状态栏显示串口的状态. 3.实现了串口的接收数据和发送数据功能. 4.串口 ...

  3. WPF - 如何引用external dll中图片

    前几天一直想引用别的DLL里面的一个图片.总是出现各种各样问题,一气之下将图片拷贝到当前Project中,运行良好.虽然知道引用图片,就1.2.列出来的2点就够了. 1. The Build Acti ...

  4. delphi中使用spcomm来实现串口通讯(转载)

    http://blog.sina.com.cn/s/blog_7880f98301010pi8.html 转自——飘雪的世界 最近两天一直在研究spcomm控件的使用,之前也是很不太明白,看了很多的例 ...

  5. Native Application 开发详解(直接在程序中调用 ntdll.dll 中的 Native API,有内存小、速度快、安全、API丰富等8大优点)

    文章目录:                   1. 引子: 2. Native Application Demo 展示: 3. Native Application 简介: 4. Native Ap ...

  6. VB中的API详解

    一.API是什么? 这个我本来不想说的,不过也许你知道其它人不知道,这里为了照顾一下新手,不得不说些废话,请大家谅解. Win32 API即为Microsoft 32位平台的应用程序编程接口(Appl ...

  7. 第22章 DLL注入和API拦截(3)

    22.6 API拦截的一个例子 22.6.1 通过覆盖代码来拦截API (1)实现过程 ①在内存中对要拦截的函数(假设是Kernel32.dll中的ExitProcess)进行定位,从而得到它的内存地 ...

  8. 第22章 DLL注入和API拦截(2)

    22.4 使用远程线程来注入DLL 22.4.1 概述 (1)远程线程注入是指一个进程在另一个进程中创建线程,然后载入我们编写的DLL,并执行该DLL代码的技术.其基本思路是通过CreateRemot ...

  9. [DllImport("kernel32.dll")]是什么意思??

    转载自:http://blog.csdn.net/sp6645597/article/details/8683737 1.简单说明 这叫引入kernel32.dll这个动态连接库(顾名思义就是一个链接 ...

随机推荐

  1. java基础(14):Eclipse、面向对象、自定义数据类型的使用

    1. Eclipse的应用 1. 常用快捷操作 Ctrl+T:查看所选中类的继承树 例如,在下面代码中,选中Teacher类名,然后按Ctrl+T,就会显示出Teacher类的继承关系 //员工 ab ...

  2. Python【day 17】面向对象-成员

    类的变量分成2种: 1.成员变量 概念:在构造方法中的变量,前面带有self 作用:可以在类中不同的方法间使用 2.类变量-静态变量 概念:在类中,构造方法和普通方法之外,定义的变量 作用: 1.调用 ...

  3. QML::Rectangle组件

    QML的Rectangle组件,描绘一个矩形,一个可视化的对象. 外加设置属性来达到我们想要的效果.常用的有矩形的颜色,边框颜色,圆角等设置. Rectangle{ x:10//这里的坐标是相对于它的 ...

  4. ft6236 触摸屏驱动

    在目录下amp\a53_linux\drv\extdrv\touchpad\ft6236下可以看到ft6236.c的文件 1. init函数 static int __init ft_init(voi ...

  5. python踩坑系列之导入包时下划红线及报错“No module named”问题

    python踩坑系列之导入包时下划红线及报错“No module named”问题 使用pycharm编写Python时,自己写了一个包(commontool),在同级另一个路径下(fileshand ...

  6. day74_10_21 三大认证

    一.权限六表. 一般在django中,基于用户权限访问控制的认证是RBAC(Role-Based Access Control) 还有一些基于auth的认证规则. Django框架采用的是RBAC认证 ...

  7. day3_7.1

    1.python的注释 python中为了使代码更容易被人看懂,提高团队开发效率,可使用注释.代码中的注释不加入编译中. 注释有单行注释,如 #这是一段注释 和多行注释: ''' 这是一行注释 ''' ...

  8. Jupyter notebook and Octave kernel installation

    Jupyter notebook 安装 为了更加方便地写 Python 代码,还需要安装 Jupyter notebook. 利用 pip 安装 Jupyter notebook. 为什么要使用 Ju ...

  9. Jenkins配置:添加用户和管理权限

    Jenkins配置:添加用户和管理权限 参考文章:http://www.cnblogs.com/zz0412/p/jenkins_jj_14.html 今天给大家说说使用Jenkins专有用户数据库的 ...

  10. Http响应乱码

    Http响应乱码 方案1 response.setHeader("Content-Type", "application/json"); response.se ...