C# 和MsComm
对于从事工控和单片机工作的人来说串口编程是很常用的和很重要的。事实上在VB.net和C#中对串口的操作和VS6里没有大的区别。你仍然可以直接调用API或者使用MSComm或其他第三方控件。这里只介绍大家常用的MSComm。例子使用2、3脚跳过线的串口将COM1和COM2连接。
首先,你必须有MSComm.ocx文件在你的Windows的System32目录下,而且它必须正确的注册。你可以装VS6来获得,微软也指出这样不会有冲突。当然我们可以自己注册而不用装庞大的VS6。先将MSComm.ocx复制到System32目录下,然后使用edit工具编辑一个以.reg扩展名的文件,在文件里输入以下的文字
REGEDIT
HKEY_CLASSES_ROOT\Licenses = Licensing: Copying the keys may be a violation of established copyrights.
// The MsComm32 Control License follows:
HKEY_CLASSES_ROOT\Licenses\4250E830-6AC2-11cf-8ADB-00AA00C00905 = kjljvjjjoquqmjjjvpqqkqmqykypoqjquoun
然后,存盘。双击文件就完成了注册。
现在,我们介绍一下MSComm在VB.net和C#中和VS6里的不同和实际的应用。在VB.net或C#中建立一个窗口Form1。加入两个MSComm控件,你会发现这里MSComm的默认名字是axMSComm,有点奇怪吧。同时因为命名空间的问题你不能给axMSComm1.InputMode赋0或1这样的值。你只能这样来做如axMSComm1.InputMode=MSCommLib.InputModeConstants.comInputModeBinary或者axMSComm1.InputMode=MSCommLib.InputModeConstants.comInputModeText。
现在我们在窗口中加入textBox和button控件。在Form1_Load中加入以下的代码(C#版本):
try
{
axMSComm1.PortOpen =true;
axMSComm2.PortOpen =true;
}
catch
{
MessageBox.Show ("串口操作失败");
}
(VB.net版本)
Try
axMSComm1.PortOpen = True
axMSComm2.PortOpen = True
Catch
MsgBox("串口操作失败", MsgBoxStyle.Critical)
End Try
在button的Click事件中加入以下代码:
(C#版本)
byte[] bytOut=new byte[1];
bytOut[0]=255;
axMSComm2.Output=bytOut;
//这里我们只发一字节0ffh如果发更多可以定义更大的数组
(VB.net版本)
Dim bytOut as byte=255
axMSComm2.Output=bytOut
现在在axMSComm1_OnComm中加入
(C#版本)
string strIn=""
byte[] bytIn;
object objIn;
int i;
axMSComm1.InputMode=MSCommLib.InputModeConstants.comInputModeBinary;
axMSComm1.InputLen = 0;
objIn=axMSComm1.Input //这里注意axMSComm1.Input返回的是一个object的
bytIn =(byte[])objIn; //类型,所以必须使用显式的类型转换,这点和VB不同
for (i=0;i<=(bytIn.Length-1);i++ )
{
strIn +="\r\n"+ " "+bytIn[i].ToString("X"); //转换为16进制显示
}
textBox1.Text+=strIn;
(VB.net版本)
Dim strIn as string =””
Dim bytIn() as byte
Dim I as Integer
axMSComm1.InputMode=MSCommLib.InputModeConstants.comInputModeBinary
axMSComm1.InputLen = 0
bytIn=axMSComm1.Input
For i = 0 To UBound(bytInput)
strIn +="\r\n"+ " "+Hex(bytIn[i])
Next
textBox1.Text+=strIn
这里请注意C#在接收的时候与VB的不同。
将axMSComm1的属性RThreshold设置为1,axMSComm1和axMSComm2的SThreshold 设置为0。现在可以编译运行了,请用一条2、3脚跳过线的NullModem线连接计算机的COM1和COM2,运行后,点击button你应该在textBox中看到FF并换行。
这里使用axMSComm1接收axMSComm2发送,只发了一个字节,但更多的字节发送也没什么问题,只要定义更大的数组就可以了,当然如果你感觉MSComm不够强大你可以调用api或者自己定义一个控制串口的类。
MSComm的其他的属性和VS6中没什么太大的不同,你可以自己试试。
public System.Threading.Thread MSComm_Receive;
public bool MSComm_IsOpen;
public bool StartComm(string CommPort,int TimeOutValue)
{
try
{
axMSComm1.CommPort = Convert.ToInt16(CommPort);
axMSComm1.Settings = "9600,N,8,1";
axMSComm1.Input = 0;
axMSComm1.CDTimeout = TimeOutValue;
axMSComm1.PortOpen = true;
MSComm_IsOpen = true;
MSComm_Receive = new System.Threading.Thread(new System.Threading.ThreadStart(this.ReceiveTxtFromComm));
MSComm_Receive.Start();
return true;
}
catch (Exception ex)
{
MSComm_IsOpen = false;
MessageBox.Show(ex.ToString());
return false;
}
}
public bool EndComm(string CommPort)
{
try
{
axMSComm1.PortOpen = false;
MSComm_IsOpen = false;
MSComm_Receive.Abort();
return true;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
return false;
}
}
public void SendCMDToComm(string sendtext)
{
try
{
axMSComm1.Output = sendtext;
}
catch (Exception ex)
{
MessageBox.Show(ex.ToString());
}
}
上面是简单的发送信息,接收信息模块我还没有写好,思路是单起一个线程,然后使用OnComm事件检测是否有输入读入,如果有的话,使用Raise来引导一个时间,然后在App中编写具体的处理程序。
如何在C#中添加MSComm控件,工具箱中没有啊~!
各位大侠.我用.NET可是没有MSComm控件啊~!
最佳答案工具箱没有,那就手动加载啊,在工具箱点鼠标右键“选择项”,从弹出的对话框中选择即可。
有下载: http://www-ese.fnal.gov/D0Cal_TWG/MSCOMM.zip 含有4个文件:MSCOMM32.OCX, MSCOMM.SRG, MSCOMM32.DEP, MSCOMM32.OCA 三个是你要的。。。 顺便看一下怎么注册: http://www.gjwtech.com/scomm/manaualregistermscomm.htm
本来开发的是采用使用modem接受对方电话号码,并且在数据库中查询对方的信息的一个功能采用的是C#+MSCOMM来做的在下面的事件中,每当客户来电显示的是"Ring"这个单词,没有象我想象的是显示号码,这个是为什么呢??大家帮帮忙private void axMSComm1_OnComm_1(object sender, System.EventArgs e){switch(this.axMSComm2.CommEvent){case 2://this.textBox2.Text="有信号在Com1端口";MessageBox.Show(this.axMSComm2.Input.ToString());break;default:break;}}在有电话得时候就是现在 MessageBox.Show(this.axMSComm2.Input.ToString());得时候出现一个框框,框框里面就是有一个单词"RING",要是就是说通信协议得关系,里面也应该是 日期+号码这样得格式吧?另外程序开始在Form_load里面我写得是 this.axMSComm2.Output="AT#CID=1\r\n";不知道是不是这么写?大家帮忙啊
回复:
答者:yxycon() 信誉:100 级别:user1 日期:2006-9-19 10:30:14 id:36822581
我以前用DELPHI写过,你那种情况可能是MODEN不支持来电显示功能,市面上这种MODEN少了,我是订做了一个,你要查一下现在什么猫支持来电,可以下载一个已有的软件你先测一下有没有来电功能
答者:tnt8csdn2000(琥珀雨田) 信誉:100 级别:user5 日期:2006-9-19 10:33:54 id:36822693
如果是商业软件建议去购买来电显示盒.200块钱左右.做得人很多.
答者:netjiwei(老虎) 信誉:100 级别:user2 日期:2006-9-19 10:55:10 id:36823343
问题是说明书上写着支持来电显示得原文这么写得V.92所具有得上网同时打电话和来电显示功能只有在电信局、接入服务商以及相应软件支持得情况下方可使用。现在电话肯定是能显示号码得,这样得话是不是就应该叫支持了??
答者:netjiwei(老虎) 信誉:100 级别:user2 日期:2006-9-19 11:23:01 id:36824232
我现在用超级终端测试了一下,显示如下:RINGDATE = 0919TIME = 1119NMBR = 013671137048这个说明我得modem肯定支持来电显示,但是是在private void axMSComm1_OnComm_1(object sender, System.EventArgs e){switch(this.axMSComm2.CommEvent){case 2://this.textBox2.Text="有信号在Com1端口";MessageBox.Show(this.axMSComm2.Input.ToString());break;default:break;}}这里没有能够把缓冲里面得数据全部读出来,请问我应该怎么解决,希望大大门帮帮忙啊,很着急得,谢谢
答者:netjiwei(老虎) 信誉:100 级别:user2 日期:2006-9-21 11:23:07 id:36871847
没有人知道吗
答者:yizhixiaozhu(天啦,手都起茧了) 信誉:99 级别:user1 日期:2006-10-4 20:41:50 id:37079120
用超级终端能模拟电话拨入?