在工作中写过很多串口调试软件,大部分都用于生产测试用。
创建串口实例:
SerialPort serialPort = new SerialPort();
在窗体加载时注册串口接收事件:
private void FrmMain_Load(object sender,EventArgs e) { InitBandRate();//初始化波特率 InitPortName();//初始化串口号 serialPort.DataReceived += new SerialDataReceivedEventHandler(serialPort_DataReceived);//注册串口接收事件 }
接收函数:
private bool closeing = false; private bool listening = false;//这两个变量是为了防止在串口接收数据时关闭串口会出现假死状态 void serialPort_DataReceived(object sender,SerialDataReceivedEventArgs e) { try { if(closeing) { return; } listening = true; byte[] data_buff = new byte[serialPort.BytesToRead];//serialPort.BytesToRead的大小代表当前串口缓冲区的大小,并且它的值是异步变化的 int count = serialPort.Read(data_buff,0,data_buff.Length); if(count>0) { //to do 在这里显示数据,在现实数据时,会提示跨线程的异常,解决办法可以关闭跨异常检测,或者用委托,一般用委托 } } catch(Exception ex) { MessageBox(ex.Message); } finally { listening = false; } }
串口号初始化函数:
private void InitPortName() { string[] strPortName = SerialPort.GetPortNames(); cbxPortName.Items.AddRange(strPortName);//将串口号添加大checkbox控件 }
注册cbxPortName控件的DropDown事件,当下来cbxPortName时重新获得串口号:
private void cbxPortName_DropDown(object sender,EventArgs e) { cbxPortName.Items.Clear(); string[] strPortName = SerialPort.GetPortName(); cbxPortName.Items.AddRange(strPortName); }
打开串口/关闭串口:
private btnOpenClose_Click(object sender,EventArgs e) { if(!serialPort.IsOpen) { serialPort.PortName = cbxPortName.Text; serialPort.BandRate = Convert.ToInt32(cbxBandRate.Text); serialPort.Open(); btnOpenClose.Text = "关闭串口"; } else { closeing = true; while(listening)Application.DoEvent(); serialPort.Close(); closeing = false; btnOpenClose.Text = "打开串口"; } }
委托:
private delegate void SetText(TextBox tb,string str); private void SetAppendTB(TextBox tb,string str) { if(tb.InvokeRequired) { SetText setText = new SetText(SetAppendTB); Invoke(setText,new object[] {tb,str}); } else { tb.AppendText(str); } }