引用kernel32.dll中的API來進行串口通訊

来源:https://www.cnblogs.com/leo-navy/archive/2019/09/02/11445923.html
-Advertisement-
Play Games

串口通訊可以引出kernel32.dll中的API來操作,相關源碼如下:using System;using System.Runtime.InteropServices; namespace Telehome.GSM{/// <summary>/// *********************** ...


串口通訊可以引出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


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 上一編講了cap2.6的快速入門,這次我們來講講在控制臺中如何使用cap2.6。因為cap2.6的記憶體模式目前已經可以使用了,相關組件已經更新,所以這次我們以簡單的記憶體模式為例。 1:創建項目 創建一個名叫CAPConsoleDemo的 “控制台應用(.NET Core)” 程式,.netcore版 ...
  • @[toc] 前言 這幾天忙活著別的東西,耽誤了很長時間,從文件操作完了之後就在考慮著下一步鼓搗點兒啥,因為最開始的業務開發就是企業微信相關的,這剛好來做個內部應用的小例子玩玩。 企業微信 前身是企業號,當時微信主推的還是公眾號與服務號,後續戰略考慮到企業的OA了(當然還是跟某個搶市場),企業號應該 ...
  • 程式出現 System.AccessViolationException異常會終止進程,try catch是無法捕捉的。 有個處理方法在引發異常的發放上面加上 [System.Runtime.ExceptionServices.HandleProcessCorruptedStateException ...
  • 前提 入行已經7,8年了,一直想做一套漂亮點的自定義控制項,於是就有了本系列文章。 GitHub:https://github.com/kwwwvagaa/NetWinformControl 碼雲:https://gitee.com/kwwwvagaa/net_winform_custom_contr ...
  • ASP.NET Core 進程外(out-of-process)托管 在本節中,我們將討論 ASP.NET Core 中的Out Of Process Hosting。 ASP.NET Core 進程內(InProcess)托管 我們先簡單回顧下 ASP.NET Core 中,要配置 InProce ...
  • Core3的 SDK下載地址是:https://dotnet.microsoft.com/download/dotnet-core/3.0 ! 不要下載preview8!!!,請先下載 preview7,preview7,preview7主要的說3遍,少走彎路!!!64/32位的操作系統自己確認好! ...
  • 一、獲取預設的控制項模板 WPF修改控制項模板是修改外觀最方便的方式,但是會出現不知道原來的控制項的模板長什麼樣,或者想用來參考的,下麵分享一下獲取某控制項預設控制項模板的方式(已Button為例): 1、創建一個Button 2、在界面上選擇Button,右鍵->編輯模板->編輯副本 ,即可看到XAML中自 ...
  • 場景 Winform中實現ZedGraph的多條Y軸(附源碼下載): https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/100132245 在上面實現可以新增多條Y軸之後,實現新增自定義Y軸。 在新增窗體中設置Y軸的屬性,用到以上幾個 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...