欢迎光临
我们一直在努力

C#串口操作(国外网站看来的,共享一下)-.NET教程,C#语言

建站超值云服务器,限时71元/月

前一阵,从国外网站看到一个用c#来操作串口的类。下载下来试了一下,觉得不错。共享一下。

/*

* author: marcus lorentzon, 2001

* d98malor@dtek.chalmers.se

*

* freeware: please do not remove this header

*

* file: serialstream.cs

*

* description: implements a stream for asynchronous

* transfers and comm. stream version.

*

* version: 2.4

*

*/

#region using

using system;

using system.io;

using system.threading;

using system.runtime.interopservices;

using system.componentmodel;

#endregion using

namespace loman.io {

public class serialstream : stream {

#region attributes

private iocompletioncallback m_iocompletioncallback;

private intptr m_hfile = intptr.zero;

private string m_sport;

private bool m_bread;

private bool m_bwrite;

#endregion attributes

#region properties

public string port {

get {

return m_sport;

}

set {

if (m_sport != value) {

close();

open(value);

}

}

}

public override bool canread {

get {

return m_bread;

}

}

public override bool canwrite {

get {

return m_bwrite;

}

}

public override bool canseek {

get {

return false;

}

}

public bool closed {

get {

return m_hfile.toint32() 0;

}

}

public bool dsr {

get {

uint status;

if (!getcommmodemstatus(m_hfile, out status)) {

throw new win32exception();

}

return (status & ms_dsr_on) > 0;

}

}

public bool ring {

get {

uint status;

if (!getcommmodemstatus(m_hfile, out status)) {

throw new win32exception();

}

return (status & ms_ring_on) > 0;

}

}

public bool rlsd {

get {

uint status;

if (!getcommmodemstatus(m_hfile, out status)) {

throw new win32exception();

}

return (status & ms_rlsd_on) > 0;

}

}

#endregion properties

#region constructors

public serialstream() : this(fileaccess.readwrite) {

}

public serialstream(fileaccess access) {

m_bread = ((int)access & (int)fileaccess.read) != 0;

m_bwrite = ((int)access & (int)fileaccess.write) != 0;

unsafe {

m_iocompletioncallback = new iocompletioncallback(asyncfscallback);

}

}

public serialstream(string port) : this(fileaccess.readwrite) {

open(port);

}

public serialstream(string port, fileaccess access) : this(access) {

open(port);

}

#endregion constructors

#region methods

public void open(string port) {

if (m_hfile != intptr.zero) {

throw new ioexception("stream already opened.");

}

m_sport = port;

m_hfile = createfile(port, (uint)((m_bread?generic_read:0)|(m_bwrite?generic_write:0)), 0, 0, open_existing, file_flag_overlapped, 0);

if (m_hfile.toint32() == invalid_handle_value) {

m_hfile = intptr.zero;

throw new filenotfoundexception("unable to open " + port);

}

threadpool.bindhandle(m_hfile);

settimeouts(0, 0, 0, 0, 0);

}

public override void close() {

closehandle(m_hfile);

m_hfile = intptr.zero;

m_sport = null;

}

public iasyncresult beginread(byte[] buffer) {

return beginread(buffer, 0, buffer.length, null, null);

}

public override iasyncresult beginread(byte[] buffer, int offset, int count, asynccallback callback, object state) {

gchandle gchbuffer = gchandle.alloc(buffer, gchandletype.pinned);

serialasyncresult sar = new serialasyncresult(this, state, callback, true, gchbuffer);

overlapped ov = new overlapped(0, 0, sar.asyncwaithandle.handle.toint32(), sar);

unsafe {

nativeoverlapped* nov = ov.pack(m_iocompletioncallback);

byte* data = (byte*)((int)gchbuffer.addrofpinnedobject() + offset);

uint read = 0;

if (readfile(m_hfile, data, (uint)count, out read, nov)) {

sar.m_bcompletedsynchronously = true;

return sar;

}

else if (getlasterror() == error_io_pending) {

return sar;

}

else

throw new exception("unable to initialize read. errorcode: " + getlasterror().tostring());

}

}

public iasyncresult beginwrite(byte[] buffer) {

return beginwrite(buffer, 0, buffer.length, null, null);

}

public override iasyncresult beginwrite(byte[] buffer, int offset, int count, asynccallback callback, object state) {

gchandle gchbuffer = gchandle.alloc(buffer, gchandletype.pinned);

serialasyncresult sar = new serialasyncresult(this, state, callback, false, gchbuffer);

overlapped ov = new overlapped(0, 0, sar.asyncwaithandle.handle.toint32(), sar);

unsafe {

nativeoverlapped* nov = ov.pack(m_iocompletioncallback);

byte* data = (byte*)((int)gchbuffer.addrofpinnedobject() + offset);

uint written = 0;

if (writefile(m_hfile, data, (uint)count, out written, nov)) {

sar.m_bcompletedsynchronously = true;

return sar;

}

else if (getlasterror() == error_io_pending) {

return sar;

}

else

throw new exception("unable to initialize write. errorcode: " + getlasterror().tostring());

}

}

private int endoperation(iasyncresult asyncresult, bool isread) {

serialasyncresult sar = (serialasyncresult)asyncresult;

if (sar.m_bisread != isread)

throw new ioexception("invalid parameter: iasyncresult is not from a " + (isread ? "read" : "write"));

if (sar.endoperationcalled) {

throw new ioexception("end" + (isread ? "read" : "write") + " called twice for the same operation.");

}

else {

sar.m_bendoperationcalled = true;

}

while (!sar.m_bcompleted) {

sar.asyncwaithandle.waitone();

}

sar.dispose();

if (sar.m_nerrorcode != error_success && sar.m_nerrorcode != error_operation_aborted) {

throw new ioexception("operation finished with errorcode: " + sar.m_nerrorcode);

}

return sar.m_nreadwritten;

}

public override int endread(iasyncresult asyncresult) {

return endoperation(asyncresult, true);

}

public override void endwrite(iasyncresult asyncresult) {

endoperation(asyncresult, false);

}

public int endwriteex(iasyncresult asyncresult) {

return endoperation(asyncresult, false);

}

public override int read(byte[] buffer, int offset, int count) {

return endread(beginread(buffer, offset, count, null, null));

}

public override void write(byte[] buffer, int offset, int count) {

endwrite(beginwrite(buffer, offset, count, null, null));

}

public int writeex(byte[] buffer, int offset, int count) {

return endwriteex(beginwrite(buffer, offset, count, null, null));

}

public int read(byte[] buffer) {

return endread(beginread(buffer, 0, buffer.length, null, null));

}

public int write(byte[] buffer) {

return endoperation(beginwrite(buffer, 0, buffer.length, null, null), false);

}

public override void flush() {

flushfilebuffers(m_hfile);

}

public bool purgeread() {

return purgecomm(m_hfile, purge_rxclear);

}

public bool purgewrite() {

return purgecomm(m_hfile, purge_txclear);

}

public bool purge() {

return purgeread() && purgewrite();

}

public bool cancelread() {

return purgecomm(m_hfile, purge_rxabort);

}

public bool cancelwrite() {

return purgecomm(m_hfile, purge_txabort);

}

public bool cancelall() {

return cancelread() && cancelwrite();

}

public override void setlength(long nlength) {

throw new notsupportedexception("setlength isnt supported on serial ports.");

}

public override long seek(long offset, seekorigin origin) {

throw new notsupportedexception("seek isnt supported on serial ports.");

}

public void settimeouts(int readintervaltimeout,

int readtotaltimeoutmultiplier,

int readtotaltimeoutconstant,

int writetotaltimeoutmultiplier,

int writetotaltimeoutconstant) {

serialtimeouts timeouts = new serialtimeouts(readintervaltimeout,

readtotaltimeoutmultiplier,

readtotaltimeoutconstant,

writetotaltimeoutmultiplier,

writetotaltimeoutconstant);

unsafe { setcommtimeouts(m_hfile, ref timeouts); }

}

public bool setportsettings(uint baudrate) {

return setportsettings(baudrate, flowcontrol.hardware);

}

public bool setportsettings(uint baudrate, flowcontrol flowcontrol) {

return setportsettings(baudrate, flowcontrol, parity.none);

}

public bool setportsettings(uint baudrate, flowcontrol flowcontrol, parity parity) {

return setportsettings(baudrate, flowcontrol, parity, 8, stopbits.one);

}

public bool setportsettings(uint baudrate, flowcontrol flowcontrol, parity parity, byte databits, stopbits stopbits) {

unsafe {

dcb dcb = new dcb();

dcb.dcblength = sizeof(dcb);

dcb.baudrate = baudrate;

dcb.bytesize = databits;

dcb.stopbits = (byte)stopbits;

dcb.parity = (byte)parity;

dcb.fparity = (parity > 0)? 1u : 0u;

dcb.fbinary = dcb.fdtrcontrol = dcb.ftxcontinueonxoff = 1;

dcb.foutxctsflow = dcb.fabortonerror = (flowcontrol == flowcontrol.hardware)? 1u : 0u;

dcb.foutx = dcb.finx = (flowcontrol == flowcontrol.xonxoff)? 1u : 0u;

dcb.frtscontrol = (flowcontrol == flowcontrol.hardware)? 2u : 1u;

dcb.xonlim = 2048;

dcb.xofflim = 512;

dcb.xonchar = 0x11; // ctrl-q

dcb.xoffchar = 0x13; // ctrl-s

return setcommstate(m_hfile, ref dcb);

}

}

public bool setportsettings(dcb dcb) {

return setcommstate(m_hfile, ref dcb);

}

public bool getportsettings(out dcb dcb) {

unsafe {

dcb dcb2 = new dcb();

dcb2.dcblength = sizeof(dcb);

bool ret = getcommstate(m_hfile, ref dcb2);

dcb = dcb2;

return ret;

}

}

public bool setxon() {

return escapecommfunction(m_hfile, setxon);

}

public bool setxoff() {

return escapecommfunction(m_hfile, setxoff);

}

private unsafe void asyncfscallback(uint errorcode, uint numbytes, nativeoverlapped* poverlapped) {

serialasyncresult sar = (serialasyncresult)overlapped.unpack(poverlapped).asyncresult;

sar.m_nerrorcode = errorcode;

sar.m_nreadwritten = (int)numbytes;

sar.m_bcompleted = true;

if (sar.callback != null)

sar.callback.invoke(sar);

overlapped.free(poverlapped);

}

#endregion methods

#region constants

private const uint purge_txabort = 0x0001; // kill the pending/current writes to the comm port.

private const uint purge_rxabort = 0x0002; // kill the pending/current reads to the comm port.

private const uint purge_txclear = 0x0004; // kill the transmit queue if there.

private const uint purge_rxclear = 0x0008; // kill the typeahead buffer if there.

private const uint setxoff = 1; // simulate xoff received

private const uint setxon = 2; // simulate xon received

private const uint setrts = 3; // set rts high

private const uint clrrts = 4; // set rts low

private const uint setdtr = 5; // set dtr high

private const uint clrdtr = 6; // set dtr low

private const uint setbreak = 8; // set the device break line.

private const uint clrbreak = 9; // clear the device break line.

private const uint ms_cts_on = 0x0010;

private const uint ms_dsr_on = 0x0020;

private const uint ms_ring_on = 0x0040;

private const uint ms_rlsd_on = 0x0080;

private const uint file_flag_overlapped = 0x40000000;

private const uint open_existing = 3;

private const int invalid_handle_value = -1;

private const uint generic_read = 0x80000000;

private const uint generic_write = 0x40000000;

private const uint error_success = 0;

private const uint error_operation_aborted = 995;

private const uint error_io_pending = 997;

#endregion constants

#region enums

public enum parity {none, odd, even, mark, space};

public enum stopbits {one, oneandhalf, two};

public enum flowcontrol {none, xonxoff, hardware};

#endregion enums

#region classes

[structlayout(layoutkind.sequential)]

public struct dcb {

#region attributes

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;

#endregion attributes

#region properties

public uint fbinary { get { return flags&0x0001; }

set { flags = flags & ~1u | value; } }

public uint fparity { get { return (flags>>1)&1; }

set { flags = flags & ~(1u >2)&1; }

set { flags = flags & ~(1u >3)&1; }

set { flags = flags & ~(1u >4)&3; }

set { flags = flags & ~(3u >6)&1; }

set { flags = flags & ~(1u >7)&1; }

set { flags = flags & ~(1u >8)&1; }

set { flags = flags & ~(1u >9)&1; }

set { flags = flags & ~(1u >10)&1; }

set { flags = flags & ~(1u >11)&1; }

set { flags = flags & ~(1u >12)&3; }

set { flags = flags & ~(3u >14)&1; }

set { flags = flags & ~(1u << 14) | (value << 14); } }

#endregion properties

#region methods

public override string tostring() {

return "dcblength: " + dcblength + "\r\n" +

"baudrate: " + baudrate + "\r\n" +

"fbinary: " + fbinary + "\r\n" +

"fparity: " + fparity + "\r\n" +

"foutxctsflow: " + foutxctsflow + "\r\n" +

"foutxdsrflow: " + foutxdsrflow + "\r\n" +

"fdtrcontrol: " + fdtrcontrol + "\r\n" +

"fdsrsensitivity: " + fdsrsensitivity + "\r\n" +

"ftxcontinueonxoff: " + ftxcontinueonxoff + "\r\n" +

"foutx: " + foutx + "\r\n" +

"finx: " + finx + "\r\n" +

"ferrorchar: " + ferrorchar + "\r\n" +

"fnull: " + fnull + "\r\n" +

"frtscontrol: " + frtscontrol + "\r\n" +

"fabortonerror: " + fabortonerror + "\r\n" +

"xonlim: " + xonlim + "\r\n" +

"xofflim: " + xofflim + "\r\n" +

"bytesize: " + bytesize + "\r\n" +

"parity: " + parity + "\r\n" +

"stopbits: " + stopbits + "\r\n" +

"xonchar: " + xonchar + "\r\n" +

"xoffchar: " + xoffchar + "\r\n" +

"eofchar: " + eofchar + "\r\n" +

"evtchar: " + evtchar + "\r\n";

}

#endregion methods

}

private class serialasyncresult : iasyncresult, idisposable {

#region attributes

internal bool m_bendoperationcalled = false;

internal bool m_bisread;

internal int m_nreadwritten = 0;

internal bool m_bcompleted = false;

internal bool m_bcompletedsynchronously = false;

internal uint m_nerrorcode = error_success;

private object m_asyncobject;

private object m_stateobject;

private manualresetevent m_waithandle = new manualresetevent(false);

private asynccallback m_callback;

private gchandle m_gchbuffer;

#endregion attributes

#region properties

internal bool endoperationcalled { get { return m_bendoperationcalled; } }

public bool iscompleted { get { return m_bcompleted; } }

public bool completedsynchronously { get { return m_bcompletedsynchronously; } }

public object asyncobject { get { return m_asyncobject; } }

public object asyncstate { get { return m_stateobject; } }

public waithandle asyncwaithandle { get { return m_waithandle; } }

internal manualresetevent waithandle { get { return m_waithandle; } }

public asynccallback callback { get { return m_callback; } }

#endregion properties

#region constructors

public serialasyncresult(object asyncobject,

object stateobject,

asynccallback callback,

bool bisread,

gchandle gchbuffer) {

m_asyncobject = asyncobject;

m_stateobject = stateobject;

m_callback = callback;

m_bisread = bisread;

m_gchbuffer = gchbuffer;

}

#endregion constructors

#region methods

public void dispose() {

m_waithandle.close();

m_gchbuffer.free();

}

#endregion methods

}

#endregion classes

#region imports

[dllimport("kernel32.dll", entrypoint="createfilew", setlasterror=true,

charset=charset.unicode, exactspelling=true)]

static extern intptr createfile(string filename, uint access, uint sharemode, uint security_attributes, uint creation, uint flags, uint template);

[dllimport("kernel32.dll", setlasterror=true)]

static extern bool closehandle(intptr handle);

[dllimport("kernel32.dll", setlasterror=true)]

static extern unsafe bool readfile(intptr hfile, byte* lpbuffer, uint nnumberofbytestoread, out uint lpnumberofbytesread, nativeoverlapped* lpoverlapped);

[dllimport("kernel32.dll", setlasterror=true)]

static extern unsafe bool writefile(intptr hfile, byte* lpbuffer, uint nnumberofbytestowrite, out uint lpnumberofbyteswritten, nativeoverlapped* lpoverlapped);

[dllimport("kernel32.dll", setlasterror=true)]

static extern bool setcommtimeouts(intptr hfile, ref serialtimeouts lpcommtimeouts);

[dllimport("kernel32.dll", setlasterror=true)]

static extern bool setcommstate(intptr hfile, ref dcb lpdcb);

[dllimport("kernel32.dll", setlasterror=true)]

static extern bool getcommstate(intptr hfile, ref dcb lpdcb);

[dllimport("kernel32.dll", setlasterror=true)]

static extern bool buildcommdcb(string def, ref dcb lpdcb);

[dllimport("kernel32.dll", setlasterror=true)]

static extern int getlasterror();

[dllimport("kernel32.dll", setlasterror=true)]

static extern bool flushfilebuffers(intptr hfile);

[dllimport("kernel32.dll", setlasterror=true)]

static extern bool purgecomm(intptr hfile, uint dwflags);

[dllimport("kernel32.dll", setlasterror=true)]

static extern bool escapecommfunction(intptr hfile, uint dwfunc);

[dllimport("kernel32.dll", setlasterror=true)]

static extern bool getcommmodemstatus(intptr hfile, out uint modemstat);

#endregion imports

}

[structlayout(layoutkind.sequential)]

public struct serialtimeouts {

#region attributes

public int readintervaltimeout;

public int readtotaltimeoutmultiplier;

public int readtotaltimeoutconstant;

public int writetotaltimeoutmultiplier;

public int writetotaltimeoutconstant;

#endregion attributes

#region constructors

public serialtimeouts(int r1, int r2, int r3, int w1, int w2) {

readintervaltimeout = r1;

readtotaltimeoutmultiplier = r2;

readtotaltimeoutconstant = r3;

writetotaltimeoutmultiplier = w1;

writetotaltimeoutconstant = w2;

}

#endregion constructors

#region methods

public override string tostring() {

return "readintervaltimeout: " + readintervaltimeout + "\r\n" +

"readtotaltimeoutmultiplier: " + readtotaltimeoutmultiplier + "\r\n" +

"readtotaltimeoutconstant: " + readtotaltimeoutconstant + "\r\n" +

"writetotaltimeoutmultiplier: " + writetotaltimeoutmultiplier + "\r\n" +

"writetotaltimeoutconstant: " + writetotaltimeoutconstant + "\r\n";

}

#endregion methods

}

}

using system;

using system.io;

using system.threading;

using loman.io;

namespace serialstreamreader {

class app {

// the main serial stream

static serialstream ss;

[stathread]

static void main(string[] args) {

// create a serial port

ss = new serialstream();

try {

ss.open("com4"); //我对猫进行了调用

}

catch (exception e) {

console.writeline("error: " + e.message);

return;

}

// set port settings

ss.setportsettings(9600);

// set timeout so read ends after 20ms of silence after a response

ss.settimeouts(20, 0, 0, 0, 0);

// create the streamwriter used to send commands

streamwriter sw = new streamwriter(ss, system.text.encoding.ascii);

// create the thread used to read responses

thread responsereaderthread = new thread(new threadstart(readresponsethread));

responsereaderthread.start();

// read all returned lines

for (;;) {

// read command from console

string command = console.readline();

// check for exit command

if (command.trim().tolower() == "exit") {

responsereaderthread.abort();

break;

}

// write command to modem

sw.writeline(command);

sw.flush();

}

}

// main loop for reading responses

static void readresponsethread() {

streamreader sr = new streamreader(ss, system.text.encoding.ascii);

try {

for (;;) {

// read response from modem

string response = sr.readline();

console.writeline("response: " + response);

}

}

catch (threadabortexception) {

}

}

}

}

程序运行后,你可以对设备进行指令操作。(具体设备接受的指令)

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » C#串口操作(国外网站看来的,共享一下)-.NET教程,C#语言
分享到: 更多 (0)