怎么样利用mscomm写一个自己的串口通信类?
http://www.devhood.com/tutorials/tutorial_details.aspx?tutorial_id=320
这篇文章是直接使用mscomm控件,我想引用mscomm,写一个自己的类,包含发送、接收、初始化三个方法,我是超级菜鸟,写这类就像叫我去驾飞机一样飞机,请给出代码,500分重谢!
问题点数:100、回复次数:12Top
1 楼9728(生菜种子)回复于 2004-08-04 12:49:00 得分 0
顶Top
2 楼9728(生菜种子)回复于 2004-08-04 15:12:42 得分 0
再顶Top
3 楼lifeixie(lifeixie)回复于 2004-08-04 15:44:40 得分 100
using System;
using System.Collections;
using System.ComponentModel;
using System.Drawing;
//using System.Data;
using System.Windows.Forms;
using System.Threading;
using System.Text;
using System.Configuration;
using System.Text.RegularExpressions;
using System.Globalization;
namespace Util
{
/// <summary>
/// SMSAdapter 的摘要说明。
/// </summary>
public class SMSAdapter : System.Windows.Forms.UserControl
{
const int MAX_WAIT_TIME = 10000;
private static int OK = 1;
// private static int WAIT = 2;
private static int ERROR = 3;
private static int WMSG = 4;
// private static int RMSG = 5;
// private static int ECHO = 6;
// private static int TIMEOUT = 7;
private const int comEvSend = 1;
private const int comEvReceive = 2;
private const int comEvCTS = 3;
private const int comEvDSR = 4;
private const int comEvCD = 5;
private const int comEvRing = 6;
private const int comEvEOF = 7;
private const int comBreak = 1001;
private const int comCTSTO = 1002;
private const int comDSRTO = 1003;
private const int comFrame = 1004;
private const int comOverrun = 1006;
private const int comCDTO = 1007;
private const int comRxOver = 1008;
private const int comRxParity = 1009;
private const int comTxFull = 1010;
private const int comDCB = 1011;
private SMSPdu smsPdu;
public delegate void MessageEventHandler(object sender, MessageEventArgs e);
public event MessageEventHandler Message;
private AxMSCommLib.AxMSComm axMSComm;
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.Container components = null;
// ManualResetEvent instances signal completion.
private static ManualResetEvent stepOneDone =
new ManualResetEvent(false);
private static ManualResetEvent stepTwoDone =
new ManualResetEvent(false);
private static ManualResetEvent receiveDone =
new ManualResetEvent(false);
private string sComBuffer = "";
public SMSAdapter()
{
// 该调用是 Windows.Forms 窗体设计器所必需的。
InitializeComponent();
initComm();
// TODO: 在 InitializeComponent 调用后铁赜任何初始化
}
/// <summary>
/// 清历琦有正在使用的资源。
/// </summary>
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Component Designer generated code
/// <summary>
/// 设计器支持所需的方法 - 不要使用代聛E嗉丒
/// 修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(SMSAdapter));
this.axMSComm = new AxMSCommLib.AxMSComm();
((System.ComponentModel.ISupportInitialize)(this.axMSComm)).BeginInit();
this.SuspendLayout();
//
// axMSComm
//
this.axMSComm.Enabled = true;
this.axMSComm.Location = new System.Drawing.Point(0, 0);
this.axMSComm.Name = "axMSComm";
this.axMSComm.OcxState = ((System.Windows.Forms.AxHost.State)(resources.GetObject("axMSComm.OcxState")));
this.axMSComm.Size = new System.Drawing.Size(38, 38);
this.axMSComm.TabIndex = 0;
this.axMSComm.OnComm += new System.EventHandler(this.axMSComm_OnComm);
//
// SMSAdapter
//
this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
this.Controls.Add(this.axMSComm);
this.Name = "SMSAdapter";
this.Size = new System.Drawing.Size(40, 40);
((System.ComponentModel.ISupportInitialize)(this.axMSComm)).EndInit();
this.ResumeLayout(false);
}
#endregion
/// <summary>
/// // serial port no
/// </summary>
public int CommPort
{
get
{
return (int)axMSComm.CommPort;
}
set
{
axMSComm.CommPort = (short)value;
}
}
Top
4 楼lifeixie(lifeixie)回复于 2004-08-04 15:46:41 得分 0
接着上面没完
/// <summary>
/// // binary or text
/// </summary>
public int InputMode
{
get
{
return (int)axMSComm.InputMode;
}
set
{
axMSComm.InputMode = (MSCommLib.InputModeConstants )value;
}
}
/// <summary>
/// // comm settings 19200,n,8,1
/// </summary>
public string Settings
{
get
{
return axMSComm.Settings;
}
set
{
axMSComm.Settings = value;
}
}
public void SendMessageThread()
{
try
{
StringBuilder sbFirst = new StringBuilder();
StringBuilder sbSecond = new StringBuilder();
if (axMSComm.PortOpen == false)
{
axMSComm.PortOpen = true;
}
sbFirst.Append( "AT+CMGS=" + smsPdu.Length() / 2 + '\x0d');
//26
sbSecond.Append(smsPdu.ToString() + '\x1a');
lock(this)
{
axMSComm.Output = sbFirst.ToString();
// must pause some time
// wait until receive the respond
stepOneDone.WaitOne(MAX_WAIT_TIME, true);
axMSComm.Output = sbSecond.ToString();
stepTwoDone.WaitOne(MAX_WAIT_TIME, true);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
protected virtual void OnMessage(MessageEventArgs e)
{
if (Message != null)
{
// Invokes the delegates.
Message(this, e);
}
}
public void SendMessage(SMSPdu smsPdu)
{
this.smsPdu = smsPdu;
stepOneDone.Reset();
stepTwoDone.Reset();
Thread sendThread = new Thread(new ThreadStart(SendMessageThread));
sendThread.Start();
}
public void InitThread()
{
try
{
StringBuilder sbFirst = new StringBuilder();
StringBuilder sbSecond = new StringBuilder();
sbFirst.Append("AT+CNMI=1,1,0,2,1\x0d");
sbSecond.Append ("AT+CMGF=0\x0d");
if (axMSComm.PortOpen == false)
{
axMSComm.PortOpen = true;
}
axMSComm.Output = sbFirst.ToString() ;;
stepTwoDone.WaitOne(MAX_WAIT_TIME, true);
axMSComm.Output = sbSecond.ToString() ;
stepTwoDone.WaitOne(MAX_WAIT_TIME, true);
}
catch(Exception ex)
{
System.Console.WriteLine(ex.ToString());
}
}
public bool Init()
{
Thread initThread = new Thread(new ThreadStart(InitThread));
initThread.Start();
return true;
}
public void SendMessage(string ReceiverNo, byte[] Message)
{
SMSPdu smsPdu = new SMSPdu(ReceiverNo, Message);
SendMessage(smsPdu);
}
/// <summary>
/// send message to receiver
/// </summary>
/// <param name="ReceiverNo"></param>
/// <param name="Message"></param>
public void SendMessage(string ReceiverNo, string Message, int CharLength)
{
SMSPdu smsPdu = new SMSPdu(ReceiverNo, Message, CharLength);
SendMessage(smsPdu);
}
public void SendMessage(string ReceiverNo, string Message)
{
SMSPdu smsPdu = new SMSPdu(ReceiverNo, Message, 2);
SendMessage(smsPdu);
}
private bool initComm()
{
axMSComm.Settings = Settings;
axMSComm.CommPort = (short)CommPort;
axMSComm.RThreshold = 1;
axMSComm.SThreshold = 1;
axMSComm.RTSEnable = true;
axMSComm.DTREnable = true;
//axMSComm.Handshaking = Handshaking;
axMSComm.InputMode = (MSCommLib.InputModeConstants )InputMode;
// With pduFrame
// .DCS = "18"
// .PID = "90"
// .SCA = "0891683108401105F0"
// .VP = "04"
// .PduType = "11"
// .MR = "00"
// End With
return true;
}
private void axMSComm_OnComm(object sender, System.EventArgs e)
{
try
{
//string sMessage = "";
switch(axMSComm.CommEvent)
{
case comEvReceive:
if (axMSComm.InBufferCount > 0)
{
object obj = axMSComm.Input;
byte[] bt = (byte[])obj;
string sReturn = "\r\n";
string sTmp = Conversion.byte2String(bt);
sComBuffer += sTmp;
if (sComBuffer.EndsWith(sReturn))
{
ProcessComData(sComBuffer);
sComBuffer = "";
}
}
break;
// case comEvSend:
// sMessage = "comEvSend";
// break;
// case comEvCTS:
// sMessage = "被紒E獾?CTS 改眮E;
// break;
// case comEvDSR:
// sMessage = "被紒E獾?DSR 改眮E;
// break;
// case comEvCD:
// sMessage = "被紒E獾?CD 改眮E;
// break;
// case comEvRing:
// sMessage = "电话铃蟻E丒;
// break;
// case comEvEOF:
// sMessage = "被紒E獾奈募嵛?;
// break;
// case comBreak:
// sMessage = "收到中断";
// break;
// case comCDTO:
// sMessage = "运输紒E獬?;
// break;
// case comCTSTO:
// sMessage = "CTS 超时";
// break;
// case comDCB:
// sMessage = "紒E丒DCB 代陙E;
// break;
// case comDSRTO:
// sMessage = "DSR 超时";
// break;
// case comFrame:
// sMessage = "帧代陙E;
// break;
// case comOverrun:
// sMessage = "超限代陙E;
// break;
// case comRxOver:
// sMessage = "接收缓冲区溢硜E;
// break;
// case comRxParity:
// sMessage = "奇偶校验磥E;
// break;
// case comTxFull:
// sMessage = "传送缓冲区聛E;
// break;
// default:
// sMessage = "未知的代牦或事件";
// break;
}
}
catch( Exception ex)
{
System.Console.WriteLine(ex.ToString());
Logger.Glog(LogLevel.LogError, ex.ToString());
}
}Top
5 楼lifeixie(lifeixie)回复于 2004-08-04 15:47:57 得分 0
再接着上面
private void ProcessComData(string input)
{
string response;
int portStatus;
string portStatusMsg;
IncomingSms rx_sms;
// bool bCmti = false;
int iIndex = 0;
// starts with '---' and ends with '==='
//Regex rLine = new Regex("^\\w+\n");
Regex rLine = new Regex(@".*?\r\n");
// Cycle through the matches
for (Match m = rLine.Match(input); m.Success; m = m.NextMatch())
{
// Display the result to the 'Output' debug window
System.Console.WriteLine( "ms------------------");
System.Console.WriteLine( m.Value);
System.Console.WriteLine( "me------------------");
// bCmti = false;
//response = m.Value;
//if (m.Index > 0)
{
//response = input.Substring(0,m.Index);
response = m.Value;
// if (response.IndexOf(">") > 0)
// {
// stepOneDone.Set();
// }
if (response.StartsWith("OK"))
{
portStatus = OK;
//stepOneDone.Set();
stepTwoDone.Set();
// if (bCmti)
// {
// //read the sms
//
// // delete sms
// axMSComm.Output = "AT+CMGD=" + iIndex + "\x0d";
// }
//portStatusLock.notify();
//InTextArea.Append(lfcr);
}
else if (response.StartsWith(">"))
{
portStatus = WMSG;
stepOneDone.Set();
}
else if (response.StartsWith("ERROR"))
{
portStatus = ERROR;
stepOneDone.Set();
stepTwoDone.Set();
}
else if (response.StartsWith("+CME ERROR") ||
response.StartsWith("+CMS ERROR"))
{
portStatus = ERROR;
portStatusMsg = response;
stepOneDone.Set();
stepTwoDone.Set();
}
else if (response.StartsWith("+CMTI") && response.Length > 12 )
{
int iStart = response.IndexOf(',');
if (iStart > 0)
{
iIndex = int.Parse(response.Substring(iStart + 1));
axMSComm.Output = "AT+CMGR=" + iIndex + "\x0d";
}
// bCmti = true;
}
else if(response.StartsWith("+CMGR:"))
{
axMSComm.Output = "AT+CMGD=" + iIndex + "\x0d";
}
//else if (response.StartsWith("07") || response.StartsWith("00"))
else if (response.StartsWith("0891"))
{
try
{
rx_sms = new IncomingSms(response);
MessageEventArgs e = new MessageEventArgs(rx_sms);
//portStatusLock.notify();
System.Console.WriteLine ("\r\nSMS received: " + rx_sms.ToString()+"\r\n");
OnMessage(e);
}
catch (Exception e)
{
System.Console.WriteLine ("Error receiving SMS message: unable to parse PDU:\r\n"+
response);
System.Console.WriteLine(e.StackTrace );
portStatus = ERROR;
}
}
else
{
//System.Console.WriteLine("continue: " + response);
continue;
}
}
// Remove the find from the string buffer
input = input.Replace(m.Value, "");
}
}
}
}
OK完了。给分吧呵呵Top
6 楼9728(生菜种子)回复于 2004-08-05 09:10:44 得分 0
谢谢楼上这位兄弟,好长呀!待会再慢慢学习,这是我在一位朋友指导下做的,经测试能接收扫锚枪的信息和打印信息。
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Collections.Specialized;
using System.Data;
using AxMSCommLib;
using MSCommLib;
namespace MyWinFomr
{
/// <summary>
/// ComTerm 的摘要说明。
/// </summary>
public delegate void ChangedEventHandler(object sender, string c);
public class ComTerm
{
MSComm com = new MSComm();
public event ChangedEventHandler Changed;
public ComTerm()
{
//
// TODO: 在此处添加构造函数逻辑
//
com.OnComm += new MSCommLib.DMSCommEvents_OnCommEventHandler(this.Receive);
InitComPort(2,9600);
}
//to call underlying com class/method to send command to com port
public bool Send(string sSendMsg)
{
if(sSendMsg != "")
{
com.Output = sSendMsg;
return true;
}
else
return false;
}
//Receive method to receive data from underlying class from com port
private void Receive()
{
if (Changed != null)
Changed(this, com.Input.ToString());
}
//PortSetting to setup port parameter such as portNumber and baudRate etc
public void InitComPort(short iPort,int iBaudRate)
{
// This port is already open, close it to reset it.
if (com.PortOpen) com.PortOpen = false;
// Set the com port to be 1
com.CommPort = iPort;
// Trigger the OnComm event whenever data is received
com.RThreshold = 1;
// Set the port to 9600 baud, no parity bit, 8 data bits, 1 stop bit (all standard)
com.Settings = iBaudRate + ",n,8,1";
// Force the DTR line high, used sometimes to hang up modems
com.DTREnable = true;
// No handshaking is used
com.Handshaking = MSCommLib.HandshakeConstants.comNone;
// Don't mess with byte arrays, only works with simple data (characters A-Z and numbers)
com.InputMode = MSCommLib.InputModeConstants.comInputModeText;
// Use this line instead for byte array input, best for most communications
//com.InputMode = MSCommLib.InputModeConstants.comInputModeText;
// Read the entire waiting data when com.Input is used
com.InputLen = 0;
// Don't discard nulls, 0x00 is a useful byte
com.NullDiscard = false;
// Attach the event handler
//com.OnComm += new System.EventHandler(this.OnComm);
// Open the com port
com.PortOpen = true;
}
}
}
Top
7 楼lifeixie(lifeixie)回复于 2004-10-09 16:36:25 得分 0
你那个委托是怎么用的?????Top
8 楼pphcsj(PPHC)回复于 2004-12-05 14:49:42 得分 0
写得很好,新手深受启发
楼主给分吧Top
9 楼lifeixie(lifeixie)回复于 2004-12-28 09:15:56 得分 0
对了还有更好的串口通信类么?Top
10 楼zhangA()回复于 2005-04-18 10:46:15 得分 0
markTop
11 楼gdf78(yeah)回复于 2005-04-30 18:22:19 得分 0
学习Top
12 楼heguosheng(何国胜)回复于 2005-05-08 13:55:56 得分 0
markTop




