C#串口类.docx

上传人:b****6 文档编号:7534942 上传时间:2023-01-24 格式:DOCX 页数:15 大小:20.21KB
下载 相关 举报
C#串口类.docx_第1页
第1页 / 共15页
C#串口类.docx_第2页
第2页 / 共15页
C#串口类.docx_第3页
第3页 / 共15页
C#串口类.docx_第4页
第4页 / 共15页
C#串口类.docx_第5页
第5页 / 共15页
点击查看更多>>
下载资源
资源描述

C#串口类.docx

《C#串口类.docx》由会员分享,可在线阅读,更多相关《C#串口类.docx(15页珍藏版)》请在冰豆网上搜索。

C#串口类.docx

C#串口类

最近在做串口通信,和大家分享一下。

C#语言把串口类做的很好,用起来很是方便。

  技术要点

  在.NETFramework2.0中提供了SerialP`ort类,该类主要实现串口数据通信等。

下面主要介绍该类的主要属性(表13.1)和方法(表13.2)。

  表13.1SerialPort类的常用属性

  名称  说明

  BaseStream  获取SerialPort对象的基础Stream对象

  BaudRate  获取或设置串行波特率

  BreakState  获取或设置中断信号状态

  BytesToRead  获取接收缓冲区中数据的字节数

  BytesToWrite  获取发送缓冲区中数据的字节数

  CDHolding  获取端口的载波检测行的状态

  CtsHolding  获取“可以发送”行的状态

  DataBits  获取或设置每个字节的标准数据位长度

  DiscardNull  获取或设置一个值,该值指示Null字节在端口和接收缓冲区之间传输时是否被忽略

  DsrHolding  获取数据设置就绪(DSR)信号的状态

  DtrEnable  获取或设置一个值,该值在串行通信过程中启用数据终端就绪(DTR)信号

  Encoding  获取或设置传输前后文本转换的字节编码

  Handshake  获取或设置串行端口数据传输的握手协议

  IsOpen  获取一个值,该值指示SerialPort对象的打开或关闭状态

  NewLine  获取或设置用于解释ReadLine()和WriteLine()方法调用结束的值

  Parity  获取或设置奇偶校验检查协议

  ParityReplace 获取或设置一个字节,该字节在发生奇偶校验错误时替换数据流中的无效字节

  PortName   获取或设置通信端口,包括但不限于所有可用的COM端口

  ReadBufferSize  获取或设置SerialPort输入缓冲区的大小

  ReadTimeout  获取或设置读取操作未完成时发生超时之前的毫秒数

  ReceivedBytesThreshold  获取或设置DataReceived事件发生前内部输入缓冲区中的字节数

  RtsEnable  获取或设置一个值,该值指示在串行通信中是否启用请求发送(RTS)信号

  StopBits  获取或设置每个字节的标准停止位数

  WriteBufferSize  获取或设置串行端口输出缓冲区的大小

  WriteTimeout  获取或设置写入操作未完成时发生超时之前的毫秒数

  

  表13.2SerialPort类的常用方法

  方法名称  说明

  Close  关闭端口连接,将IsOpen属性设置为False,并释放内部Stream对象

  Open  打开一个新的串行端口连接

  Read  从SerialPort输入缓冲区中读取

  ReadByte  从SerialPort输入缓冲区中同步读取一个字节

  ReadChar  从SerialPort输入缓冲区中同步读取一个字符

  ReadLine  一直读取到输入缓冲区中的NewLine值

  ReadTo  一直读取到输入缓冲区中指定value的字符串

  Write  已重载。

将数据写入串行端口输出缓冲区

  WriteLine 将指定的字符串和NewLine值写入输出缓冲区

  

  注意:

用跳线使串口的第2、3针连接,可以在本地计算机上实现串口通信,所以,通过串口的第2、3针的连接可以对程序进行检测。

  实现过程

  

(1)新建一个项目,命名为Ex13_01,默认窗体为Form1。

  

(2)在Form1窗体中,主要添加两个Button控件,分别用于执行发送数据和接受数据,添加两个TextBox控件,用于输入发送数据和显示接收数据。

  (3)主要程序代码。

  privatevoidbutton1_Click(objectsender,EventArgse)

  {

  serialPort1.PortName="COM1";

  serialPort1.BaudRate=9600;

  serialPort1.Open();

  byte[]data=Encoding.Unicode.GetBytes(textBox1.Text);

  stringstr=Convert.ToBase64String(data);

  serialPort1.WriteLine(str);

  MessageBox.Show("数据发送成功!

","系统提示");

  }

  privatevoidbutton2_Click(objectsender,EventArgse)

  {

  byte[]data=Convert.FromBase64String(serialPort1.ReadLine());

  textBox2.Text=Encoding.Unicode.GetString(data);

  serialPort1.Close();

  MessageBox.Show("数据接收成功!

","系统提示");

  }

  举一反三

  根据本实例,读者可以实现以下功能。

  远程监控对方计算机屏幕。

  下位机控制程序。

  实例419通过串口关闭对方计算机

  实例说明

  在网络应用程序中,主要通过网卡实现数据的传输,因此可以利用套接字技术实现远程关闭计算机。

如果计算机中没有安装网卡,该如何实现远程关闭计算机呢?

本例实现了利用串口关闭对方计算机.

  技术要点

  本实例使用SerialPort类的属性和方法,请参见实例“通过串口发送数据”。

下面主要介绍SerialPort类的DataReceived事件,DataReceived事件为本实例的主要使用技术。

DataReceived事件表示将处理SerialPort对象的数据接收事件的方法。

串行接收事件可以由SerialData枚举中的任何项引起,是否引发此事件由操作系统决定,所以不一定会报告所有奇偶校验错误。

  注意:

本实例从开发到测试,都是由本地计算机完成的,用户只需要使用跳线将串口的第2、3针连接,可以在本地计算机上实现串口通信。

  实现过程

  

(1)新建一个项目,命名为Ex13_02,默认窗体为Form1。

  

(2)在Form1窗体中,主要添加两个Button控件,分别用于打开通信串口和关闭对方计算机。

  (3)主要程序代码。

  privatevoidbutton1_Click(objectsender,EventArgse)

  {

  //打开串口

  serialPort1.PortName="COM1";

  serialPort1.Open();

  button1.Enabled=false;

  button2.Enabled=true;

  }//数据接收事件,等待接收关机命令

  privatevoidserialPort1_DataReceived(objectsender,SerialDataReceivedEventArgse)

  {

  byte[]data=Convert.FromBase64String(serialPort1.ReadLine());

  stringstr=Encoding.Unicode.GetString(data);

  serialPort1.Close();

  if(str=="关机")

  {

  Processp=newProcess();

  p.StartInfo.FileName="cmd.exe";

  p.StartInfo.UseShellExecute=false;

  p.StartInfo.RedirectStandardInput=true;

  p.StartInfo.RedirectStandardOutput=true;

  p.StartInfo.RedirectStandardError=true;

  p.StartInfo.CreateNoWindow=true;

  p.Start();

  p.StandardInput.WriteLine("shutdown/s");

  p.StandardInput.WriteLine("exit");

  }

  }//发送关机命令

  privatevoidbutton2_Click(objectsender,EventArgse)

  {

  if(button2.Text=="关闭计算机")

  {

  //发送关机命令数据

  byte[]data=Encoding.Unicode.GetBytes("关机");

  stringstr=Convert.ToBase64String(data);

  serialPort1.WriteLine(str);

  button2.Text="取消关机";

  }

  else

  {

  button2.Text="关闭计算机";

  button1.Enabled=true;

  button2.Enabled=false;

  //取消关机

  Processp=newProcess();

  p.StartInfo.FileName="cmd.exe";

  p.StartInfo.UseShellExecute=false;

  p.StartInfo.RedirectStandardInput=true;

  p.StartInfo.RedirectStandardOutput=true;

  p.StartInfo.RedirectStandardError=true;

  p.StartInfo.CreateNoWindow=true;

  p.Start();

  p.StandardInput.WriteLine("shutdown/a");

  p.StandardInput.WriteLine("exit");

  }

  }

  在我的测试软件中发现一个问题,就是当发送数据小于或等于8位时,一切正常,如果大于8为字节,则在datareceived事件中接收到的数据会分成两段,第一段为8位,第二段为剩下的字节,很奇怪,在msdn中讲到不能保证每次发送的数据都能正确接收到,需要参照BytesToRead属性来确定要读取的数据量,所以我想出来的解决办法为:

  intDataLength=serialPort.BytesToRead;

  inti=0;

  StringBuildersb=newStringBuilder();

  while(i

  {

  byte[]ds=newbyte[1024];

  intlen=serialPort.Read(ds,0,1024);

  sb.Append(Encoding.Ascii.GetString(ds,0,len));

  i+=len;

  }

  Console.Write(sb,ToString());

  这种奇怪的方法可以解决问题,后来想想应该是串口的工作方式决定的也有可能,期待其他的解决方式。

微软代码:

取出本机的COM端口字符串

publicstaticstring[]GetPortNames()

{

RegistryKeylocalMachine=null;

RegistryKeykey2=null;

string[]textArray=null;

//这里有个断言,判断该注册表项是否存在

newRegistryPermission(RegistryPermissionAccess.Read,@"HKEY_LOCAL_MACHINE\HARDWARE\DEVICEMAP\SERIALCOMM").Assert();

try

{

localMachine=Registry.LocalMachine;

key2=localMachine.OpenSubKey(@"HARDWARE\DEVICEMAP\SERIALCOMM",false);

if(key2!

=null)

{

string[]valueNames=key2.GetValueNames();

textArray=newstring[valueNames.Length];

for(inti=0;i

{

textArray[i]=(string)key2.GetValue(valueNames[i]);

}

}

}

finally

{

if(localMachine!

=null)

{

localMachine.Close();

}

if(key2!

=null)

{

key2.Close();

}

CodeAccessPermission.RevertAssert();

}

if(textArray==null)

{

textArray=newstring[0];

}

returntextArray;

}

VS.NET2005中SerialPort控件操作详解(C#)

usingSystem;

usingSystem.Collections.Generic;

usingSystem.ComponentModel;

usingSystem.Data;

usingSystem.Drawing;

usingSystem.Text;

usingSystem.Windows.Forms;

usingSystem.IO.Ports;

namespaceSerialPorts

{

publicpartialclassfrm_Main:

Form

{

#regionPublicEnumerations

publicenumDataMode{Text,Hex}

publicenumLogMsgType{Incoming,Outgoing,Normal,Warning,Error};

#endregion

privateColor[]LogMsgTypeColor={Color.Orange,Color.Green,Color.Black,Color.Blue,Color.Red};

//禁用和启用程序中各控件的状态

privatevoidEnableControls()

{

//基于串口的打开与否,设置控件状态

gbPortSettings.Enabled=!

ComPort.IsOpen;

btns.Enabled=btnstop.Enabled=txtSendData.Enabled=btnSend.Enabled=ComPort.IsOpen;

if(ComPort.IsOpen)btnOpenPort.Text="关闭串口";

elsebtnOpenPort.Text="打开串口";

}

//初始化组件的数据,为串口提供相关参数

privatevoidInitializeControlValues()

{

cmbParity.Items.Clear();cmbParity.Items.AddRange(Enum.GetNames(typeof(Parity)));

cmbStopBits.Items.Clear();cmbStopBits.Items.AddRange(Enum.GetNames(typeof(StopBits)));

cmbPortName.Items.Clear();

foreach(stringsinSerialPort.GetPortNames())

cmbPortName.Items.Add(s);

cmbPortName.Text=cmbPortName.Items[0].ToString();

cmbParity.Text=cmbParity.Items[0].ToString();

cmbStopBits.Text=cmbStopBits.Items[0].ToString();

cmbDataBits.Text=cmbDataBits.Items[0].ToString();

cmbParity.Text=cmbParity.Items[0].ToString();

cmbBaudRate.Text=cmbBaudRate.Items[0].ToString();

EnableControls();

}

//十六进制转换字节数组

privatebyte[]HexStringToByteArray(strings)

{

s=s.Replace("","");

byte[]buffer=newbyte[s.Length/2];

for(inti=0;i

buffer[i/2]=(byte)Convert.ToByte(s.Substring(i,2),16);

returnbuffer;

}

//字节数组转换十六进制

privatestringByteArrayToHexString(byte[]data)

{

StringBuildersb=newStringBuilder(data.Length*3);

foreach(bytebindata)

sb.Append(Convert.ToString(b,16).PadLeft(2,'0').PadRight(3,''));

returnsb.ToString().ToUpper();

}

//显示数据日志

privatevoidLog(LogMsgTypemsgtype,stringmsg)

{

rtfTerminal.Invoke(newEventHandler(delegate

{

rtfTerminal.SelectedText=string.Empty;

rtfTerminal.SelectionFont=newFont(rtfTerminal.SelectionFont,FontStyle.Bold);

rtfTerminal.SelectionColor=LogMsgTypeColor[(int)msgtype];

rtfTerminal.AppendText(msg);

rtfTerminal.ScrollToCaret();

}));

}

//串口发送方式

#regionLocalProperties

privateDataModeCurrentDataMode

{

get

{

if(rbHex.Checked)returnDataMode.Hex;

elsereturnDataMode.Text;

}

set

{

if(value==DataMode.Text)rbText.Checked=true;

elserbHex.Checked=true;

}

}

#endregion

//发送数据

privatevoidSendData()

{

if(CurrentDataMode==DataMode.Text)

{

//发送用户的文本到串口

ComPort.Write(txtSendData.Text);

//将用户的文本显示到数据窗口

Log(LogMsgType.Outgoing,txtSendData.Text+"\n");

}

else

{

try

{

//转换用户十六进制数据到字节数组

byte[]data=HexStringToByteArray(txtSendData.Text);

//发送数据到串口

ComPort.Write(data,0,data.Length);

//将用户十六进制数据到数据窗口

Log(LogMsgType.Outgoing,ByteArrayToHexString(data)+"\n");

}

catch(FormatException)

{

//转换错误

Log(LogMsgType.Error,"十六进制数据有误:

"+txtSendData.Text+"\n");

}

}

txtSendData.SelectAll();

}

///

///-------------------------------------------------------------

///

publicfrm_Main()

{

InitializeComponent();

}

privatevoidForm1_Load(objectsender,EventArgse)

{

InitializeControlValues();

ComPort.DataReceived+=newSerialDataReceivedEventHandler(port_DataReceived);

}

//打开串口

privatevoidbtnOpenPort_Click(objectsender,EventArgse)

{

if(ComPort.IsOpen)ComPort.Close();

else

{

//设置串口参数

ComPort.BaudRate=int.Parse(cmbBaudRate.Text);

ComPort.DataBits=int.Parse(cmbDataBits.Text);

ComPort.StopBits=(StopBits)Enum.Parse(typeof(StopBits),cmb

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 经管营销 > 生产经营管理

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1