C#开发串口总结,并提炼串口辅助类到公用类库中.doc_第1页
C#开发串口总结,并提炼串口辅助类到公用类库中.doc_第2页
C#开发串口总结,并提炼串口辅助类到公用类库中.doc_第3页
C#开发串口总结,并提炼串口辅助类到公用类库中.doc_第4页
C#开发串口总结,并提炼串口辅助类到公用类库中.doc_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

开发C#相关的项目有很多年了,一直没有接触串口的开发,近期由于工作的需要,需要了解熟悉对硬件串口的开发,通过对串口的深入了解,串口也不再是什么神秘的东西,利用SerailPort组件,对串口的各种操作也非常的方便,由于本人总是喜欢把一些常用的东西封装成可供重复利用的类库,因此,阅百家代码,提炼总结优化,把对串口的操作封装成一个公用的类库,应付日常的串口编程开发,也算是工作的一个阶段性总结吧。先上图,了解串口的一些基本的东西,并逐步介绍相关的知识。微软在 .NET FrameWork2.0中对串口通讯进行了封装,我们可以在.net2.0及以上版本开发时直接使用SerialPort类对串口进行读写操作。SerialPort类的属性主要包括:1)串口名称(PortName) 2)波特率(BaudRate)3)数据位 DataBits4)停止位 StopBits5)奇偶校验 Parity SerialPort类的事件主要包括:DataReceived:用于异步接收串口数据事件ErrorReceived:错误处理事件SerialPort类的方法主要包括: Open();Close();Read();Write()、DiscardInBuffer()、DiscardOutBuffer()等从上面的测试例子图中,我们可以看到,一般对串口的操作,需要提供串口号、波特率、数据位、停止位、奇偶校验的参数,用来构造一个串口操作类,以便实现具体的串口操作,而这些参数有的是系统内置的枚举参数,我们可以通过遍历枚举对象来绑定下来列表(如停止位、奇偶校验);但有些参数却不是系统内置的枚举类型,例如波特率、数据位等,而且对这些参数操作也是串口开发经常用到的,因此,第一步,我对这些参数的绑定做了一个简单的封装。1、先构造波特率、数据位这两个枚举对象,方便实际操作。/ / 串口数据位列表(5,6,7,8)/ public enum SerialPortDatabits : intFiveBits = 5,SixBits = 6,SeventBits = 7,EightBits = 8/ / 串口波特率列表。/ 75,110,150,300,600,1200,2400,4800,9600,14400,19200,28800,38400,56000,57600,/ 115200,128000,230400,256000/ public enum SerialPortBaudRates : intBaudRate_75 = 75,BaudRate_110 = 110,BaudRate_150 = 150,BaudRate_300 = 300,BaudRate_600 = 600,BaudRate_1200 = 1200,BaudRate_2400 = 2400,BaudRate_4800 = 4800,BaudRate_9600 = 9600,BaudRate_14400 = 14400,BaudRate_19200 = 19200,BaudRate_28800 = 28800,BaudRate_38400 = 38400,BaudRate_56000 = 56000,BaudRate_57600 = 57600,BaudRate_115200 = 115200,BaudRate_128000 = 128000,BaudRate_230400 = 230400,BaudRate_256000 = 256000 复制代码2、对常用的参数下拉列表绑定做一个封装。/ / 设置串口号/ / public static void SetPortNameValues(ComboBox obj)obj.Items.Clear();foreach (string str in SerialPort.GetPortNames()obj.Items.Add(str);/ / 设置波特率/ public static void SetBauRateValues(ComboBox obj)obj.Items.Clear();foreach (SerialPortBaudRates rate in Enum.GetValues(typeof(SerialPortBaudRates)obj.Items.Add(int)rate).ToString();/ / 设置数据位/ public static void SetDataBitsValues(ComboBox obj)obj.Items.Clear();foreach (SerialPortDatabits databit in Enum.GetValues(typeof(SerialPortDatabits)obj.Items.Add(int)databit).ToString();/ / 设置校验位列表/ public static void SetParityValues(ComboBox obj)obj.Items.Clear();foreach (string str in Enum.GetNames(typeof(Parity)obj.Items.Add(str);/ / 设置停止位/ public static void SetStopBitValues(ComboBox obj)obj.Items.Clear();foreach (string str in Enum.GetNames(typeof(StopBits)obj.Items.Add(str); 复制代码这样我们在窗体界面代码中,绑定相关参数的数据源就很方便了,如下所示。private void Form1_Load(object sender, EventArgs e)BindData();private void BindData()/绑定端口号SerialPortUtil.SetPortNameValues(txtPort);txtPort.SelectedIndex = 0;/波特率SerialPortUtil.SetBauRateValues(txtBaudRate);txtBaudRate.SelectedText = 57600;/数据位SerialPortUtil.SetDataBitsValues(txtDataBits);this.txtDataBits.SelectedText = 8;/校验位SerialPortUtil.SetParityValues(txtParity);this.txtParity.SelectedIndex = 0;/停止位SerialPortUtil.SetStopBitValues(txtStopBit);this.txtStopBit.SelectedIndex = 1;this.btnSend.Enabled = isOpened;复制代码3、 为了方便构造封装的窗口类,提供了两个不同类型参数的串口辅助类构造函数,一个可以使用枚举参数,一个使用字符串参数(最终转换为枚举参数对象),如下所示。使用枚举对象,不需要记住不同参数应该填写那些值,只需要从枚举中选择即可,方便又直观。/ / 参数构造函数(使用枚举参数构造)/ / 波特率/ 奇偶校验位/ 停止位/ 数据位/ 串口号public SerialPortUtil(string name, SerialPortBaudRates baud, Parity par, SerialPortDatabits dBits, StopBits sBits)_portName = name;_baudRate = baud;_parity = par;_dataBits = dBits;_stopBits = sBits;comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);comPort.ErrorReceived += new SerialErrorReceivedEventHandler(comPort_ErrorReceived);/ / 参数构造函数(使用字符串参数构造)/ / 波特率/ 奇偶校验位/ 停止位/ 数据位/ 串口号public SerialPortUtil(string name, string baud, string par, string dBits, string sBits)_portName = name;_baudRate = (SerialPortBaudRates)Enum.Parse(typeof(SerialPortBaudRates), baud);_parity = (Parity)Enum.Parse(typeof(Parity), par);_dataBits = (SerialPortDatabits)Enum.Parse(typeof(SerialPortDatabits), dBits);_stopBits = (StopBits)Enum.Parse(typeof(StopBits), sBits);comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);comPort.ErrorReceived += new SerialErrorReceivedEventHandler(comPort_ErrorReceived);复制代码构造函数做好了,就很方便在实际的窗体界面函数中构造串口实例了,如下使用代码所示:private void btnConnect_Click(object sender, EventArgs e)tryif (serial = null)trystring portname = this.txtPort.Text;SerialPortBaudRates rate = (SerialPortBaudRates)Enum.Parse(typeof(SerialPortBaudRates), this.txtBaudRate.Text);/int.Parse(this.txtBaudRate.Text);SerialPortDatabits databit = (SerialPortDatabits)int.Parse(this.txtDataBits.Text);Parity party = (Parity)Enum.Parse(typeof(Parity), this.txtParity.Text);StopBits stopbit = (StopBits)Enum.Parse(typeof(StopBits), this.txtStopBit.Text);/使用枚举参数构造/serial = new SerialPortUtil(portname, rate, party, databit, stopbit);/使用字符串参数构造serial = new SerialPortUtil(portname, this.txtBaudRate.Text, this.txtParity.Text, this.txtDataBits.Text, this.txtStopBit.Text);serial.DataReceived += new DataReceivedEventHandler(serial_DataReceived);catch (Exception ex)MessageBox.Show(ex.Message);serial = null;return;if (!isOpened) serial.OpenPort();btnConnect.Text = 断开;elseserial.ClosePort();serial = null;btnConnect.Text = 连接;isOpened = !isOpened;this.btnSend.Enabled = isOpened;this.lblTips.Text = isOpened ? 已连接 : 未连接;catch (Exception ex)this.lblTips.Text = ex.Message;MessageBox.Show(ex.Message);复制代码4、对串口数据的发送以及串口的一些基本操作进行简单封装,方便辅助类对串口进行相关操作。/ / 端口是否已经打开/ public bool IsOpengetreturn comPort.IsOpen;/ / 打开端口/ / public void OpenPort()if (comPort.IsOpen) comPort.Close();comPort.PortName = _portName;comPort.BaudRate = (int)_baudRate;comPort.Parity = _parity;comPort.DataBits = (int)_dataBits;comPort.StopBits = _stopBits;comPort.Open();/ / 关闭端口/ public void ClosePort()if (comPort.IsOpen) comPort.Close();/ / 丢弃来自串行驱动程序的接收和发送缓冲区的数据/ public void DiscardBuffer()comPort.DiscardInBuffer();comPort.DiscardOutBuffer();/ / 写入数据/ / public void WriteData(string msg)if (!(comPort.IsOpen) comPort.Open();comPort.Write(msg);/ / 写入数据/ / 写入端口的字节数组public void WriteData(byte msg)if (!(comPort.IsOpen) comPort.Open();comPort.Write(msg, 0, msg.Length);/ / 写入数据/ / 包含要写入端口的字节数组/ 参数从0字节开始的字节偏移量/ 要写入的字节数public void WriteData(byte msg, int offset, int count)if (!(comPort.IsOpen) comPort.Open();comPort.Write(msg, offset, count);复制代码6、接收数据的还原这样基本上就对串口封装的差不多了,不过还有一个重要的操作就是对串口的数据进行接收,并进行处理。由于串口获取数据不是一次性完整的获取的,可能会被拆分为好几段,因此,如何还原接收到的数据也就是一个值得注意的问题,这个最好能根据协议来确定,如我的协议基本上是以“”符号开始,以“#”符号结束,因此我对协议数据的还原,就有可依据的准则。1)首先要构造一个数据处理的代理,和一个数据处理的事件参数类,如下所示。 public class DataReceivedEventArgs : EventArgspublic string DataReceived;public DataReceivedEventArgs(string m_DataReceived)this.DataReceived = m_DataReceived;public delegate void DataReceivedEventHandler(DataReceivedEventArgs e); 复制代码2)然后构造一个数据接收和错误处理的事件,如下所示/ / 完整协议的记录处理事件/ public event DataReceivedEventHandler DataReceived;public event SerialErrorReceivedEventHandler Error; 复制代码3)在构造函数添加相关的事件处理,如下所示/ / 参数构造函数(使用枚举参数构造)/ / 波特率/ 奇偶校验位/ 停止位/ 数据位/ 串口号public SerialPortUtil(string name, SerialPortBaudRates baud, Parity par, SerialPortDatabits dBits, StopBits sBits)_portName = name;_baudRate = baud;_parity = par;_dataBits = dBits;_stopBits = sBits;comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);comPort.ErrorReceived += new SerialErrorReceivedEventHandler(comPort_ErrorReceived);复制代码4)实现对数据的接收和错误的处理 / / 结束符比特/ public byte EndByte = 0x23;/string End = #;/ / 数据接收处理/ void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)/禁止接收事件时直接退出if (ReceiveEventFlag) return;#region 根据结束字节来判断是否全部获取完成List _byteData = new List();bool found = false;/是否检测到结束符号while (comPort.BytesToRead 0 | !found)byte readBuffer = new bytecomPort.ReadBufferSize + 1;int count = comPort.Read(readBuffer, 0, comPort.ReadBufferSize);for (int i = 0; i count; i+

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论