- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Data;
- using System.Drawing;
- using System.Text;
- using System.Windows.Forms;
- using System.IO.Ports;
- using System.Threading;
- namespace TestSerialPort
- {
- public partial class frmTESTSerialPort : Form
- {
- public frmTESTSerialPort()
- {
- InitializeComponent();
- Control.CheckForIllegalCrossThreadCalls = false;
- }
- private Button button1;
- private TextBox txtSend;
- private TextBox txtReceive;
- private Label label1;
- private Label label2;
- /// <summary>
- /// 必需的设计器变量。
- /// </summary>
- private System.ComponentModel.IContainer components = null;
- /// <summary>
- /// 清理所有正在使用的资源。
- /// </summary>
- /// <param name="disposing">如果应释放托管资源,为 true;否则为 false。</param>
- protected override void Dispose(bool disposing)
- {
- if (disposing && (components != null))
- {
- components.Dispose();
- }
- base.Dispose(disposing);
- }
- #region Windows 窗体设计器生成的代码
- /// <summary>
- /// 设计器支持所需的方法 - 不要
- /// 使用代码编辑器修改此方法的内容。
- /// </summary>
- private void InitializeComponent()
- {
- this.button1 = new System.Windows.Forms.Button();
- this.txtSend = new System.Windows.Forms.TextBox();
- this.txtReceive = new System.Windows.Forms.TextBox();
- this.label1 = new System.Windows.Forms.Label();
- this.label2 = new System.Windows.Forms.Label();
- this.SuspendLayout();
- //
- // button1
- //
- this.button1.Location = new System.Drawing.Point(440, 379);
- this.button1.Name = "button1";
- this.button1.Size = new System.Drawing.Size(75, 23);
- this.button1.TabIndex = 0;
- this.button1.Text = "发送";
- this.button1.UseVisualStyleBackColor = true;
- this.button1.Click += new System.EventHandler(this.button1_Click);
- //
- // txtSend
- //
- this.txtSend.Location = new System.Drawing.Point(59, 12);
- this.txtSend.Multiline = true;
- this.txtSend.Name = "txtSend";
- this.txtSend.Size = new System.Drawing.Size(456, 164);
- this.txtSend.TabIndex = 2;
- //
- // txtReceive
- //
- this.txtReceive.Location = new System.Drawing.Point(59, 200);
- this.txtReceive.Multiline = true;
- this.txtReceive.Name = "txtReceive";
- this.txtReceive.Size = new System.Drawing.Size(456, 164);
- this.txtReceive.TabIndex = 2;
- //
- // label1
- //
- this.label1.Location = new System.Drawing.Point(13, 15);
- this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(41, 12);
- this.label1.TabIndex = 0;
- this.label1.Text = "发送";
- //
- // label2
- //
- this.label2.Location = new System.Drawing.Point(13, 213);
- this.label2.Name = "label2";
- this.label2.Size = new System.Drawing.Size(41, 12);
- this.label2.TabIndex = 0;
- this.label2.Text = "接收";
- //
- // frmTESTSerialPort
- //
- this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
- this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
- this.ClientSize = new System.Drawing.Size(546, 434);
- this.Controls.Add(this.label2);
- this.Controls.Add(this.label1);
- this.Controls.Add(this.txtReceive);
- this.Controls.Add(this.txtSend);
- this.Controls.Add(this.button1);
- this.Name = "frmTESTSerialPort";
- this.Text = "串口试验";
- this.ResumeLayout(false);
- this.PerformLayout();
- }
- #endregion
- private void button1_Click(object sender, EventArgs e)
- {
- //实例化串口对象(默认:COMM1,9600,e,8,1)
- SerialPort serialPort1 = new SerialPort();
- //更改参数
- serialPort1.PortName = "COM1";
- serialPort1.BaudRate = 19200;
- serialPort1.Parity = Parity.Odd;
- serialPort1.StopBits = StopBits.Two;
- //上述步骤可以用在实例化时调用SerialPort类的重载构造函数
- //SerialPort serialPort = new SerialPort("COM1", 19200, Parity.Odd, StopBits.Two);
- //打开串口(打开串口后不能修改端口名,波特率等参数,修改参数要在串口关闭后修改)
- serialPort1.Open();
- //发送数据
- SendStringData(serialPort1);
- //也可用字节的形式发送数据
- //SendBytesData(serialPort1);
- //开启接收数据线程
- ReceiveData(serialPort1);
- }
- //发送字符串数据
- private void SendStringData(SerialPort serialPort)
- {
- serialPort.Write(txtSend.Text);
- }
- /// <summary>
- /// 开启接收数据线程
- /// </summary>
- private void ReceiveData(SerialPort serialPort)
- {
- //同步阻塞接收数据线程
- Thread threadReceive=new Thread(new ParameterizedThreadStart(SynReceiveData));
- threadReceive.Start(serialPort);
- //也可用异步接收数据线程
- //Thread threadReceiveSub = new Thread(new ParameterizedThreadStart(AsyReceiveData));
- //threadReceiveSub.Start(serialPort);
- }
- //发送二进制数据
- private void SendBytesData(SerialPort serialPort)
- {
- byte[] bytesSend=System.Text.Encoding.Default.GetBytes(txtSend.Text );
- serialPort.Write(bytesSend, 0, bytesSend.Length);
- }
- //同步阻塞读取
- private void SynReceiveData(object serialPortobj)
- {
- SerialPort serialPort = (SerialPort)serialPortobj;
- System.Threading.Thread.Sleep(0);
- serialPort.ReadTimeout = 1000;
- try
- {
- //阻塞到读取数据或超时(这里为2秒)
- byte firstByte=Convert.ToByte(serialPort.ReadByte());
- int bytesRead=serialPort.BytesToRead ;
- byte[] bytesData=new byte[bytesRead+1];
- bytesData[0] = firstByte;
- for (int i = 1; i <=bytesRead; i++)
- bytesData = Convert.ToByte( serialPort.ReadByte());
- txtReceive.Text = System.Text.Encoding.Default.GetString(bytesData);
- }
- catch(Exception e)
- {
- MessageBox.Show(e.Message);
- //处理超时错误
- }
- serialPort.Close();
- }
- //异步读取
- private void AsyReceiveData(object serialPortobj)
- {
- SerialPort serialPort = (SerialPort)serialPortobj;
- System.Threading.Thread.Sleep(500);
- try
- {
- txtReceive.Text = serialPort.ReadExisting();
- }
- catch (Exception e)
- {
- MessageBox.Show(e.Message);
- //处理错误
- }
- serialPort.Close();
- }
- }
- static class Program
- {
- /// <summary>
- /// 应用程序的主入口点。
- /// </summary>
- [STAThread]
- static void Main()
- {
- Application.EnableVisualStyles();
- Application.SetCompatibleTextRenderingDefault(false);
- Application.Run(new frmTESTSerialPort());
- }
- }
- }
SerialPort 类:
(以下是附加同步和异步线程)
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.IO.Ports;
- using System.ComponentModel;
- using System.Threading;
- namespace Cserver
- {
- class ToCom
- {
- priva
- using System;
- using System.Collections.Generic;
- using System.Text;
- using System.IO.Ports;
- using System.ComponentModel;
- using System.Threading;
- namespace Cserver
- {
- class ToCom
- {
- private System.IO.Ports.SerialPort serialPort1 = new SerialPort();
- public delegate byte[] getDate(byte[] bts);
- private getDate mygetDate;
- private string com;
- public ToCom(string com)
- {
- this.com = com;
- serialPort1.PortName = com; //端口号
- serialPort1.BaudRate = 9600; //比特率
- serialPort1.Parity = Parity.None;//奇偶校验
- serialPort1.StopBits = StopBits.One;//停止位
- serialPort1.ReadTimeout = 1000; //读超时,即在1000内未读到数据就引起超时异常
- }
- #region 发送接收数据
- public void SendMsg(string senStr)
- {
- serialPort1.Open();
- byte[] myByte = StringToByte_2(senStr);
- serialPort1.Write(myByte, 0, myByte.Length);
- serialPort1.Close();
- }
- public string ReadMsg()
- {
- serialPort1.Open();
- string rd="null ";
- #region 读数据老方法
- ------------mothed1----
- //int i = serialPort1.ReadBufferSize;
- // byte[] data = Convert.FromBase64String(serialPort1.ReadLine());
- // rd = Encoding.Unicode.GetString(data);
- // // mothed2
- //int DataLength = serialPort1.BytesToRead;
- //int i = 0;
- //StringBuilder sb = new StringBuilder();
- //while (i < DataLength)
- //{
- // byte[] ds = new byte[1024];
- // int len = serialPort1.Read(ds, 0, 1024);
- // // sb.Append(Encoding.ASCII.GetString(ds, 0, len));
- // sb.Append(ByteToString(ds));
- // i += len;
- //}
- // // mothed2
- //byte[] data= new byte[serialPort1.BytesToRead];
- //int i = serialPort1.Read(data, 0, serialPort1.BytesToRead);
- //rd = ByteToString(data);
- #endregion
- // mothed3
- byte[] data = new byte[serialPort1.BytesToRead];
- int i = serialPort1.Read(data, 0, serialPort1.BytesToRead);
- rd = ByteToString(data);
- return rd;
- }
- // string getdate(byte[])
- public void Sp_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
- {
- byte[] readBuffer = new byte[serialPort1.ReadBufferSize];
- serialPort1.Read(readBuffer, 0, readBuffer.Length);
- //this.Invoke(interfaceUpdataHandle, new string[] { Encoding.UTF8.GetString(readBuffer) });
- // this.Invoke(interfaceUpdataHandle, new string[] { ToCom.ByteToString(readBuffer) });
- string s = ToCom.ByteToString(readBuffer);
- }
- #endregion
- /// <summary>
- /// 串口读(非阻塞方式读串口,直到串口缓冲区中没有数据
- /// </summary>
- /// <param name="readBuf">串口数据缓冲 </param>
- /// <param name="bufRoom">串口数据缓冲空间大小 </param>
- /// <param name="HowTime">设置串口读放弃时间 </param>
- /// <param name="ByteTime">字节间隔最大时间 </param>
- /// <returns>串口实际读入数据个数 </returns>
- public int ReadComm(out Byte[] readBuf, int bufRoom, int HowTime, int ByteTime)
- {
- //throw new System.NotImplementedException();
- readBuf = new Byte[64];
- Array.Clear(readBuf, 0, readBuf.Length);
- int nReadLen, nBytelen;
- if (serialPort1.IsOpen == false)
- return -1;
- nBytelen = 0;
- serialPort1.ReadTimeout = HowTime;
- try
- {
- readBuf[nBytelen] = (byte)serialPort1.ReadByte();
- byte[] bTmp = new byte[1023];
- Array.Clear(bTmp, 0, bTmp.Length);
- nReadLen = ReadBlock(out bTmp, bufRoom - 1, ByteTime);
- if (nReadLen > 0)
- {
- Array.Copy(bTmp, 0, readBuf, 1, nReadLen);
- nBytelen = 1 + nReadLen;
- }
- else if (nReadLen == 0)
- nBytelen = 1;
- }
- catch (Exception ex)
- {
- throw new Exception(ex.Message);
- }
- return nBytelen;
- }
- /// <summary>
- /// 串口同步读(阻塞方式读串口,直到串口缓冲区中没有数据,靠字符间间隔超时确定没有数据)
- /// </summary>
- /// <param name="ReadBuf">串口数据缓冲 </param>
- /// <param name="ReadRoom">串口数据缓冲空间大小 </param>
- /// <param name="ByteTime">字节间隔最大时间 </param>
- /// <returns>从串口实际读入的字节个数 </returns>
- public int ReadBlock(out byte[] ReadBuf, int ReadRoom, int ByteTime)
- {
- //throw new System.NotImplementedException();
- ReadBuf = new byte[1024];
- Array.Clear(ReadBuf, 0, ReadBuf.Length);
- sbyte nBytelen;
- //long nByteRead;
- if (serialPort1.IsOpen == false)
- return 0;
- nBytelen = 0;
- serialPort1.ReadTimeout = ByteTime;
- while (nBytelen < (ReadRoom - 1))
- {
- try
- {
- ReadBuf[nBytelen] = (byte)serialPort1.ReadByte();
- nBytelen++; // add one
- }
- catch (Exception ex)
- {
- throw new Exception( ex.Message);
- break;
- }
- }
- ReadBuf[nBytelen] = 0x00;
- return nBytelen;
- }
- /// <summary>
- /// 字符数组转字符串16进制
- /// </summary>
- /// <param name="InBytes"> 二进制字节 </param>
- /// <returns>类似"01 02 0F" </returns>
- public static string ByteToString(byte[] InBytes)
- {
- string StringOut = "";
- foreach (byte InByte in InBytes)
- {
- StringOut = StringOut + String.Format("{0:X2}", InByte) + " ";
- }
- return StringOut.Trim();
- }
- /// <summary>
- /// strhex 转字节数组
- /// </summary>
- /// <param name="InString">类似"01 02 0F" 用空格分开的 </param>
- /// <returns> </returns>
- public static byte[] StringToByte(string InString)
- {
- string[] ByteStrings;
- ByteStrings = InString.Split(" ".ToCharArray());
- byte[] ByteOut;
- ByteOut = new byte[ByteStrings.Length];
- for (int i = 0; i <= ByteStrings.Length - 1; i++)
- {
- ByteOut[i] = byte.Parse(ByteStrings[i], System.Globalization.NumberStyles.HexNumber);
- }
- return ByteOut;
- }
- /// <summary>
- /// strhex 转字节数组
- /// </summary>
- /// <param name="InString">类似"01 02 0F" 中间无空格 </param>
- /// <returns> </returns>
- public static byte[] StringToByte_2(string InString)
- {
- byte[] ByteOut;
- InString = InString.Replace(" ","");
- try
- {
- string[] ByteStrings = new string[InString.Length/2];
- int j = 0;
- for (int i = 0; i < ByteStrings.Length ; i++)
- {
- ByteStrings[i] = InString.Substring(j,2);
- j += 2;
- }
- ByteOut = new byte[ByteStrings.Length];
- for (int i = 0; i <= ByteStrings.Length - 1; i++)
- {
- ByteOut[i] = byte.Parse(ByteStrings[i], System.Globalization.NumberStyles.HexNumber);
- }
- }
- catch (Exception ex)
- {
- throw new Exception(ex.Message);
- }
- return ByteOut;
- }
- /// <summary>
- /// 字符串 转16进制字符串
- /// </summary>
- /// <param name="InString">unico </param>
- /// <returns>类似“01 0f” </returns>
- public static string Str_To_0X(string InString)
- {
- return ByteToString (UnicodeEncoding.Default.GetBytes(InString));
- }
- }
- }