silverlight5 OOB 直接p/invoke实现串口通信
public class SerialWrapper : IDisposable
{
#region Enum
public enum StopBits
{
None,
One,
Two,
OnePointFive,
}
public enum Parity
{
None,
Odd,
Even,
Mark,
Space,
}
#endregion
#region Fields
/// <summary>
/// The baud rate at which the communications device operates.
/// </summary>
private readonly int iBaudRate;
/// <summary>
/// The number of bits in the bytes to be transmitted and received.
/// </summary>
private readonly byte byteSize;
/// <summary>
/// The system handle to the serial port connection ('file' handle).
/// </summary>
private IntPtr pHandle = IntPtr.Zero;
/// <summary>
/// The parity scheme to be used.
/// </summary>
private readonly Parity parity;
/// <summary>
/// The name of the serial port to connect to.
/// </summary>
private readonly string sPortName;
/// <summary>
/// The number of bits in the bytes to be transmitted and received.
/// </summary>
private readonly StopBits stopBits;
#endregion
#region Constructor
/// <summary>
/// Creates a new instance of SerialCom.
/// </summary>
/// <param>The name of the serial port to connect to</param>
/// <param>The baud rate at which the communications device operates</param>
/// <param>The number of stop bits to be used</param>
/// <param>The parity scheme to be used</param>
/// <param>The number of bits in the bytes to be transmitted and received</param>
public SerialWrapper(string portName, int baudRate, StopBits stopBits, Parity parity, byte byteSize)
{
if (stopBits == StopBits.None)
throw new ArgumentException("stopBits cannot be StopBits.None", "stopBits");
if (byteSize < 5 || byteSize > 8)
throw new ArgumentOutOfRangeException("The number of data bits must be 5 to 8 bits.", "byteSize");
if (baudRate < 110 || baudRate > 256000)
throw new ArgumentOutOfRangeException("Invalid baud rate specified.", "baudRate");
if ((byteSize == 5 && stopBits == StopBits.Two) || (stopBits == StopBits.OnePointFive && byteSize > 5))
throw new ArgumentException("The use of 5 data bits with 2 stop bits is an invalid combination, " +
"as is 6, 7, or 8 data bits with 1.5 stop bits.");
this.sPortName = portName;
this.iBaudRate = baudRate;
this.byteSize = byteSize;
this.stopBits = stopBits;
this.parity = parity;
}
/// <summary>
/// Creates a new instance of SerialCom.
/// </summary>
/// <param>The name of the serial port to connect to</param>
/// <param>The baud rate at which the communications device operates</param>
/// <param>The number of stop bits to be used</param>
/// <param>The parity scheme to be used</param>
public SerialWrapper(string portName, int baudRate, StopBits stopBits, Parity parity)
: this(portName, baudRate, stopBits, parity, 8)
{
}
#endregion
#region Open
/// <summary>
/// Opens and initializes the serial connection.
/// </summary>
/// <returns>Whether or not the operation succeeded</returns>
public bool Open()
{
pHandle = CreateFile(this.sPortName, FileAccess.ReadWrite, FileShare.None,
IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
if (pHandle == IntPtr.Zero) return false;
if (ConfigureSerialPort()) return true;
else
{
Dispose();
return false;
}
}
#endregion
#region Write
/// <summary>
/// Transmits the specified array of bytes.
/// </summary>
/// <param>The bytes to write</param>
/// <returns>The number of bytes written (-1 if error)</returns>
public int Write(byte[] data)
{
FailIfNotConnected();
if (data == null) return 0;
int bytesWritten;
if (WriteFile(pHandle, data, data.Length, out bytesWritten, 0))
return bytesWritten;
return -1;
}
/// <summary>
/// Transmits the specified string.
/// </summary>
/// <param>The string to write</param>
/// <returns>The number of bytes written (-1 if error)</returns>
public int Write(string data)
{
FailIfNotConnected();
// convert the string to bytes
byte[] bytes;
if (data == null)
{
bytes = null;
}
else
{
bytes = Encoding.UTF8.GetBytes(data);
}
return Write(bytes);
}
/// <summary>
/// Transmits the specified string and appends the carriage return to the end
/// if it does not exist.
/// </summary>
/// <remarks>
/// Note that the string must end in '\r\n' before any serial device will interpret the data
/// sent. For ease of programmability, this method should be used instead of Write() when you
/// want to automatically execute the specified command string.
/// </remarks>
/// <param>The string to write</param>
/// <returns>The number of bytes written (-1 if error)</returns>
public int WriteLine(string data)
{
if (data != null && !data.EndsWith("\r\n"))
data += "\r\n";
return Write(data);
}
#endregion
#region Read
/// <summary>
/// Reads any bytes that have been received and writes them to the specified array.
/// </summary>
/// <param>The array to write the read data to</param>
/// <returns>The number of bytes read (-1 if error)</returns>
public int Read(byte[] data)
{
FailIfNotConnected();
if (data == null) return 0;
int bytesRead;
if (ReadFile(pHandle, data, data.Length, out bytesRead, 0))
return bytesRead;
return -1;
}
/// <summary>
/// Reads any data that has been received as a string.
/// </summary>
/// <param>The maximum number of bytes to read</param>
/// <returns>The data received (null if no data)</returns>
public string ReadString(int maxBytesToRead)
{
if (maxBytesToRead < 1) throw new ArgumentOutOfRangeException("maxBytesToRead");
byte[] bytes = new byte[maxBytesToRead];
int numBytes = Read(bytes);
//string data = ASCIIEncoding.ASCII.GetString(bytes, 0, numBytes);
string data = Encoding.UTF8.GetString(bytes, 0, numBytes);
return data;
}
#endregion
#region Dispose Utils
/// <summary>
/// Disconnects and disposes of the SerialCom instance.
/// </summary>
public void Dispose()
{
if (pHandle != IntPtr.Zero)
{
CloseHandle(pHandle);
pHandle = IntPtr.Zero;
}
}
/// <summary>
/// Flushes the serial I/O buffers.
/// </summary>
/// <returns>Whether or not the operation succeeded</returns>
public bool Flush()
{
FailIfNotConnected();
const int PURGE_RXCLEAR = 0x0008; // input buffer
const int PURGE_TXCLEAR = 0x0004; // output buffer
return PurgeComm(pHandle, PURGE_RXCLEAR | PURGE_TXCLEAR);
}
#endregion
#region Private Helpers
/// <summary>
/// Configures the serial device based on the connection parameters pased in by the user.
/// </summary>
/// <returns>Whether or not the operation succeeded</returns>
private bool ConfigureSerialPort()
{
DCB serialConfig = new DCB();
if (GetCommState(pHandle, ref serialConfig))
{
// setup the DCB struct with the serial settings we need
serialConfig.BaudRate = (uint)this.iBaudRate;
serialConfig.ByteSize = this.byteSize;
serialConfig.fBinary = 1; // must be true
serialConfig.fDtrControl = 1; // DTR_CONTROL_ENABLE "Enables the DTR line when the device is opened and leaves it on."
serialConfig.fAbortOnError = 0; // false
serialConfig.fTXContinueOnXoff = 0; // false
serialConfig.fParity = 1; // true so that the Parity member is looked at
switch (this.parity)
{
case Parity.Even:
serialConfig.Parity = 2;
break;
case Parity.Mark:
serialConfig.Parity = 3;
break;
case Parity.Odd:
serialConfig.Parity = 1;
break;
case Parity.Space:
serialConfig.Parity = 4;
break;
case Parity.None:
default:
serialConfig.Parity = 0;
break;
}
switch (this.stopBits)
{
case StopBits.One:
serialConfig.StopBits = 0;
break;
case StopBits.OnePointFive:
serialConfig.StopBits = 1;
break;
case StopBits.Two:
serialConfig.StopBits = 2;
break;
case StopBits.None:
default:
throw new ArgumentException("stopBits cannot be StopBits.None");
}
if (SetCommState(pHandle, ref serialConfig))
{
// set the serial connection timeouts
COMMTIMEOUTS timeouts = new COMMTIMEOUTS();
timeouts.ReadIntervalTimeout = 1;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
if (SetCommTimeouts(pHandle, ref timeouts))
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
else
{
return false;
}
}
/// <summary>
/// Helper that throws a InvalidOperationException if we don't have a serial connection.
/// </summary>
private void FailIfNotConnected()
{
if (pHandle == IntPtr.Zero)
throw new InvalidOperationException("You must be connected to the serial port before performing this operation.");
}
#endregion
#region Native Helpers
#region Native structures
/// <summary>
/// Contains the time-out parameters for a communications device.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
struct COMMTIMEOUTS
{
public uint ReadIntervalTimeout;
public uint ReadTotalTimeoutMultiplier;
public uint ReadTotalTimeoutConstant;
public uint WriteTotalTimeoutMultiplier;
public uint WriteTotalTimeoutConstant;
}
/// <summary>
/// Defines the control setting for a serial communications device.
/// </summary>
[StructLayout(LayoutKind.Sequential)]
struct DCB
{
public int DCBlength;
public uint BaudRate;
public uint Flags;
public ushort wReserved;
public ushort XonLim;
public ushort XoffLim;
public byte ByteSize;
public byte Parity;
public byte StopBits;
public sbyte XonChar;
public sbyte XoffChar;
public sbyte ErrorChar;
public sbyte EofChar;
public sbyte EvtChar;
public ushort wReserved1;
public uint fBinary;
public uint fParity;
public uint fOutxCtsFlow;
public uint fOutxDsrFlow;
public uint fDtrControl;
public uint fDsrSensitivity;
public uint fTXContinueOnXoff;
public uint fOutX;
public uint fInX;
public uint fErrorChar;
public uint fNull;
public uint fRtsControl;
public uint fAbortOnError;
}
#endregion
#region Native Methods
// Used to get a handle to the serial port so that we can read/write to it.
[DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern IntPtr CreateFile(string fileName,
[MarshalAs(UnmanagedType.U4)] FileAccess fileAccess,
[MarshalAs(UnmanagedType.U4)] FileShare fileShare,
IntPtr securityAttributes,
[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
int flags,
IntPtr template);
// Used to close the handle to the serial port.
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool CloseHandle(IntPtr hObject);
// Used to get the state of the serial port so that we can configure it.
[DllImport("kernel32.dll")]
static extern bool GetCommState(IntPtr hFile, ref DCB lpDCB);
// Used to configure the serial port.
[DllImport("kernel32.dll")]
static extern bool SetCommState(IntPtr hFile, [In] ref DCB lpDCB);
// Used to set the connection timeouts on our serial connection.
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool SetCommTimeouts(IntPtr hFile, ref COMMTIMEOUTS lpCommTimeouts);
// Used to read bytes from the serial connection.
[DllImport("kernel32.dll")]
static extern bool ReadFile(IntPtr hFile, byte[] lpBuffer,
int nNumberOfBytesToRead, out int lpNumberOfBytesRead, int lpOverlapped);
// Used to write bytes to the serial connection.
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteFile(IntPtr hFile, byte[] lpBuffer,
int nNumberOfBytesToWrite, out int lpNumberOfBytesWritten, int lpOverlapped);
// Used to flush the I/O buffers.
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool PurgeComm(IntPtr hFile, int dwFlags);
#endregion
#endregion
}
silverlight5 OOB 直接p/invoke实现串口通信的更多相关文章
- C#串口通信
通过COM1发送数据,COM2接收数据.当COM2接收完本次发送的数据后,向COM1发送信息通知COM1本次数据已发完,COM1接到通知后,再发下一段数据.这样可以确保每次发送的数据都可以被正确接收. ...
- 利用 SerialPort 控件实现 PC 串口通信
整理参考自<Visual C#.NET 串口通信及测控应用典型实例>1.3 节 以及 一篇博文:C# 串口操作系列(1) -- 入门篇,一个标准的,简陋的串口例子. 硬件部分 如果是两个串 ...
- 在C#中实现串口通信的方法
通常,在C#中实现串口通信,我们有四种方法: 第一:通过MSCOMM控件这是最简单的,最方便的方法.可功能上很难做到控制自如,同时这个控件并不是系统本身所带,所以还得注册,不在本文讨论范围.可以访问h ...
- C#串口介绍以及简单串口通信程序设计实现
C#串口介绍以及简单串口通信程序设计实现 周末,没事干,写个简单的串口通信工具,也算是本周末曾来过,废话不多,直接到主题 串口介绍 串行接口简称串口,也称串行通信接口或串行通讯接口(通常指COM接口) ...
- C# 编程实现串口通信
http://blog.sina.com.cn/s/blog_6c67dab30101p3vn.html ----------------------------------------------- ...
- C#中缓存的使用 ajax请求基于restFul的WebApi(post、get、delete、put) 让 .NET 更方便的导入导出 Excel .net core api +swagger(一个简单的入门demo 使用codefirst+mysql) C# 位运算详解 c# 交错数组 c# 数组协变 C# 添加Excel表单控件(Form Controls) C#串口通信程序
C#中缓存的使用 缓存的概念及优缺点在这里就不多做介绍,主要介绍一下使用的方法. 1.在ASP.NET中页面缓存的使用方法简单,只需要在aspx页的顶部加上一句声明即可: <%@ Outp ...
- C#串口通信及数据表格存储
1.开发环境 系统:win10 开发工具:Visual Studio 2017 2.界面设计 串口通信的界面大致如此,在此基础上添加项目所需的调试指令与数据存储功能,界面排布方面可参考其他教程. 3. ...
- C#串口通信程序实现无感知签到与答题
最近公司项目上线,之前利用串口通讯实现校牌的无感知签到程序, 项目上线以后刚刚好有时间把之前的出现的问题做下记录,废话不多,直接到主题 串口介绍: 串行接口简称串口,也称串行通信接口或串行通讯接口(通 ...
- C#实现简单的串口通信
前言 本着学习研究的态度,用c#语言实现简单的串口通信工具. 一.串口通信原理 串口通信 串口通信(Serial Communications)的概念非常简单,串口按位(bit)发送和接收字节.尽管比 ...
随机推荐
- java后台发送请求并获取返回值
项目中需要前端发送请求给后端,而后端需要从另一个平台中取数据然后再透传给前端,通过下述代码将其实现.在此记录一下. package com.autotest.utils; import java.io ...
- Laravel 5.2--如何让表单提交错误,不清空?
控制器 public function store(Request $request) { $validator = Validator::make($request->all(), [ 'Su ...
- vue.js computed,watch的区别
computed: 当数据没有变化时,它会去读取缓存,当数据有变化时,它才会去执行computed,而不会像method和watch一样每次都去执行函数(摘自https://www.jb51.net/ ...
- [PHP]curl上传多文件
码一下curl上传多文件的行 5.5之前版本的写法 $file = array( 'pic[0]'=>"@E:\\wwwroot\\10003\\temp_56.ini;type=te ...
- awk简单用法-(1)
一.awk基本操作 awk指定多个分割符,分隔符中有:和空格,还有:和空格的组合,这个时候需要指定多个分隔符 -F'[ :]+',[ :]表示分隔符为:和空格,一个或者多个+号表示空格和:的组合也为一 ...
- 在XIB 或者 SB 上面 实现 半透明的背景上添加UILabel是文字不透明
设透明背景的时候直接设置RGB值 然后设置Opacity即可
- functions 示例
示例1: ","字符串截取 CREATE OR REPLACE FUNCTION splitstr(p_string IN VARCHAR2, p_delimiter IN VA ...
- 使用 Apache 来限制访问 Confluence 6 的管理员界面
限制特定的 IP 地址可以访问管理员后台 Confluence 的管理员控制台界面对整个应用来说是非常重要的,任何人访问 Confluence 的控制台不仅仅可以访问 Confluence 安装实例, ...
- Confluence 6 附件存储配置
在默认的情况下 Confluence 的附件存储在 home 目录中(例如,在文件系统). 希望对 Confluence 的附件存储进行配置: 在屏幕的右上角单击 控制台按钮 ,然后选择 Genera ...
- JMeter进行一次简单的压力测试
测试目的:10个用户并发打开百度首页(https://www.baidu.com/),百度能否正常响应. 操作步骤 一.打开JMeter 打开后的界面如下: 二.右击“测试计划”,添加线程组 三.设置 ...