C#在WinCE下操作串口的类

 
  1. using System;
  2. using System.Runtime.InteropServices;
  3. using System.Collections.Generic;
  4. using System.Text;
  5. namespace NewPortTest
  6. {
  7.     public class CommPort
  8.     {
  9.         ///<summary>
  10.         ///端口名称(COM1,COM2...COM4...)COM2:
  11.         ///</summary>
  12.         public string Port = "COM1";
  13.         ///<summary>
  14.         ///波特率9600
  15.         ///</summary>
  16.         public int BaudRate = 115200;
  17.         ///<summary>
  18.         ///数据位4-8
  19.         ///</summary>
  20.         public byte ByteSize = 8; //4-8
  21.         ///<summary>
  22.         ///奇偶校验0-4=no,odd,even,mark,space
  23.         ///</summary>
  24.         public byte Parity = 0;   //0-4=no,odd,even,mark,space
  25.         ///<summary>
  26.         ///停止位
  27.         ///</summary>
  28.         public byte StopBits = 0;   //0,1,2 = 1, 1.5, 2
  29.         ///<summary>
  30.         ///超时长
  31.         ///</summary>
  32.         public int ReadTimeout = 200;
  33.         ///<summary>
  34.         ///串口是否已经打开
  35.         ///</summary>
  36.         public bool Opened = false;
  37.         ///<summary>
  38.         /// COM口句柄
  39.         ///</summary>
  40.         private int hComm = -1;
  41.         #region "API相关定义"
  42.         private const string DLLPATH = "//windows//coredll.dll"windows//coredll.dll "kernel32";
  43.         ///<summary>
  44.         /// WINAPI常量,写标志
  45.         ///</summary>
  46.         private const uint GENERIC_READ = 0x80000000;
  47.         ///<summary>
  48.         /// WINAPI常量,读标志
  49.         ///</summary>
  50.         private const uint GENERIC_WRITE = 0x40000000;
  51.         ///<summary>
  52.         /// WINAPI常量,打开已存在
  53.         ///</summary>
  54.         private const int OPEN_EXISTING = 3;
  55.         ///<summary>
  56.         /// WINAPI常量,无效句柄
  57.         ///</summary>
  58.         private const int INVALID_HANDLE_VALUE = -1;
  59.         private const int PURGE_RXABORT = 0x2;
  60.         private const int PURGE_RXCLEAR = 0x8;
  61.         private const int PURGE_TXABORT = 0x1;
  62.         private const int PURGE_TXCLEAR = 0x4;
  63.         ///<summary>
  64.         ///设备控制块结构体类型
  65.         ///</summary>
  66.         [StructLayout(LayoutKind.Sequential)]
  67.         public struct DCB
  68.         {
  69.             ///<summary>
  70.             /// DCB长度
  71.             ///</summary>
  72.             public int DCBlength;
  73.             ///<summary>
  74.             ///指定当前波特率
  75.             ///</summary>
  76.             public int BaudRate;
  77.             ///<summary>
  78.             ///标志位
  79.             ///</summary>
  80.             public uint flags;
  81.             ///<summary>
  82.             ///未使用,必须为0
  83.             ///</summary>
  84.             public ushort wReserved;
  85.             ///<summary>
  86.             ///指定在XON字符发送这前接收缓冲区中可允许的最小字节数
  87.             ///</summary>
  88.             public ushort XonLim;
  89.             ///<summary>
  90.             ///指定在XOFF字符发送这前接收缓冲区中可允许的最小字节数
  91.             ///</summary>
  92.             public ushort XoffLim;
  93.             ///<summary>
  94.             ///指定端口当前使用的数据位
  95.             ///</summary>
  96.             public byte ByteSize;
  97.             ///<summary>
  98.             ///指定端口当前使用的奇偶校验方法,可能为:EVENPARITY,MARKPARITY,NOPARITY,ODDPARITY 0-4=no,odd,even,mark,space
  99.             ///</summary>
  100.             public byte Parity;
  101.             ///<summary>
  102.             ///指定端口当前使用的停止位数,可能为:ONESTOPBIT,ONE5STOPBITS,TWOSTOPBITS 0,1,2 = 1, 1.5, 2
  103.             ///</summary>
  104.             public byte StopBits;
  105.             ///<summary>
  106.             ///指定用于发送和接收字符XON的值 Tx and Rx XON character
  107.             ///</summary>
  108.             public byte XonChar;
  109.             ///<summary>
  110.             ///指定用于发送和接收字符XOFF值 Tx and Rx XOFF character
  111.             ///</summary>
  112.             public byte XoffChar;
  113.             ///<summary>
  114.             ///本字符用来代替接收到的奇偶校验发生错误时的值
  115.             ///</summary>
  116.             public byte ErrorChar;
  117.             ///<summary>
  118.             ///当没有使用二进制模式时,本字符可用来指示数据的结束
  119.             ///</summary>
  120.             public byte EofChar;
  121.             ///<summary>
  122.             ///当接收到此字符时,会产生一个事件
  123.             ///</summary>
  124.             public byte EvtChar;
  125.             ///<summary>
  126.             ///未使用
  127.             ///</summary>
  128.             public ushort wReserved1;
  129.         }
  130.         ///<summary>
  131.         ///串口超时时间结构体类型
  132.         ///</summary>
  133.         [StructLayout(LayoutKind.Sequential)]
  134.         private struct COMMTIMEOUTS
  135.         {
  136.             public int ReadIntervalTimeout;
  137.             public int ReadTotalTimeoutMultiplier;
  138.             public int ReadTotalTimeoutConstant;
  139.             public int WriteTotalTimeoutMultiplier;
  140.             public int WriteTotalTimeoutConstant;
  141.         }
  142.         ///<summary>
  143.         ///溢出缓冲区结构体类型
  144.         ///</summary>
  145.         [StructLayout(LayoutKind.Sequential)]
  146.         private struct OVERLAPPED
  147.         {
  148.             public int Internal;
  149.             public int InternalHigh;
  150.             public int Offset;
  151.             public int OffsetHigh;
  152.             public int hEvent;
  153.         }
  154.         ///<summary>
  155.         ///打开串口
  156.         ///</summary>
  157.         ///<param name="lpFileName">要打开的串口名称</param>
  158.         ///<param name="dwDesiredAccess">指定串口的访问方式,一般设置为可读可写方式</param>
  159.         ///<param name="dwShareMode">指定串口的共享模式,串口不能共享,所以设置为0</param>
  160.         ///<param name="lpSecurityAttributes">设置串口的安全属性,WIN9X下不支持,应设为NULL</param>
  161.         ///<param name="dwCreationDisposition">对于串口通信,创建方式只能为OPEN_EXISTING</param>
  162.         ///<param name="dwFlagsAndAttributes">指定串口属性与标志,设置为FILE_FLAG_OVERLAPPED(重叠I/O操作),指定串口以异步方式通信</param>
  163.         ///<param name="hTemplateFile">对于串口通信必须设置为NULL</param>
  164.         [DllImport(DLLPATH)]
  165.         private static extern int CreateFile(string lpFileName, uint dwDesiredAccess, int dwShareMode,
  166.         int lpSecurityAttributes, int dwCreationDisposition, int dwFlagsAndAttributes, int hTemplateFile);
  167.         ///<summary>
  168.         ///得到串口状态
  169.         ///</summary>
  170.         ///<param name="hFile">通信设备句柄</param>
  171.         ///<param name="lpDCB">设备控制块DCB</param>
  172.         [DllImport(DLLPATH)]
  173.         private static extern bool GetCommState(int hFile, ref DCB lpDCB);
  174.         ///<summary>
  175.         ///建立串口设备控制块(嵌入版没有)
  176.         ///</summary>
  177.         ///<param name="lpDef">设备控制字符串</param>
  178.         ///<param name="lpDCB">设备控制块</param>
  179.         //[DllImport(DLLPATH)]
  180.         //private static extern bool BuildCommDCB(string lpDef, ref DCB lpDCB);
  181.         ///<summary>
  182.         ///设置串口状态
  183.         ///</summary>
  184.         ///<param name="hFile">通信设备句柄</param>
  185.         ///<param name="lpDCB">设备控制块</param>
  186.         [DllImport(DLLPATH)]
  187.         private static extern bool SetCommState(int hFile, ref DCB lpDCB);
  188.         ///<summary>
  189.         ///读取串口超时时间
  190.         ///</summary>
  191.         ///<param name="hFile">通信设备句柄</param>
  192.         ///<param name="lpCommTimeouts">超时时间</param>
  193.         [DllImport(DLLPATH)]
  194.         private static extern bool GetCommTimeouts(int hFile, ref COMMTIMEOUTS lpCommTimeouts);
  195.         ///<summary>
  196.         ///设置串口超时时间
  197.         ///</summary>
  198.         ///<param name="hFile">通信设备句柄</param>
  199.         ///<param name="lpCommTimeouts">超时时间</param>
  200.         [DllImport(DLLPATH)]
  201.         private static extern bool SetCommTimeouts(int hFile, ref COMMTIMEOUTS lpCommTimeouts);
  202.         ///<summary>
  203.         ///读取串口数据
  204.         ///</summary>
  205.         ///<param name="hFile">通信设备句柄</param>
  206.         ///<param name="lpBuffer">数据缓冲区</param>
  207.         ///<param name="nNumberOfBytesToRead">多少字节等待读取</param>
  208.         ///<param name="lpNumberOfBytesRead">读取多少字节</param>
  209.         ///<param name="lpOverlapped">溢出缓冲区</param>
  210.         [DllImport(DLLPATH)]
  211.         private static extern bool ReadFile(int hFile, byte[] lpBuffer, int nNumberOfBytesToRead,
  212.         ref int lpNumberOfBytesRead, ref OVERLAPPED lpOverlapped);
  213.         ///<summary>
  214.         ///写串口数据
  215.         ///</summary>
  216.         ///<param name="hFile">通信设备句柄</param>
  217.         ///<param name="lpBuffer">数据缓冲区</param>
  218.         ///<param name="nNumberOfBytesToWrite">多少字节等待写入</param>
  219.         ///<param name="lpNumberOfBytesWritten">已经写入多少字节</param>
  220.         ///<param name="lpOverlapped">溢出缓冲区</param>
  221.         [DllImport(DLLPATH)]
  222.         private static extern bool WriteFile(int hFile, byte[] lpBuffer, int nNumberOfBytesToWrite,
  223.         ref int lpNumberOfBytesWritten, ref OVERLAPPED lpOverlapped);
  224.         [DllImport(DLLPATH, SetLastError = true)]
  225.         private static extern bool FlushFileBuffers(int hFile);
  226.         [DllImport(DLLPATH, SetLastError = true)]
  227.         private static extern bool PurgeComm(int hFile, uint dwFlags);
  228.         ///<summary>
  229.         ///关闭串口
  230.         ///</summary>
  231.         ///<param name="hObject">通信设备句柄</param>
  232.         [DllImport(DLLPATH)]
  233.         private static extern bool CloseHandle(int hObject);
  234.         ///<summary>
  235.         ///得到串口最后一次返回的错误
  236.         ///</summary>
  237.         [DllImport(DLLPATH)]
  238.         private static extern uint GetLastError();
  239.         #endregion
  240.         ///<summary>
  241.         ///设置DCB标志位
  242.         ///</summary>
  243.         ///<param name="whichFlag"></param>
  244.         ///<param name="setting"></param>
  245.         ///<param name="dcb"></param>
  246.         internal void SetDcbFlag(int whichFlag, int setting, DCB dcb)
  247.         {
  248.             uint num;
  249.             setting = setting << whichFlag;
  250.             if ((whichFlag == 4) || (whichFlag == 12))
  251.             {
  252.                 num = 3;
  253.             }
  254.             else if (whichFlag == 15)
  255.             {
  256.                 num = 0x1ffff;
  257.             }
  258.             else
  259.             {
  260.                 num = 1;
  261.             }
  262.             dcb.flags &= ~(num << whichFlag);
  263.             dcb.flags |= (uint)setting;
  264.         }
  265.         ///<summary>
  266.         ///建立与串口的连接
  267.         ///</summary>
  268.         public int Open()
  269.         {
  270.             DCB dcb = new DCB();
  271.             COMMTIMEOUTS ctoCommPort = new COMMTIMEOUTS();
  272.             // 打开串口
  273.             hComm = CreateFile(Port, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0);
  274.             if (hComm == INVALID_HANDLE_VALUE)
  275.             {
  276.                 return -1;
  277.             }
  278.             // 设置通信超时时间
  279.             GetCommTimeouts(hComm, ref ctoCommPort);
  280.             ctoCommPort.ReadTotalTimeoutConstant = ReadTimeout;
  281.             ctoCommPort.ReadTotalTimeoutMultiplier = 0;
  282.             ctoCommPort.WriteTotalTimeoutMultiplier = 0;
  283.             ctoCommPort.WriteTotalTimeoutConstant = 0;
  284.             SetCommTimeouts(hComm, ref ctoCommPort);
  285.             //设置串口参数
  286.             GetCommState(hComm, ref dcb);
  287.             dcb.DCBlength = Marshal.SizeOf(dcb);
  288.             dcb.BaudRate = BaudRate;
  289.             dcb.flags = 0;
  290.             dcb.ByteSize = (byte)ByteSize;
  291.             dcb.StopBits = StopBits;
  292.             dcb.Parity = (byte)Parity;
  293.             //------------------------------
  294.             SetDcbFlag(0, 1, dcb);            //二进制方式
  295.             SetDcbFlag(1, (Parity == 0) ? 0 : 1, dcb);
  296.             SetDcbFlag(2, 0, dcb);            //不用CTS检测发送流控制
  297.             SetDcbFlag(3, 0, dcb);            //不用DSR检测发送流控制
  298.             SetDcbFlag(4, 0, dcb);            //禁止DTR流量控制
  299.             SetDcbFlag(6, 0, dcb);            //对DTR信号线不敏感
  300.             SetDcbFlag(9, 1, dcb);            //检测接收缓冲区
  301.             SetDcbFlag(8, 0, dcb);            //不做发送字符控制
  302.             SetDcbFlag(10, 0, dcb);           //是否用指定字符替换校验错的字符
  303.             SetDcbFlag(11, 0, dcb);           //保留NULL字符
  304.             SetDcbFlag(12, 0, dcb);           //允许RTS流量控制
  305.             SetDcbFlag(14, 0, dcb);           //发送错误后,继续进行下面的读写操作
  306.             //--------------------------------
  307.             dcb.wReserved = 0;                       //没有使用,必须为0      
  308.             dcb.XonLim = 0;                          //指定在XOFF字符发送之前接收到缓冲区中可允许的最小字节数
  309.             dcb.XoffLim = 0;                         //指定在XOFF字符发送之前缓冲区中可允许的最小可用字节数
  310.             dcb.XonChar = 0;                         //发送和接收的XON字符
  311.             dcb.XoffChar = 0;                        //发送和接收的XOFF字符
  312.             dcb.ErrorChar = 0;                       //代替接收到奇偶校验错误的字符
  313.             dcb.EofChar = 0;                         //用来表示数据的结束     
  314.             dcb.EvtChar = 0;                         //事件字符,接收到此字符时,会产生一个事件       
  315.             dcb.wReserved1 = 0;                      //没有使用
  316.             if (!SetCommState(hComm, ref dcb))
  317.             {
  318.                 return -2;
  319.             }
  320.             Opened = true;
  321.             return 0;
  322.         }
  323.         ///<summary>
  324.         ///关闭串口,结束通讯
  325.         ///</summary>
  326.         public void Close()
  327.         {
  328.             if (hComm != INVALID_HANDLE_VALUE)
  329.             {
  330.                 CloseHandle(hComm);
  331.             }
  332.         }
  333.         ///<summary>
  334.         ///读取串口返回的数据
  335.         ///</summary>
  336.         ///<param name="NumBytes">数据长度</param>
  337.         public int Read(ref byte[] bytData, int NumBytes)
  338.         {
  339.             if (hComm != INVALID_HANDLE_VALUE)
  340.             {
  341.                 OVERLAPPED ovlCommPort = new OVERLAPPED();
  342.                 int BytesRead = 0;
  343.                 ReadFile(hComm, bytData, NumBytes, ref BytesRead, ref ovlCommPort);
  344.                 return BytesRead;
  345.             }
  346.             else
  347.             {
  348.                 return -1;
  349.             }
  350.         }
  351.         public byte[] Readport(int NumBytes)
  352.         {
  353.             byte[] BufBytes;
  354.             byte[] OutBytes;
  355.             BufBytes = new byte[NumBytes];
  356.             if (hComm != INVALID_HANDLE_VALUE)
  357.             {
  358.                 OVERLAPPED ovlCommPort = new OVERLAPPED();
  359.                 int BytesRead = 0;
  360.                 ReadFile(hComm, BufBytes, NumBytes, ref BytesRead, ref ovlCommPort);
  361.                 OutBytes = new byte[BytesRead];
  362.                 Array.Copy(BufBytes, OutBytes, BytesRead);
  363.             }
  364.             else
  365.             {
  366.                 throw (new ApplicationException("串口未打开!"));
  367.             }
  368.             return OutBytes;
  369.         }
  370.         ///<summary>
  371.         ///向串口写数据
  372.         ///</summary>
  373.         ///<param name="WriteBytes">数据数组</param>
  374.         public int Write(byte[] WriteBytes, int intSize)
  375.         {
  376.             if (hComm != INVALID_HANDLE_VALUE)
  377.             {
  378.                 OVERLAPPED ovlCommPort = new OVERLAPPED();
  379.                 int BytesWritten = 0;
  380.                 WriteFile(hComm, WriteBytes, intSize, ref BytesWritten, ref ovlCommPort);
  381.                 return BytesWritten;
  382.             }
  383.             else
  384.             {
  385.                 return -1;
  386.             }
  387.         }
  388.         ///<summary>
  389.         ///清除接收缓冲区
  390.         ///</summary>
  391.         ///<returns></returns>
  392.         public void ClearReceiveBuf()
  393.         {
  394.             if (hComm != INVALID_HANDLE_VALUE)
  395.             {
  396.                 PurgeComm(hComm, PURGE_RXABORT | PURGE_RXCLEAR);
  397.             }
  398.         }
  399.         ///<summary>
  400.         ///清除发送缓冲区
  401.         ///</summary>
  402.         public void ClearSendBuf()
  403.         {
  404.             if (hComm != INVALID_HANDLE_VALUE)
  405.             {
  406.                 PurgeComm(hComm, PURGE_TXABORT | PURGE_TXCLEAR);
  407.             }
  408.         }
  409.     }
  410.    
  411. }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值