using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.IO.Ports; using System.Text.RegularExpressions; namespace ports { public partial class Form1 : Form { private SerialPort comm = new SerialPort(); private StringBuilder builder = new StringBuilder();//避免在事件处理方法中反复的创建,定义到外面。 private bool Listening = false;//是否没有执行完invoke相关操作 private bool Closing = false;//是否正在关闭串口,执行Application.DoEvents,并阻止再次invoke public Form1() { InitializeComponent(); } //窗体初始化 private void Form1_Load(object sender, EventArgs e) { comm.PortName = "COM5"; comm.BaudRate = 2400; comm.DataBits = 8; comm.StopBits = StopBits.One; comm.Parity = Parity.Even; //上面的可以根据需求改 //初始化SerialPort对象 comm.NewLine = "/r/n"; comm.RtsEnable = true;//根据实际情况吧。 //添加事件注册 comm.DataReceived += serialPort1_DataReceived; } private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) { if (Closing) return;//如果正在关闭,忽略操作,直接返回,尽快的完成串口监听线程的一次循环 try { Listening = true;//设置标记,说明我已经开始处理数据,一会儿要使用系统UI的。 int n = comm.BytesToRead;//先记录下来,避免某种原因,人为的原因,操作几次之间时间长,缓存不一致 byte[] buf = new byte[n];//声明一个临时数组存储当前来的串口数据 comm.Read(buf, 0, n);//读取缓冲数据 builder.Clear();//清除字符串构造器的内容 //因为要访问ui资源,所以需要使用invoke方式同步ui。 this.Invoke((EventHandler)(delegate { foreach (byte b in buf) { //builder.Append(b.ToString("X2") + " "); builder.Append(b.ToString ("X2")); } this.textBox1.AppendText(builder.ToString()); })); } finally { Listening = false;//我用完了,ui可以关闭串口了。 } } private void button1_Click(object sender, EventArgs e) { string str = "FEFEFE68AAAAAAAAAAAA681300DF16"; // string str=输入内容; //根据当前串口对象,来判断操作 if (comm.IsOpen) { Closing = true; while (Listening) Application.DoEvents(); //打开时点击,则关闭串口 comm.Close(); Closing = false; } else { //关闭时点击,则设置好端口,波特率后打开 comm.PortName = "COM5"; comm.BaudRate = 2400; try { comm.Open(); comm.Write(HexToByte(str), 0, HexToByte(str).Length); } catch (Exception ex) { //捕获到异常信息,创建一个新的comm对象,之前的不能用了。 comm = new SerialPort(); //现实异常信息给客户。 MessageBox.Show(ex.Message); } } string a = textBox1.Text; textBox2.Text = a; } private static byte[] HexToByte(string hexString)//string转16进制byte[] { byte[] returnBytes = new byte[hexString.Length / 2]; for (int i = 0; i < returnBytes.Length; i++) returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16); return returnBytes; } } }
上面的代码是可以在VS2010上面正常运行,button发送命令,textbox接收串口返回的数据
SerialPort.Write 函数是没有返回值的。
可以使用 SerialPort.Read 函数来从串口中读取数据,m_Port.Read(...)
SerialPort.Read 只是读啊!如果使用如SQL语句类似的查询该怎么做呢!我有这么一个设备,在读取数据之前需要发送命令,才会返回数据。这样的该怎么做呀
SerialPort 里面有这个事件,comPort_DataReceived,你定制一下就成了,发送之前打开串口,并监听此事件。。
comPort.BaudRate = 9600;
comPort.ReadTimeout = 500;
comPort.WriteTimeout = 500;
comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
void comPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
Thread.Sleep(120);//暂停120毫秒等一条完整的命令进入缓冲区
byte[] c = new byte[50];//用来接收缓冲区收到的数据
try
{
comPort.Read(c, 0, 50);
}
catch { }
}